@strapi/data-transfer
Version:
Data transfer capabilities for Strapi
1 lines • 29.9 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../../../src/strapi/providers/remote-source/index.ts"],"sourcesContent":["import { PassThrough, Readable, Writable } from 'stream';\nimport type { Struct, Utils } from '@strapi/types';\nimport { WebSocket } from 'ws';\nimport { castArray } from 'lodash/fp';\n\nimport type {\n IAsset,\n IMetadata,\n ISourceProvider,\n ISourceProviderTransferResults,\n MaybePromise,\n Protocol,\n ProviderType,\n TransferStage,\n} from '../../../../types';\nimport type { IDiagnosticReporter } from '../../../utils/diagnostic';\nimport { Client, Server, Auth } from '../../../../types/remote/protocol';\nimport { ProviderTransferError, ProviderValidationError } from '../../../errors/providers';\nimport { TRANSFER_PATH } from '../../remote/constants';\nimport { ILocalStrapiSourceProviderOptions } from '../local-source';\nimport { createDispatcher, connectToWebsocket, trimTrailingSlash } from '../utils';\n\nexport interface IRemoteStrapiSourceProviderOptions extends ILocalStrapiSourceProviderOptions {\n url: URL; // the url of the remote Strapi admin\n auth?: Auth.ITransferTokenAuth;\n retryMessageOptions?: {\n retryMessageTimeout: number; // milliseconds to wait for a response from a message\n retryMessageMaxRetries: number; // max number of retries for a message before aborting transfer\n };\n streamTimeout?: number; // milliseconds to wait between chunks of an asset before aborting the transfer\n}\n\ntype QueueableAction = Protocol.Client.TransferAssetFlow &\n ({ action: 'stream' } | { action: 'end' });\n\nclass RemoteStrapiSourceProvider implements ISourceProvider {\n name = 'source::remote-strapi';\n\n type: ProviderType = 'source';\n\n options: IRemoteStrapiSourceProviderOptions;\n\n ws: WebSocket | null;\n\n dispatcher: ReturnType<typeof createDispatcher> | null;\n\n defaultOptions: Partial<IRemoteStrapiSourceProviderOptions> = {\n streamTimeout: 15000,\n };\n\n constructor(options: IRemoteStrapiSourceProviderOptions) {\n this.options = {\n ...this.defaultOptions,\n ...options,\n };\n\n this.ws = null;\n this.dispatcher = null;\n }\n\n results?: ISourceProviderTransferResults | undefined;\n\n #diagnostics?: IDiagnosticReporter;\n\n async #createStageReadStream(stage: Exclude<TransferStage, 'schemas'>) {\n const startResult = await this.#startStep(stage);\n\n if (startResult instanceof Error) {\n throw startResult;\n }\n\n const { id: processID } = startResult as { id: string };\n\n const stream = new PassThrough({ objectMode: true });\n\n const listener = async (raw: Buffer) => {\n const parsed = JSON.parse(raw.toString());\n // If not a message related to our transfer process, ignore it\n if (!parsed.uuid || parsed?.data?.type !== 'transfer' || parsed?.data?.id !== processID) {\n this.ws?.once('message', listener);\n return;\n }\n\n const { uuid, data: message } = parsed;\n const { ended, error, data } = message;\n\n if (error) {\n await this.#respond(uuid);\n stream.destroy(error);\n return;\n }\n\n if (ended) {\n await this.#respond(uuid);\n await this.#endStep(stage);\n\n stream.end();\n return;\n }\n\n // if we get a single items instead of a batch\n for (const item of castArray(data)) {\n stream.push(item);\n }\n\n this.ws?.once('message', listener);\n\n await this.#respond(uuid);\n };\n\n this.ws?.once('message', listener);\n\n return stream;\n }\n\n createEntitiesReadStream(): MaybePromise<Readable> {\n return this.#createStageReadStream('entities');\n }\n\n createLinksReadStream(): MaybePromise<Readable> {\n return this.#createStageReadStream('links');\n }\n\n writeAsync = <T>(stream: Writable, data: T) => {\n return new Promise<void>((resolve, reject) => {\n stream.write(data, (error) => {\n if (error) {\n reject(error);\n }\n\n resolve();\n });\n });\n };\n\n async createAssetsReadStream(): Promise<Readable> {\n // Create the streams used to transfer the assets\n const stream = await this.#createStageReadStream('assets');\n const pass = new PassThrough({ objectMode: true });\n\n // Init the asset map\n const assets: {\n // TODO: could we include filename in this for improved logging?\n [assetID: string]: IAsset & {\n stream: PassThrough;\n queue: Array<QueueableAction>;\n status: 'ok' | 'closed' | 'errored';\n timeout?: NodeJS.Timeout;\n };\n } = {};\n\n // Watch for stalled assets; if we don't receive a chunk within timeout, abort transfer\n const resetTimeout = (assetID: string) => {\n if (assets[assetID].timeout) {\n clearTimeout(assets[assetID].timeout);\n }\n assets[assetID].timeout = setTimeout(() => {\n this.#reportInfo(`Asset ${assetID} transfer stalled, aborting.`);\n assets[assetID].status = 'errored';\n assets[assetID].stream.destroy(new Error(`Asset ${assetID} transfer timed out`));\n }, this.options.streamTimeout);\n };\n\n stream\n /**\n * Process a payload of many transfer assets and performs the following tasks:\n * - Start: creates a stream for new assets.\n * - Stream: writes asset chunks to the asset's stream.\n * - End: closes the stream after the asset s transferred and cleanup related resources.\n */\n .on('data', async (payload: Protocol.Client.TransferAssetFlow[]) => {\n for (const item of payload) {\n const { action, assetID } = item;\n\n // Creates the stream to send the incoming asset through\n if (action === 'start') {\n // if a transfer has already been started for the same asset ID, something is wrong\n if (assets[assetID]) {\n throw new Error(`Asset ${assetID} already started`);\n }\n\n this.#reportInfo(`Asset ${assetID} starting`);\n // Register the asset\n assets[assetID] = {\n ...item.data,\n stream: new PassThrough(),\n status: 'ok',\n queue: [],\n };\n\n resetTimeout(assetID);\n\n // Connect the individual asset stream to the main asset stage stream\n // Note: nothing is transferred until data chunks are fed to the asset stream\n await this.writeAsync(pass, assets[assetID]);\n }\n\n // Writes the asset's data chunks to their corresponding stream\n // \"end\" is considered a chunk, but it's not a data chunk, it's a control message\n // That is done so that we don't complicate the already complicated async processing of the queue\n else if (action === 'stream' || action === 'end') {\n // If the asset hasn't been registered, or if it's been closed already, something is wrong\n if (!assets[assetID]) {\n throw new Error(`No id matching ${assetID} for stream action`);\n }\n\n // On every action, reset the timeout timer\n if (action === 'stream') {\n resetTimeout(assetID);\n } else {\n clearTimeout(assets[assetID].timeout);\n }\n\n if (assets[assetID].status === 'closed') {\n throw new Error(`Asset ${assetID} is closed`);\n }\n\n assets[assetID].queue.push(item);\n }\n }\n\n // each new payload will start new processQueue calls, which may cause some extra calls\n // it's essentially saying \"start processing this asset again, I added more data to the queue\"\n for (const assetID in assets) {\n if (Object.prototype.hasOwnProperty.call(assets, assetID)) {\n const asset = assets[assetID];\n if (asset.queue?.length > 0) {\n await processQueue(assetID);\n }\n }\n }\n })\n .on('close', () => {\n pass.end();\n });\n\n /**\n * Start processing the queue for a given assetID\n *\n * Even though this is a loop that attempts to process the entire queue, it is safe to call this more than once\n * for the same asset id because the queue is shared globally, the items are shifted off, and immediately written\n */\n const processQueue = async (id: string) => {\n if (!assets[id]) {\n throw new Error(`Failed to write asset chunk for \"${id}\". Asset not found.`);\n }\n\n const asset = assets[id];\n const { status: currentStatus } = asset;\n\n if (['closed', 'errored'].includes(currentStatus)) {\n throw new Error(\n `Failed to write asset chunk for \"${id}\". The asset is currently \"${currentStatus}\"`\n );\n }\n\n while (asset.queue.length > 0) {\n const data = asset.queue.shift();\n\n if (!data) {\n throw new Error(`Invalid chunk found for ${id}`);\n }\n\n try {\n // if this is an end chunk, close the asset stream\n if (data.action === 'end') {\n this.#reportInfo(`Ending asset stream for ${id}`);\n await closeAssetStream(id);\n break; // Exit the loop after closing the stream\n }\n\n // Save the current chunk\n await writeChunkToStream(id, data);\n } catch {\n if (!assets[id]) {\n throw new Error(`No id matching ${id} for writeAssetChunk`);\n }\n }\n }\n };\n\n /**\n * Writes a chunk of data to the asset's stream.\n *\n * Only check if the targeted asset exists, no other validation is done.\n */\n const writeChunkToStream = async (id: string, data: unknown) => {\n const asset = assets[id];\n\n if (!asset) {\n throw new Error(`Failed to write asset chunk for \"${id}\". Asset not found.`);\n }\n\n const rawBuffer = data as { type: 'Buffer'; data: Uint8Array };\n const chunk = Buffer.from(rawBuffer.data);\n\n await this.writeAsync(asset.stream, chunk);\n };\n\n /**\n * Closes the asset stream associated with the given ID.\n *\n * It deletes the stream for the asset upon successful closure.\n */\n const closeAssetStream = async (id: string) => {\n if (!assets[id]) {\n throw new Error(`Failed to close asset \"${id}\". Asset not found.`);\n }\n\n assets[id].status = 'closed';\n\n await new Promise<void>((resolve, reject) => {\n const { stream } = assets[id];\n\n stream\n .on('close', () => {\n resolve();\n })\n .on('error', (e) => {\n assets[id].status = 'errored';\n reject(new Error(`Failed to close asset \"${id}\". Asset stream error: ${e.toString()}`));\n })\n .end();\n });\n };\n\n return pass;\n }\n\n createConfigurationReadStream(): MaybePromise<Readable> {\n return this.#createStageReadStream('configuration');\n }\n\n async getMetadata(): Promise<IMetadata | null> {\n const metadata = await this.dispatcher?.dispatchTransferAction<IMetadata>('getMetadata');\n\n return metadata ?? null;\n }\n\n assertValidProtocol(url: URL) {\n const validProtocols = ['https:', 'http:'];\n\n if (!validProtocols.includes(url.protocol)) {\n throw new ProviderValidationError(`Invalid protocol \"${url.protocol}\"`, {\n check: 'url',\n details: {\n protocol: url.protocol,\n validProtocols,\n },\n });\n }\n }\n\n async initTransfer(): Promise<string> {\n const query = this.dispatcher?.dispatchCommand({\n command: 'init',\n });\n\n const res = (await query) as Server.Payload<Server.InitMessage>;\n\n if (!res?.transferID) {\n throw new ProviderTransferError('Init failed, invalid response from the server');\n }\n\n return res.transferID;\n }\n\n #reportInfo(message: string) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n origin: 'remote-source-provider',\n },\n kind: 'info',\n });\n }\n\n async bootstrap(diagnostics?: IDiagnosticReporter): Promise<void> {\n this.#diagnostics = diagnostics;\n const { url, auth } = this.options;\n let ws: WebSocket;\n this.assertValidProtocol(url);\n const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n const wsUrl = `${wsProtocol}//${url.host}${trimTrailingSlash(\n url.pathname\n )}${TRANSFER_PATH}/pull`;\n\n this.#reportInfo('establishing websocket connection');\n // No auth defined, trying public access for transfer\n if (!auth) {\n ws = await connectToWebsocket(wsUrl, undefined, this.#diagnostics);\n }\n\n // Common token auth, this should be the main auth method\n else if (auth.type === 'token') {\n const headers = { Authorization: `Bearer ${auth.token}` };\n ws = await connectToWebsocket(wsUrl, { headers }, this.#diagnostics);\n }\n\n // Invalid auth method provided\n else {\n throw new ProviderValidationError('Auth method not available', {\n check: 'auth.type',\n details: {\n auth: auth.type,\n },\n });\n }\n\n this.#reportInfo('established websocket connection');\n this.ws = ws;\n const { retryMessageOptions } = this.options;\n\n this.#reportInfo('creating dispatcher');\n this.dispatcher = createDispatcher(this.ws, retryMessageOptions, (message: string) =>\n this.#reportInfo(message)\n );\n this.#reportInfo('creating dispatcher');\n\n this.#reportInfo('initialize transfer');\n const transferID = await this.initTransfer();\n this.#reportInfo(`initialized transfer ${transferID}`);\n\n this.dispatcher.setTransferProperties({ id: transferID, kind: 'pull' });\n await this.dispatcher.dispatchTransferAction('bootstrap');\n }\n\n async close() {\n await this.dispatcher?.dispatchTransferAction('close');\n\n await new Promise<void>((resolve) => {\n const { ws } = this;\n\n if (!ws || ws.CLOSED) {\n resolve();\n return;\n }\n\n ws.on('close', () => resolve()).close();\n });\n }\n\n async getSchemas() {\n const schemas =\n await this.dispatcher?.dispatchTransferAction<Utils.String.Dict<Struct.Schema>>('getSchemas');\n\n return schemas ?? null;\n }\n\n async #startStep<T extends Client.TransferPullStep>(step: T) {\n try {\n return await this.dispatcher?.dispatchTransferStep({ action: 'start', step });\n } catch (e) {\n if (e instanceof Error) {\n return e;\n }\n\n if (typeof e === 'string') {\n return new ProviderTransferError(e);\n }\n\n return new ProviderTransferError('Unexpected error');\n }\n }\n\n async #respond(uuid: string) {\n return new Promise((resolve, reject) => {\n this.ws?.send(JSON.stringify({ uuid }), (e) => {\n if (e) {\n reject(e);\n } else {\n resolve(e);\n }\n });\n });\n }\n\n async #endStep<T extends Client.TransferPullStep>(step: T) {\n try {\n await this.dispatcher?.dispatchTransferStep({ action: 'end', step });\n } catch (e) {\n if (e instanceof Error) {\n return e;\n }\n\n if (typeof e === 'string') {\n return new ProviderTransferError(e);\n }\n\n return new ProviderTransferError('Unexpected error');\n }\n\n return null;\n }\n}\n\nexport const createRemoteStrapiSourceProvider = (options: IRemoteStrapiSourceProviderOptions) => {\n return new RemoteStrapiSourceProvider(options);\n};\n"],"names":["RemoteStrapiSourceProvider","createEntitiesReadStream","createStageReadStream","createLinksReadStream","createAssetsReadStream","stream","pass","PassThrough","objectMode","assets","resetTimeout","assetID","timeout","clearTimeout","setTimeout","reportInfo","status","destroy","Error","options","streamTimeout","on","payload","item","action","data","queue","writeAsync","push","Object","prototype","hasOwnProperty","call","asset","length","processQueue","end","id","currentStatus","includes","shift","closeAssetStream","writeChunkToStream","rawBuffer","chunk","Buffer","from","Promise","resolve","reject","e","toString","createConfigurationReadStream","getMetadata","metadata","dispatcher","dispatchTransferAction","assertValidProtocol","url","validProtocols","protocol","ProviderValidationError","check","details","initTransfer","query","dispatchCommand","command","res","transferID","ProviderTransferError","bootstrap","diagnostics","auth","ws","wsProtocol","wsUrl","host","trimTrailingSlash","pathname","TRANSFER_PATH","connectToWebsocket","undefined","type","headers","Authorization","token","retryMessageOptions","createDispatcher","message","setTransferProperties","kind","close","CLOSED","getSchemas","schemas","constructor","name","defaultOptions","write","error","stage","startResult","startStep","processID","listener","raw","parsed","JSON","parse","uuid","once","ended","respond","endStep","castArray","report","createdAt","Date","origin","step","dispatchTransferStep","send","stringify","createRemoteStrapiSourceProvider"],"mappings":"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"}