@strapi/data-transfer
Version:
Data transfer capabilities for Strapi
1 lines • 57.7 kB
Source Map (JSON)
{"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","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","abort","TransferEngineError","init","source","sourceMetadata","destinationProvider","setMetadata","bootstrap","results","Promise","allSettled","sourceProvider","forEach","result","status","reason","close","integrityCheck","getMetadata","destinationMetadata","strapi","version","sourceSchemas","destinationSchemas","TransferEngineValidationError","diffs","schemaDiffs","ignoredDiffs","destination","unresolvedDiffs","check","transfer","progress","data","beforeTransfer","transferSchemas","transferEntities","transferAssets","transferLinks","transferConfiguration","e","lastDiagnostic","last","stack","items","Error","rollback","engine","runWithDiagnostic","provider","resolved","createSchemasReadStream","createSchemasWriteStream","transform","tracker","key","value","modelType","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","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","payload","emit","transferStage","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","getSchemas","createTransferEngine"],"mappings":"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