"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.initTransform = void 0; 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. */ /** * Extract versions metadata from an object migration definition * * @param migrationDefinition The object migration definition * @returns Metadata about the versions (list of available, last supported, latest) */ const getVersionsMeta = migrationDefinition => { const versions = Object.keys(migrationDefinition).map(version => { const { result, value } = (0, _utils.validateVersion)(version); if (!result) { throw new Error(`Invalid version number [${version}].`); } return value; }).sort((a, b) => a - b); const latestVersion = versions[versions.length - 1]; const lastSupportedVersion = versions[0]; return { versions, lastSupportedVersion, latestVersion }; }; /** * Get a list of pure functions to transform an object from one version * to another. Either "up" or "down" according if the "to" is > than the "from" * * @param from The version to start from * @param to The version to end to * @param migrationDefinition The object migration definition * @returns An array of transform functions */ const getTransformFns = (from, to, migrationDefinition) => { const fns = []; let i = from; let fn; if (to > from) { while (i <= to) { fn = migrationDefinition[i].up; if (fn) { fns.push(fn); } i++; } } else if (to < from) { while (i >= to) { fn = migrationDefinition[i].down; if (fn) { fns.push(fn); } i--; } } return fns; }; /** * Initiate a transform for a specific request version. After we initiate the transforms * for a specific version we can then pass different `ObjectMigrationDefinition` to the provided * handler to start up/down transforming different object based on this request version. * * @example * * ```ts * const transforms = initTransform(2); // start from version "2" * const fooTransforms = transforms(fooMigrationDefinition); * const barTransforms = transforms(barMigrationDefinition); * * // Up transform the objects to the latest, starting from version "2" * const { value: fooOnLatest } = foo.up(); * const { value: barOnLatest } = bar.up(); * ``` * * @param requestVersion The starting version before up/down transforming * @returns A handler to pass an object migration definition */ const initTransform = requestVersion => migrationDefinition => { const { latestVersion } = getVersionsMeta(migrationDefinition); const getVersion = v => v === 'latest' ? latestVersion : v; const validateFn = (value, version = requestVersion) => { const def = migrationDefinition[version]; if (!def) { throw new Error(`Invalid version number [${version}].`); } const { schema } = def; if (schema) { return (0, _utils.validateObj)(value, schema); } return null; }; return { up: (obj, to = 'latest', { validate = true } = {}) => { try { if (!migrationDefinition[requestVersion]) { return { error: new Error(`Unvalid version to up transform from [${requestVersion}].`), value: null }; } if (validate) { const error = validateFn(obj, requestVersion); if (error) { return { error, value: null }; } } const targetVersion = getVersion(to); if (!migrationDefinition[targetVersion]) { return { error: new Error(`Unvalid version to up transform to [${to}].`), value: null }; } const fns = getTransformFns(requestVersion, targetVersion, migrationDefinition); const value = fns.reduce((acc, fn) => { const res = fn(acc); return res; }, obj); return { value, error: null }; } catch (e) { var _e$message; return { value: null, error: new Error(`[Transform error] ${(_e$message = e.message) !== null && _e$message !== void 0 ? _e$message : 'could not transform object'}.`) }; } }, down: (obj, from = 'latest', { validate = true } = {}) => { try { if (!migrationDefinition[requestVersion]) { return { error: new Error(`Unvalid version to down transform to [${requestVersion}].`), value: null }; } const fromVersion = getVersion(from); if (!migrationDefinition[fromVersion]) { return { error: new Error(`Unvalid version to down transform from [${from}].`), value: null }; } if (validate) { const error = validateFn(obj, fromVersion); if (error) { return { error, value: null }; } } const fns = getTransformFns(fromVersion, requestVersion, migrationDefinition); const value = fns.reduce((acc, fn) => { const res = fn(acc); return res; }, obj); return { value: value, error: null }; } catch (e) { var _e$message2; return { value: null, error: new Error(`[Transform error] ${(_e$message2 = e.message) !== null && _e$message2 !== void 0 ? _e$message2 : 'could not transform object'}.`) }; } }, validate: validateFn }; }; exports.initTransform = initTransform;