"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.updateArgsToSoUpdateOptionsDefault = exports.searchArgsToSOFindOptionsDefault = exports.createArgsToSoCreateOptionsDefault = exports.SOContentStorage = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _boom = _interopRequireDefault(require("@hapi/boom")); var _lodash = require("lodash"); var _utils = require("./utils"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ const savedObjectClientFromRequest = async ctx => { if (!ctx.requestHandlerContext) { throw new Error('Storage context.requestHandlerContext missing.'); } const { savedObjects } = await ctx.requestHandlerContext.core; return savedObjects.client; }; function savedObjectToItem(savedObject, allowedSavedObjectAttributes) { const { id, type, updated_at: updatedAt, created_at: createdAt, attributes, references, error, namespaces, version } = savedObject; return { id, type, updatedAt, createdAt, attributes: (0, _lodash.pick)(attributes, allowedSavedObjectAttributes), references, error, namespaces, version }; } const searchArgsToSOFindOptionsDefault = params => { var _options$searchFields, _options$fields; const { query, contentTypeId, options } = params; return { type: contentTypeId, search: query.text, perPage: query.limit, page: query.cursor ? +query.cursor : undefined, defaultSearchOperator: 'AND', searchFields: (_options$searchFields = options === null || options === void 0 ? void 0 : options.searchFields) !== null && _options$searchFields !== void 0 ? _options$searchFields : ['description', 'title'], fields: (_options$fields = options === null || options === void 0 ? void 0 : options.fields) !== null && _options$fields !== void 0 ? _options$fields : ['description', 'title'], ...(0, _utils.tagsToFindOptions)(query.tags) }; }; exports.searchArgsToSOFindOptionsDefault = searchArgsToSOFindOptionsDefault; const createArgsToSoCreateOptionsDefault = params => params; exports.createArgsToSoCreateOptionsDefault = createArgsToSoCreateOptionsDefault; const updateArgsToSoUpdateOptionsDefault = params => params; exports.updateArgsToSoUpdateOptionsDefault = updateArgsToSoUpdateOptionsDefault; class SOContentStorage { constructor({ savedObjectType, cmServicesDefinition, createArgsToSoCreateOptions, updateArgsToSoUpdateOptions, searchArgsToSOFindOptions, enableMSearch, allowedSavedObjectAttributes, mSearchAdditionalSearchFields }) { (0, _defineProperty2.default)(this, "savedObjectType", void 0); (0, _defineProperty2.default)(this, "cmServicesDefinition", void 0); (0, _defineProperty2.default)(this, "createArgsToSoCreateOptions", void 0); (0, _defineProperty2.default)(this, "updateArgsToSoUpdateOptions", void 0); (0, _defineProperty2.default)(this, "searchArgsToSOFindOptions", void 0); (0, _defineProperty2.default)(this, "allowedSavedObjectAttributes", void 0); (0, _defineProperty2.default)(this, "mSearch", void 0); this.savedObjectType = savedObjectType; this.cmServicesDefinition = cmServicesDefinition; this.createArgsToSoCreateOptions = createArgsToSoCreateOptions || createArgsToSoCreateOptionsDefault; this.updateArgsToSoUpdateOptions = updateArgsToSoUpdateOptions || updateArgsToSoUpdateOptionsDefault; this.searchArgsToSOFindOptions = searchArgsToSOFindOptions || searchArgsToSOFindOptionsDefault; this.allowedSavedObjectAttributes = allowedSavedObjectAttributes; if (enableMSearch) { this.mSearch = { savedObjectType: this.savedObjectType, additionalSearchFields: mSearchAdditionalSearchFields, toItemResult: (ctx, savedObject) => { const transforms = ctx.utils.getTransforms(this.cmServicesDefinition); // Validate DB response and DOWN transform to the request version const { value, error: resultError } = transforms.mSearch.out.result.down(savedObjectToItem(savedObject, this.allowedSavedObjectAttributes, false)); if (resultError) { throw _boom.default.badRequest(`Invalid response. ${resultError.message}`); } return value; } }; } } async get(ctx, id) { const transforms = ctx.utils.getTransforms(this.cmServicesDefinition); const soClient = await savedObjectClientFromRequest(ctx); // Save data in DB const { saved_object: savedObject, alias_purpose: aliasPurpose, alias_target_id: aliasTargetId, outcome } = await soClient.resolve(this.savedObjectType, id); const response = { item: savedObjectToItem(savedObject, this.allowedSavedObjectAttributes, false), meta: { aliasPurpose, aliasTargetId, outcome } }; // Validate DB response and DOWN transform to the request version const { value, error: resultError } = transforms.get.out.result.down(response); if (resultError) { throw _boom.default.badRequest(`Invalid response. ${resultError.message}`); } return value; } async bulkGet() { // Not implemented throw new Error(`[bulkGet] has not been implemented. See ${this.constructor.name} class.`); } async create(ctx, data, options) { const transforms = ctx.utils.getTransforms(this.cmServicesDefinition); const soClient = await savedObjectClientFromRequest(ctx); // Validate input (data & options) & UP transform them to the latest version const { value: dataToLatest, error: dataError } = transforms.create.in.data.up(data); if (dataError) { throw _boom.default.badRequest(`Invalid data. ${dataError.message}`); } const { value: optionsToLatest, error: optionsError } = transforms.create.in.options.up(options); if (optionsError) { throw _boom.default.badRequest(`Invalid options. ${optionsError.message}`); } const createOptions = this.createArgsToSoCreateOptions(optionsToLatest); // Save data in DB const savedObject = await soClient.create(this.savedObjectType, dataToLatest, createOptions); // Validate DB response and DOWN transform to the request version const { value, error: resultError } = transforms.create.out.result.down({ item: savedObjectToItem(savedObject, this.allowedSavedObjectAttributes, false) }); if (resultError) { throw _boom.default.badRequest(`Invalid response. ${resultError.message}`); } return value; } async update(ctx, id, data, options) { const transforms = ctx.utils.getTransforms(this.cmServicesDefinition); const soClient = await savedObjectClientFromRequest(ctx); // Validate input (data & options) & UP transform them to the latest version const { value: dataToLatest, error: dataError } = transforms.update.in.data.up(data); if (dataError) { throw _boom.default.badRequest(`Invalid data. ${dataError.message}`); } const { value: optionsToLatest, error: optionsError } = transforms.update.in.options.up(options); if (optionsError) { throw _boom.default.badRequest(`Invalid options. ${optionsError.message}`); } const updateOptions = this.updateArgsToSoUpdateOptions(optionsToLatest); // Save data in DB const partialSavedObject = await soClient.update(this.savedObjectType, id, dataToLatest, updateOptions); // Validate DB response and DOWN transform to the request version const { value, error: resultError } = transforms.update.out.result.down({ item: savedObjectToItem(partialSavedObject, this.allowedSavedObjectAttributes, true) }); if (resultError) { throw _boom.default.badRequest(`Invalid response. ${resultError.message}`); } return value; } async delete(ctx, id, // force is necessary to delete saved objects that exist in multiple namespaces options) { var _options$force; const soClient = await savedObjectClientFromRequest(ctx); await soClient.delete(this.savedObjectType, id, { force: (_options$force = options === null || options === void 0 ? void 0 : options.force) !== null && _options$force !== void 0 ? _options$force : false }); return { success: true }; } async search(ctx, query, options = {}) { const transforms = ctx.utils.getTransforms(this.cmServicesDefinition); const soClient = await savedObjectClientFromRequest(ctx); // Validate and UP transform the options const { value: optionsToLatest, error: optionsError } = transforms.search.in.options.up(options); if (optionsError) { throw _boom.default.badRequest(`Invalid payload. ${optionsError.message}`); } const soQuery = this.searchArgsToSOFindOptions({ contentTypeId: this.savedObjectType, query, options: optionsToLatest }); // Execute the query in the DB const response = await soClient.find(soQuery); // Validate the response and DOWN transform to the request version const { value, error: resultError } = transforms.search.out.result.down({ hits: response.saved_objects.map(so => savedObjectToItem(so, this.allowedSavedObjectAttributes, false)), pagination: { total: response.total } }); if (resultError) { throw _boom.default.badRequest(`Invalid response. ${resultError.message}`); } return value; } } exports.SOContentStorage = SOContentStorage;