UNPKG

@strapi/data-transfer

Version:

Data transfer capabilities for Strapi

1 lines • 58.3 kB
{"version":3,"file":"index.mjs","sources":["../../src/engine/index.ts"],"sourcesContent":["import { PassThrough, Transform, Readable, Writable } from 'stream';\nimport { pipeline } from 'stream/promises';\nimport { extname } from 'path';\nimport { EOL } from 'os';\nimport type Chain from 'stream-chain';\nimport { chain } from 'stream-chain';\nimport { isEmpty, uniq, last, isNumber, set, pick } from 'lodash/fp';\nimport { diff as semverDiff } from 'semver';\n\nimport type { Struct, Utils } from '@strapi/types';\n\nimport type {\n IAsset,\n IDestinationProvider,\n IEntity,\n ILink,\n IMetadata,\n ISourceProvider,\n ITransferEngine,\n ITransferEngineOptions,\n TransferProgress,\n ITransferResults,\n TransferStage,\n TransferTransform,\n IProvider,\n TransferFilters,\n TransferFilterPreset,\n StreamItem,\n SchemaDiffHandler,\n SchemaDiffHandlerContext,\n ErrorHandler,\n ErrorHandlerContext,\n ErrorHandlers,\n ErrorCode,\n} from '../../types';\nimport type { Diff } from '../utils/json';\n\nimport { compareSchemas, validateProvider } from './validation';\n\nimport { TransferEngineError, TransferEngineValidationError } from './errors';\nimport {\n createDiagnosticReporter,\n IDiagnosticReporter,\n ErrorDiagnosticSeverity,\n} from '../utils/diagnostic';\nimport { DataTransferError } from '../errors';\nimport * as utils from '../utils';\nimport { ProviderTransferError } from '../errors/providers';\n\nexport const TRANSFER_STAGES: ReadonlyArray<TransferStage> = Object.freeze([\n 'entities',\n 'links',\n 'assets',\n 'schemas',\n 'configuration',\n]);\n\nexport type TransferGroupFilter = Record<TransferFilterPreset, TransferFilters>;\n\n/**\n * Preset filters for only/exclude options\n * */\nexport const TransferGroupPresets: TransferGroupFilter = {\n content: {\n links: true, // Example: content includes the entire links stage\n entities: true,\n // TODO: If we need to implement filtering on a running stage, it would be done like this, but we still need to implement it\n // [\n // // Example: content processes the entities stage, but filters individual entities\n // {\n // filter(data) {\n // return shouldIncludeThisData(data);\n // },\n // },\n // ],\n },\n files: {\n assets: true,\n },\n config: {\n configuration: true,\n },\n};\n\nexport const DEFAULT_VERSION_STRATEGY = 'ignore';\nexport const DEFAULT_SCHEMA_STRATEGY = 'strict';\n\ntype SchemaMap = Utils.String.Dict<Struct.Schema>;\n\nclass TransferEngine<\n S extends ISourceProvider = ISourceProvider,\n D extends IDestinationProvider = IDestinationProvider,\n> implements ITransferEngine\n{\n sourceProvider: ISourceProvider;\n\n destinationProvider: IDestinationProvider;\n\n options: ITransferEngineOptions;\n\n #metadata: { source?: IMetadata; destination?: IMetadata } = {};\n\n #schema: { source?: SchemaMap; destination?: SchemaMap } = {};\n\n // Progress of the current stage\n progress: {\n // metrics on the progress such as size and record count\n data: TransferProgress;\n // stream that emits events\n stream: PassThrough;\n };\n\n diagnostics: IDiagnosticReporter;\n\n #handlers: {\n schemaDiff: SchemaDiffHandler[];\n errors: Partial<ErrorHandlers>;\n } = {\n schemaDiff: [],\n errors: {},\n };\n\n #currentStreamController?: AbortController;\n\n #aborted: boolean = false;\n\n onSchemaDiff(handler: SchemaDiffHandler) {\n this.#handlers?.schemaDiff?.push(handler);\n }\n\n addErrorHandler(handlerName: ErrorCode, handler: ErrorHandler) {\n if (!this.#handlers.errors[handlerName]) {\n this.#handlers.errors[handlerName] = [];\n }\n this.#handlers.errors[handlerName]?.push(handler);\n }\n\n async attemptResolveError(error: Error) {\n const context: ErrorHandlerContext = {};\n if (error instanceof ProviderTransferError && error.details?.details.code) {\n const errorCode = error.details?.details.code as ErrorCode;\n if (!this.#handlers.errors[errorCode]) {\n this.#handlers.errors[errorCode] = [];\n }\n await utils.middleware.runMiddleware(context ?? {}, this.#handlers.errors[errorCode] ?? []);\n }\n\n return !!context.ignore;\n }\n\n constructor(sourceProvider: S, destinationProvider: D, options: ITransferEngineOptions) {\n this.diagnostics = createDiagnosticReporter();\n\n validateProvider('source', sourceProvider);\n validateProvider('destination', destinationProvider);\n\n this.sourceProvider = sourceProvider;\n this.destinationProvider = destinationProvider;\n this.options = options;\n\n this.progress = { data: {}, stream: new PassThrough({ objectMode: true }) };\n }\n\n /**\n * Report a fatal error and throw it\n */\n panic(error: Error) {\n this.reportError(error, 'fatal');\n\n throw error;\n }\n\n /**\n * Report an error diagnostic\n */\n reportError(error: Error, severity: ErrorDiagnosticSeverity) {\n this.diagnostics.report({\n kind: 'error',\n details: {\n severity,\n createdAt: new Date(),\n name: error.name,\n message: error.message,\n error,\n },\n });\n }\n\n /**\n * Report a warning diagnostic\n */\n reportWarning(message: string, origin?: string) {\n this.diagnostics.report({\n kind: 'warning',\n details: { createdAt: new Date(), message, origin },\n });\n }\n\n /**\n * Report an info diagnostic\n */\n reportInfo(message: string, params?: unknown) {\n this.diagnostics.report({\n kind: 'info',\n details: { createdAt: new Date(), message, params, origin: 'engine' },\n });\n }\n\n /**\n * Create and return a transform stream based on the given stage and options.\n *\n * Allowed transformations includes 'filter' and 'map'.\n */\n #createStageTransformStream<T extends TransferStage>(\n key: T,\n options: { includeGlobal?: boolean } = {}\n ): PassThrough | Transform {\n const { includeGlobal = true } = options;\n const { throttle } = this.options;\n const { global: globalTransforms, [key]: stageTransforms } = this.options?.transforms ?? {};\n\n let stream: PassThrough | Chain = new PassThrough({ objectMode: true });\n\n const applyTransforms = <U>(transforms: TransferTransform<U>[] = []) => {\n const chainTransforms: StreamItem[] = [];\n for (const transform of transforms) {\n if ('filter' in transform) {\n chainTransforms.push(utils.stream.filter(transform.filter));\n }\n\n if ('map' in transform) {\n chainTransforms.push(utils.stream.map(transform.map));\n }\n }\n if (chainTransforms.length) {\n stream = stream.pipe(chain(chainTransforms));\n }\n };\n\n if (includeGlobal) {\n applyTransforms(globalTransforms);\n }\n\n if (isNumber(throttle) && throttle > 0) {\n stream = stream.pipe(\n new PassThrough({\n objectMode: true,\n async transform(data, _encoding, callback) {\n await new Promise((resolve) => {\n setTimeout(resolve, throttle);\n });\n callback(null, data);\n },\n })\n );\n }\n\n applyTransforms(stageTransforms as TransferTransform<unknown>[]);\n\n return stream;\n }\n\n /**\n * Update the Engine's transfer progress data for a given stage.\n *\n * Providing aggregate options enable custom computation to get the size (bytes) or the aggregate key associated with the data\n */\n #updateTransferProgress<T = unknown>(\n stage: TransferStage,\n data: T,\n aggregate?: {\n size?: (value: T) => number;\n key?: (value: T) => string;\n }\n ) {\n if (!this.progress.data[stage]) {\n this.progress.data[stage] = { count: 0, bytes: 0, startTime: Date.now() };\n }\n\n const stageProgress = this.progress.data[stage];\n\n if (!stageProgress) {\n return;\n }\n\n const size = aggregate?.size?.(data) ?? JSON.stringify(data).length;\n const key = aggregate?.key?.(data);\n\n stageProgress.count += 1;\n stageProgress.bytes += size;\n\n // Handle aggregate updates if necessary\n if (key) {\n if (!stageProgress.aggregates) {\n stageProgress.aggregates = {};\n }\n\n const { aggregates } = stageProgress;\n\n if (!aggregates[key]) {\n aggregates[key] = { count: 0, bytes: 0 };\n }\n\n aggregates[key].count += 1;\n aggregates[key].bytes += size;\n }\n }\n\n /**\n * Create and return a PassThrough stream.\n *\n * Upon writing data into it, it'll update the Engine's transfer progress data and trigger stage update events.\n */\n #progressTracker(\n stage: TransferStage,\n aggregate?: {\n size?(value: unknown): number;\n key?(value: unknown): string;\n }\n ) {\n return new PassThrough({\n objectMode: true,\n transform: (data, _encoding, callback) => {\n this.#updateTransferProgress(stage, data, aggregate);\n this.#emitStageUpdate('progress', stage);\n callback(null, data);\n },\n });\n }\n\n /**\n * Shorthand method used to trigger transfer update events to every listeners\n */\n #emitTransferUpdate(type: 'init' | 'start' | 'finish' | 'error', payload?: object) {\n this.progress.stream.emit(`transfer::${type}`, payload);\n }\n\n /**\n * Shorthand method used to trigger stage update events to every listeners\n */\n #emitStageUpdate(\n type: 'start' | 'finish' | 'progress' | 'skip' | 'error',\n transferStage: TransferStage\n ) {\n this.progress.stream.emit(`stage::${type}`, {\n data: this.progress.data,\n stage: transferStage,\n });\n }\n\n /**\n * Run a version check between two strapi version (source and destination) using the strategy given to the engine during initialization.\n *\n * If there is a mismatch, throws a validation error.\n */\n #assertStrapiVersionIntegrity(sourceVersion?: string, destinationVersion?: string) {\n const strategy = this.options.versionStrategy || DEFAULT_VERSION_STRATEGY;\n\n const reject = () => {\n throw new TransferEngineValidationError(\n `The source and destination provide are targeting incompatible Strapi versions (using the \"${strategy}\" strategy). The source (${this.sourceProvider.name}) version is ${sourceVersion} and the destination (${this.destinationProvider.name}) version is ${destinationVersion}`,\n {\n check: 'strapi.version',\n strategy,\n versions: { source: sourceVersion, destination: destinationVersion },\n }\n );\n };\n\n if (\n !sourceVersion ||\n !destinationVersion ||\n strategy === 'ignore' ||\n destinationVersion === sourceVersion\n ) {\n return;\n }\n\n let diff;\n try {\n diff = semverDiff(sourceVersion, destinationVersion);\n } catch {\n reject();\n }\n\n if (!diff) {\n return;\n }\n\n const validPatch = ['prelease', 'build'];\n const validMinor = [...validPatch, 'patch', 'prepatch'];\n const validMajor = [...validMinor, 'minor', 'preminor'];\n if (strategy === 'patch' && validPatch.includes(diff)) {\n return;\n }\n if (strategy === 'minor' && validMinor.includes(diff)) {\n return;\n }\n if (strategy === 'major' && validMajor.includes(diff)) {\n return;\n }\n\n reject();\n }\n\n /**\n * Run a check between two set of schemas (source and destination) using the strategy given to the engine during initialization.\n *\n * If there are differences and/or incompatibilities between source and destination schemas, then throw a validation error.\n */\n #assertSchemasMatching(sourceSchemas: SchemaMap, destinationSchemas: SchemaMap) {\n const strategy = this.options.schemaStrategy || DEFAULT_SCHEMA_STRATEGY;\n\n if (strategy === 'ignore') {\n return;\n }\n\n const keys = uniq(Object.keys(sourceSchemas).concat(Object.keys(destinationSchemas)));\n const diffs: { [key: string]: Diff[] } = {};\n\n keys.forEach((key) => {\n const sourceSchema = sourceSchemas[key];\n const destinationSchema = destinationSchemas[key];\n const schemaDiffs = compareSchemas(sourceSchema, destinationSchema, strategy);\n\n if (schemaDiffs.length) {\n diffs[key] = schemaDiffs as Diff<Struct.Schema>[];\n }\n });\n\n if (!isEmpty(diffs)) {\n const formattedDiffs = Object.entries(diffs)\n .map(([uid, ctDiffs]) => {\n let msg = `- ${uid}:${EOL}`;\n\n msg += ctDiffs\n .sort((a, b) => (a.kind > b.kind ? -1 : 1))\n .map((diff) => {\n const path = diff.path.join('.');\n\n if (diff.kind === 'added') {\n return `${path} exists in destination schema but not in source schema and the data will not be transferred.`;\n }\n\n if (diff.kind === 'deleted') {\n return `${path} exists in source schema but not in destination schema and the data will not be transferred.`;\n }\n\n if (diff.kind === 'modified') {\n if (diff.types[0] === diff.types[1]) {\n return `Schema value changed at \"${path}\": \"${diff.values[0]}\" (${diff.types[0]}) => \"${diff.values[1]}\" (${diff.types[1]})`;\n }\n\n return `Schema has differing data types at \"${path}\": \"${diff.values[0]}\" (${diff.types[0]}) => \"${diff.values[1]}\" (${diff.types[1]})`;\n }\n\n throw new TransferEngineValidationError(`Invalid diff found for \"${uid}\"`, {\n check: `schema on ${uid}`,\n });\n })\n .map((line) => ` - ${line}`)\n .join(EOL);\n\n return msg;\n })\n .join(EOL);\n\n throw new TransferEngineValidationError(\n `Invalid schema changes detected during integrity checks (using the ${strategy} strategy). Please find a summary of the changes below:\\n${formattedDiffs}`,\n {\n check: 'schema.changes',\n strategy,\n diffs,\n }\n );\n }\n }\n\n shouldSkipStage(stage: TransferStage) {\n const { exclude, only } = this.options;\n\n // schemas must always be included\n if (stage === 'schemas') {\n return false;\n }\n\n // everything is included by default unless 'only' has been set\n let included = isEmpty(only);\n if (only && only.length > 0) {\n included = only.some((transferGroup) => {\n return TransferGroupPresets[transferGroup][stage];\n });\n }\n\n if (exclude && exclude.length > 0) {\n if (included) {\n included = !exclude.some((transferGroup) => {\n return TransferGroupPresets[transferGroup][stage];\n });\n }\n }\n\n return !included;\n }\n\n async #transferStage(options: {\n stage: TransferStage;\n source?: Readable;\n destination?: Writable;\n transform?: PassThrough | Chain;\n tracker?: PassThrough;\n }) {\n if (this.#aborted) {\n throw new TransferEngineError('fatal', 'Transfer aborted.');\n }\n\n const { stage, source, destination, transform, tracker } = options;\n\n const updateEndTime = () => {\n const stageData = this.progress.data[stage];\n\n if (stageData) {\n stageData.endTime = Date.now();\n }\n };\n\n if (!source || !destination || this.shouldSkipStage(stage)) {\n // Wait until source and destination are closed\n const results = await Promise.allSettled(\n [source, destination].map((stream) => {\n // if stream is undefined or already closed, resolve immediately\n if (!stream || stream.destroyed) {\n return Promise.resolve();\n }\n\n // Wait until the close event is produced and then destroy the stream and resolve\n return new Promise((resolve, reject) => {\n stream.on('close', resolve).on('error', reject).destroy();\n });\n })\n );\n\n results.forEach((state) => {\n if (state.status === 'rejected') {\n this.reportWarning(state.reason, `transfer(${stage})`);\n }\n });\n\n this.#emitStageUpdate('skip', stage);\n\n return;\n }\n\n this.#emitStageUpdate('start', stage);\n\n try {\n const streams: (Readable | Writable)[] = [source];\n\n if (transform) {\n streams.push(transform);\n }\n if (tracker) {\n streams.push(tracker);\n }\n\n streams.push(destination);\n\n // NOTE: to debug/confirm backpressure issues from misbehaving stream, uncomment the following lines\n // source.on('pause', () => console.log(`[${stage}] Source paused due to backpressure`));\n // source.on('resume', () => console.log(`[${stage}] Source resumed`));\n // destination.on('drain', () =>\n // console.log(`[${stage}] Destination drained, resuming data flow`)\n // );\n // destination.on('error', (err) => console.error(`[${stage}] Destination error:`, err));\n\n const controller = new AbortController();\n const { signal } = controller;\n\n // Store the controller so you can cancel later\n this.#currentStreamController = controller;\n\n await pipeline(streams, { signal });\n\n this.#emitStageUpdate('finish', stage);\n } catch (e) {\n updateEndTime();\n this.#emitStageUpdate('error', stage);\n this.reportError(e as Error, 'error');\n if (!destination.destroyed) {\n destination.destroy(e as Error);\n }\n } finally {\n updateEndTime();\n }\n }\n\n // Cause an ongoing transfer to abort gracefully\n async abortTransfer(): Promise<void> {\n this.#aborted = true;\n this.#currentStreamController?.abort();\n throw new TransferEngineError('fatal', 'Transfer aborted.');\n }\n\n async init(): Promise<void> {\n // Resolve providers' resource and store\n // them in the engine's internal state\n await this.#resolveProviderResource();\n\n // Update the destination provider's source metadata\n const { source: sourceMetadata } = this.#metadata;\n\n if (sourceMetadata) {\n this.destinationProvider.setMetadata?.('source', sourceMetadata);\n }\n }\n\n /**\n * Run the bootstrap method in both source and destination providers\n */\n async bootstrap(): Promise<void> {\n const results = await Promise.allSettled([\n this.sourceProvider.bootstrap?.(this.diagnostics),\n this.destinationProvider.bootstrap?.(this.diagnostics),\n ]);\n\n results.forEach((result) => {\n if (result.status === 'rejected') {\n this.panic(result.reason);\n }\n });\n }\n\n /**\n * Run the close method in both source and destination providers\n */\n async close(): Promise<void> {\n const results = await Promise.allSettled([\n this.sourceProvider.close?.(),\n this.destinationProvider.close?.(),\n ]);\n\n results.forEach((result) => {\n if (result.status === 'rejected') {\n this.panic(result.reason);\n }\n });\n }\n\n async #resolveProviderResource() {\n const sourceMetadata = await this.sourceProvider.getMetadata();\n const destinationMetadata = await this.destinationProvider.getMetadata();\n\n if (sourceMetadata) {\n this.#metadata.source = sourceMetadata;\n }\n\n if (destinationMetadata) {\n this.#metadata.destination = destinationMetadata;\n }\n }\n\n async #getSchemas() {\n if (!this.#schema.source) {\n this.#schema.source = (await this.sourceProvider.getSchemas?.()) as SchemaMap;\n }\n\n if (!this.#schema.destination) {\n this.#schema.destination = (await this.destinationProvider.getSchemas?.()) as SchemaMap;\n }\n\n return {\n sourceSchemas: this.#schema.source,\n destinationSchemas: this.#schema.destination,\n };\n }\n\n async integrityCheck() {\n const sourceMetadata = await this.sourceProvider.getMetadata();\n const destinationMetadata = await this.destinationProvider.getMetadata();\n\n if (sourceMetadata && destinationMetadata) {\n this.#assertStrapiVersionIntegrity(\n sourceMetadata?.strapi?.version,\n destinationMetadata?.strapi?.version\n );\n }\n\n const { sourceSchemas, destinationSchemas } = await this.#getSchemas();\n\n try {\n if (sourceSchemas && destinationSchemas) {\n this.#assertSchemasMatching(sourceSchemas, destinationSchemas);\n }\n } catch (error) {\n // if this is a schema matching error, allow handlers to resolve it\n if (error instanceof TransferEngineValidationError && error.details?.details?.diffs) {\n const schemaDiffs = error.details?.details?.diffs as Record<string, Diff[]>;\n\n const context: SchemaDiffHandlerContext = {\n ignoredDiffs: {},\n diffs: schemaDiffs,\n source: this.sourceProvider,\n destination: this.destinationProvider,\n };\n\n // if we don't have any handlers, throw the original error\n if (isEmpty(this.#handlers.schemaDiff)) {\n throw error;\n }\n\n await utils.middleware.runMiddleware<SchemaDiffHandlerContext>(\n context,\n this.#handlers.schemaDiff\n );\n\n // if there are any remaining diffs that weren't ignored\n const unresolvedDiffs = utils.json.diff(context.diffs, context.ignoredDiffs);\n if (unresolvedDiffs.length) {\n this.panic(\n new TransferEngineValidationError('Unresolved differences in schema', {\n check: 'schema.changes',\n unresolvedDiffs,\n })\n );\n }\n\n return;\n }\n\n throw error;\n }\n }\n\n async transfer(): Promise<ITransferResults<S, D>> {\n // reset data between transfers\n this.progress.data = {};\n\n try {\n this.#emitTransferUpdate('init');\n await this.bootstrap();\n await this.init();\n\n await this.integrityCheck();\n\n this.#emitTransferUpdate('start');\n\n await this.beforeTransfer();\n\n // Run the transfer stages\n await this.transferSchemas();\n await this.transferEntities();\n await this.transferAssets();\n await this.transferLinks();\n await this.transferConfiguration();\n // Gracefully close the providers\n await this.close();\n\n this.#emitTransferUpdate('finish');\n } catch (e: unknown) {\n this.#emitTransferUpdate('error', { error: e });\n\n const lastDiagnostic = last(this.diagnostics.stack.items);\n // Do not report an error diagnostic if the last one reported the same error\n if (\n e instanceof Error &&\n (!lastDiagnostic || lastDiagnostic.kind !== 'error' || lastDiagnostic.details.error !== e)\n ) {\n this.reportError(e, (e as DataTransferError).severity || 'fatal');\n }\n\n // Rollback the destination provider if an exception is thrown during the transfer\n // Note: This will be configurable in the future\n await this.destinationProvider.rollback?.(e as Error);\n\n throw e;\n }\n\n return {\n source: this.sourceProvider.results,\n destination: this.destinationProvider.results,\n engine: this.progress.data,\n };\n }\n\n async beforeTransfer(): Promise<void> {\n const runWithDiagnostic = async (provider: IProvider) => {\n try {\n await provider.beforeTransfer?.();\n } catch (error) {\n if (error instanceof Error) {\n const resolved = await this.attemptResolveError(error);\n\n if (resolved) {\n return;\n }\n this.panic(error);\n } else {\n this.panic(\n new Error(`Unknwon error when executing \"beforeTransfer\" on the ${origin} provider`)\n );\n }\n }\n };\n\n await runWithDiagnostic(this.sourceProvider);\n await runWithDiagnostic(this.destinationProvider);\n }\n\n async transferSchemas(): Promise<void> {\n const stage: TransferStage = 'schemas';\n if (this.shouldSkipStage(stage)) {\n return;\n }\n\n const source = await this.sourceProvider.createSchemasReadStream?.();\n const destination = await this.destinationProvider.createSchemasWriteStream?.();\n\n const transform = this.#createStageTransformStream(stage);\n const tracker = this.#progressTracker(stage, {\n key: (value: Struct.Schema) => value.modelType,\n });\n\n await this.#transferStage({ stage, source, destination, transform, tracker });\n }\n\n async transferEntities(): Promise<void> {\n const stage: TransferStage = 'entities';\n if (this.shouldSkipStage(stage)) {\n return;\n }\n\n const source = await this.sourceProvider.createEntitiesReadStream?.();\n const destination = await this.destinationProvider.createEntitiesWriteStream?.();\n\n const transform = chain([\n this.#createStageTransformStream(stage),\n new Transform({\n objectMode: true,\n transform: async (entity: IEntity, _encoding, callback) => {\n const { destinationSchemas: schemas } = await this.#getSchemas();\n\n if (!schemas) {\n return callback(null, entity);\n }\n\n // TODO: this would be safer if we only ignored things in ignoredDiffs, otherwise continue and let an error be thrown\n const availableContentTypes = Object.entries(schemas)\n .filter(([, schema]) => schema.modelType === 'contentType')\n .map(([uid]) => uid);\n\n // If the type of the transferred entity doesn't exist in the destination, then discard it\n if (!availableContentTypes.includes(entity.type)) {\n return callback(null, undefined);\n }\n\n const { type, data } = entity;\n const attributes = schemas[type].attributes;\n const attributesToKeep = Object.keys(attributes).concat('documentId');\n const updatedEntity = set('data', pick(attributesToKeep, data), entity);\n\n callback(null, updatedEntity);\n },\n }),\n ]);\n\n const tracker = this.#progressTracker(stage, { key: (value: IEntity) => value.type });\n\n await this.#transferStage({ stage, source, destination, transform, tracker });\n }\n\n async transferLinks(): Promise<void> {\n const stage: TransferStage = 'links';\n if (this.shouldSkipStage(stage)) {\n return;\n }\n\n const source = await this.sourceProvider.createLinksReadStream?.();\n const destination = await this.destinationProvider.createLinksWriteStream?.();\n\n const transform = chain([\n this.#createStageTransformStream(stage),\n new Transform({\n objectMode: true,\n transform: async (link: ILink, _encoding, callback) => {\n const { destinationSchemas: schemas } = await this.#getSchemas();\n if (!schemas) {\n return callback(null, link);\n }\n\n // TODO: this would be safer if we only ignored things in ignoredDiffs, otherwise continue and let an error be thrown\n const availableContentTypes = Object.keys(schemas);\n\n const isValidType = (uid: string) => availableContentTypes.includes(uid);\n\n if (!isValidType(link.left.type) || !isValidType(link.right.type)) {\n return callback(null, undefined); // ignore the link\n }\n\n callback(null, link);\n },\n }),\n ]);\n\n const tracker = this.#progressTracker(stage);\n\n await this.#transferStage({ stage, source, destination, transform, tracker });\n }\n\n async transferAssets(): Promise<void> {\n const stage: TransferStage = 'assets';\n if (this.shouldSkipStage(stage)) {\n return;\n }\n\n const source = await this.sourceProvider.createAssetsReadStream?.();\n const destination = await this.destinationProvider.createAssetsWriteStream?.();\n\n const transform = this.#createStageTransformStream(stage);\n const tracker = this.#progressTracker(stage, {\n size: (value: IAsset) => value.stats.size,\n key: (value: IAsset) => extname(value.filename) || 'No extension',\n });\n\n await this.#transferStage({ stage, source, destination, transform, tracker });\n }\n\n async transferConfiguration(): Promise<void> {\n const stage: TransferStage = 'configuration';\n if (this.shouldSkipStage(stage)) {\n return;\n }\n\n const source = await this.sourceProvider.createConfigurationReadStream?.();\n const destination = await this.destinationProvider.createConfigurationWriteStream?.();\n\n const transform = this.#createStageTransformStream(stage);\n const tracker = this.#progressTracker(stage);\n\n await this.#transferStage({ stage, source, destination, transform, tracker });\n }\n}\n\nexport const createTransferEngine = <S extends ISourceProvider, D extends IDestinationProvider>(\n sourceProvider: S,\n destinationProvider: D,\n options: ITransferEngineOptions\n): TransferEngine<S, D> => {\n return new TransferEngine<S, D>(sourceProvider, destinationProvider, options);\n};\n\nexport type {\n TransferEngine,\n ITransferEngine,\n ITransferEngineOptions,\n ISourceProvider,\n IDestinationProvider,\n TransferStage,\n TransferFilterPreset,\n ErrorHandlerContext,\n SchemaDiffHandlerContext,\n ITransferResults,\n};\n\nexport * as errors from './errors';\n"],"names":["TRANSFER_STAGES","Object","freeze","TransferGroupPresets","content","links","entities","files","assets","config","configuration","DEFAULT_VERSION_STRATEGY","DEFAULT_SCHEMA_STRATEGY","TransferEngine","onSchemaDiff","handler","handlers","schemaDiff","push","addErrorHandler","handlerName","errors","attemptResolveError","error","context","ProviderTransferError","details","code","errorCode","utils","ignore","panic","reportError","severity","diagnostics","report","kind","createdAt","Date","name","message","reportWarning","origin","reportInfo","params","shouldSkipStage","stage","exclude","only","options","included","isEmpty","length","some","transferGroup","abortTransfer","aborted","currentStreamController","abort","TransferEngineError","init","resolveProviderResource","source","sourceMetadata","metadata","destinationProvider","setMetadata","bootstrap","results","Promise","allSettled","sourceProvider","forEach","result","status","reason","close","integrityCheck","getMetadata","destinationMetadata","assertStrapiVersionIntegrity","strapi","version","sourceSchemas","destinationSchemas","getSchemas","assertSchemasMatching","TransferEngineValidationError","diffs","schemaDiffs","ignoredDiffs","destination","unresolvedDiffs","check","transfer","progress","data","emitTransferUpdate","beforeTransfer","transferSchemas","transferEntities","transferAssets","transferLinks","transferConfiguration","e","lastDiagnostic","last","stack","items","Error","rollback","engine","runWithDiagnostic","provider","resolved","createSchemasReadStream","createSchemasWriteStream","transform","createStageTransformStream","tracker","progressTracker","key","value","modelType","transferStage","createEntitiesReadStream","createEntitiesWriteStream","chain","Transform","objectMode","entity","_encoding","callback","schemas","availableContentTypes","entries","filter","schema","map","uid","includes","type","undefined","attributes","attributesToKeep","keys","concat","updatedEntity","set","pick","createLinksReadStream","createLinksWriteStream","link","isValidType","left","right","createAssetsReadStream","createAssetsWriteStream","size","stats","extname","filename","createConfigurationReadStream","createConfigurationWriteStream","constructor","createDiagnosticReporter","validateProvider","stream","PassThrough","includeGlobal","throttle","global","globalTransforms","stageTransforms","transforms","applyTransforms","chainTransforms","pipe","isNumber","resolve","setTimeout","aggregate","count","bytes","startTime","now","stageProgress","JSON","stringify","aggregates","updateTransferProgress","emitStageUpdate","payload","emit","sourceVersion","destinationVersion","strategy","versionStrategy","reject","versions","diff","semverDiff","validPatch","validMinor","validMajor","schemaStrategy","uniq","sourceSchema","destinationSchema","compareSchemas","formattedDiffs","ctDiffs","msg","EOL","sort","a","b","path","join","types","values","line","updateEndTime","stageData","endTime","destroyed","on","destroy","state","streams","controller","AbortController","signal","pipeline","createTransferEngine"],"mappings":"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