UNPKG

@strapi/data-transfer

Version:

Data transfer capabilities for Strapi

1 lines 22.8 kB
{"version":3,"file":"index.mjs","sources":["../../../../src/file/providers/source/index.ts"],"sourcesContent":["import type { Stats } from 'node:fs';\nimport type { Readable } from 'stream';\n\nimport zip from 'zlib';\nimport path from 'path';\nimport { pipeline, PassThrough } from 'stream';\nimport fs from 'fs-extra';\nimport { Parser, type ReadEntry } from 'tar';\nimport { isEmpty, keyBy } from 'lodash/fp';\nimport { chain } from 'stream-chain';\nimport { parser } from 'stream-json/jsonl/Parser';\nimport type { Struct } from '@strapi/types';\n\nimport type { IAsset, IMetadata, ISourceProvider, ProviderType, IFile } from '../../../../types';\nimport type { IDiagnosticReporter } from '../../../utils/diagnostic';\n\nimport * as utils from '../../../utils';\nimport { write } from '../../../utils/writable-async-write';\nimport { ProviderInitializationError, ProviderTransferError } from '../../../errors/providers';\nimport { isFilePathInDirname, isPathEquivalent, unknownPathToPosix } from './utils';\n\ntype StreamItemArray = Parameters<typeof chain>[0];\n\n/**\n * Constant for the metadata file path\n */\nconst METADATA_FILE_PATH = 'metadata.json';\n\n/**\n * Provider options\n */\nexport interface ILocalFileSourceProviderOptions {\n file: {\n path: string; // the file to load\n };\n\n encryption: {\n enabled: boolean; // if the file is encrypted (and should be decrypted)\n key?: string; // the key to decrypt the file\n };\n\n compression: {\n enabled: boolean; // if the file is compressed (and should be decompressed)\n };\n}\n\nexport const createLocalFileSourceProvider = (options: ILocalFileSourceProviderOptions) => {\n return new LocalFileSourceProvider(options);\n};\n\nclass LocalFileSourceProvider implements ISourceProvider {\n type: ProviderType = 'source';\n\n name = 'source::local-file';\n\n options: ILocalFileSourceProviderOptions;\n\n #metadata?: IMetadata;\n\n #diagnostics?: IDiagnosticReporter;\n\n constructor(options: ILocalFileSourceProviderOptions) {\n this.options = options;\n\n const { encryption } = this.options;\n\n if (encryption.enabled && encryption.key === undefined) {\n throw new Error('Missing encryption key');\n }\n }\n\n #reportInfo(message: string) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n origin: 'file-source-provider',\n },\n kind: 'info',\n });\n }\n\n /**\n * tar `Parser` invokes the pipeline completion callback when the archive ends, but it does not\n * reliably await async `onReadEntry` — defer `end` until outstanding async entry work is done.\n */\n #endPassThroughWhenTarIdle(\n outStream: PassThrough,\n activeAsyncEntries: () => number,\n err?: Error | null\n ) {\n if (err) {\n outStream.destroy(err);\n return;\n }\n const tick = () => {\n if (activeAsyncEntries() === 0) {\n outStream.end();\n } else {\n setImmediate(tick);\n }\n };\n tick();\n }\n\n /**\n * Pre flight checks regarding the provided options, making sure that the file can be opened (decrypted, decompressed), etc.\n */\n async bootstrap(diagnostics: IDiagnosticReporter) {\n this.#diagnostics = diagnostics;\n const { path: filePath } = this.options.file;\n\n try {\n // Read the metadata to ensure the file can be parsed\n await this.#loadMetadata();\n // TODO: we might also need to read the schema.jsonl files & implements a custom stream-check\n } catch (e) {\n if (this.options?.encryption?.enabled) {\n throw new ProviderInitializationError(\n `Key is incorrect or the file '${filePath}' is not a valid Strapi data file.`\n );\n }\n throw new ProviderInitializationError(`File '${filePath}' is not a valid Strapi data file.`);\n }\n\n if (!this.#metadata) {\n throw new ProviderInitializationError('Could not load metadata from Strapi data file.');\n }\n }\n\n async #loadMetadata() {\n const backupStream = this.#getBackupStream();\n this.#metadata = await this.#parseJSONFile<IMetadata>(backupStream, METADATA_FILE_PATH);\n }\n\n async #loadAssetMetadata(path: string) {\n const backupStream = this.#getBackupStream();\n return this.#parseJSONFile<IFile>(backupStream, path);\n }\n\n async getMetadata() {\n this.#reportInfo('getting metadata');\n if (!this.#metadata) {\n await this.#loadMetadata();\n }\n\n return this.#metadata ?? null;\n }\n\n async getSchemas() {\n this.#reportInfo('getting schemas');\n const schemaCollection = await utils.stream.collect<Struct.Schema>(\n this.createSchemasReadStream()\n );\n\n if (isEmpty(schemaCollection)) {\n throw new ProviderInitializationError('Could not load schemas from Strapi data file.');\n }\n\n // Group schema by UID\n const schemas = keyBy('uid', schemaCollection);\n\n // Transform to valid JSON\n return utils.schema.schemasToValidJSON(schemas);\n }\n\n createEntitiesReadStream(): Readable {\n this.#reportInfo('creating entities read stream');\n return this.#streamJsonlDirectory('entities');\n }\n\n createSchemasReadStream(): Readable {\n this.#reportInfo('creating schemas read stream');\n return this.#streamJsonlDirectory('schemas');\n }\n\n createLinksReadStream(): Readable {\n this.#reportInfo('creating links read stream');\n return this.#streamJsonlDirectory('links');\n }\n\n createConfigurationReadStream(): Readable {\n this.#reportInfo('creating configuration read stream');\n // NOTE: TBD\n return this.#streamJsonlDirectory('configuration');\n }\n\n createAssetsReadStream(): Readable | Promise<Readable> {\n const inStream = this.#getBackupStream();\n const outStream = new PassThrough({ objectMode: true });\n const loadAssetMetadata = this.#loadAssetMetadata.bind(this);\n this.#reportInfo('creating assets read stream');\n\n let activeAsyncEntries = 0;\n const runReadEntry = async (fn: () => Promise<void>) => {\n activeAsyncEntries += 1;\n try {\n await fn();\n } finally {\n activeAsyncEntries -= 1;\n }\n };\n\n pipeline(\n [\n inStream,\n new Parser({\n // find only files in the assets/uploads folder\n filter(filePath: string, entry: Stats | ReadEntry) {\n if (!('type' in entry) || entry.type !== 'File') {\n return false;\n }\n return isFilePathInDirname('assets/uploads', filePath);\n },\n async onReadEntry(entry: ReadEntry) {\n await runReadEntry(async () => {\n const { path: filePath, size = 0 } = entry;\n const normalizedPath = unknownPathToPosix(filePath);\n const file = path.basename(normalizedPath);\n let metadata;\n try {\n metadata = await loadAssetMetadata(`assets/metadata/${file}.json`);\n } catch (error) {\n throw new Error(`Failed to read metadata for ${file}`);\n }\n const asset: IAsset = {\n metadata,\n filename: file,\n filepath: normalizedPath,\n stats: { size },\n stream: entry as unknown as Readable,\n };\n await write(outStream, asset);\n });\n },\n }),\n ],\n (err) => this.#endPassThroughWhenTarIdle(outStream, () => activeAsyncEntries, err)\n );\n\n return outStream;\n }\n\n #getBackupStream() {\n const { file, encryption, compression } = this.options;\n\n const streams: StreamItemArray = [];\n\n try {\n streams.push(fs.createReadStream(file.path));\n } catch (e) {\n throw new Error(`Could not read backup file path provided at \"${this.options.file.path}\"`);\n }\n\n if (encryption.enabled && encryption.key) {\n streams.push(utils.encryption.createDecryptionCipher(encryption.key));\n }\n\n if (compression.enabled) {\n streams.push(zip.createGunzip());\n }\n\n return chain(streams);\n }\n\n // `directory` must be posix formatted path\n #streamJsonlDirectory(directory: string) {\n const inStream = this.#getBackupStream();\n\n const outStream = new PassThrough({ objectMode: true });\n\n let activeAsyncEntries = 0;\n const runReadEntry = async (fn: () => Promise<void>) => {\n activeAsyncEntries += 1;\n try {\n await fn();\n } finally {\n activeAsyncEntries -= 1;\n }\n };\n\n pipeline(\n [\n inStream,\n new Parser({\n filter(filePath: string, entry: Stats | ReadEntry) {\n if (!('type' in entry) || entry.type !== 'File') {\n return false;\n }\n\n return isFilePathInDirname(directory, filePath);\n },\n\n async onReadEntry(entry: ReadEntry) {\n await runReadEntry(async () => {\n const transforms = [\n // JSONL parser to read the data chunks one by one (line by line)\n parser({\n checkErrors: true,\n }),\n // The JSONL parser returns each line as key/value\n (line: { key: string; value: object }) => line.value,\n ];\n\n const stream = entry.pipe(chain(transforms));\n\n try {\n for await (const chunk of stream) {\n await write(outStream, chunk);\n }\n } catch (e: unknown) {\n outStream.destroy(\n new ProviderTransferError(\n `Error parsing backup files from backup file ${entry.path}: ${\n (e as Error).message\n }`,\n {\n details: {\n error: e,\n },\n }\n )\n );\n }\n });\n },\n }),\n ],\n (err) => this.#endPassThroughWhenTarIdle(outStream, () => activeAsyncEntries, err)\n );\n\n return outStream;\n }\n\n // For collecting an entire JSON file then parsing it, not for streaming JSONL\n async #parseJSONFile<T extends object>(fileStream: Readable, filePath: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n pipeline(\n [\n fileStream,\n // Custom backup archive parsing\n new Parser({\n /**\n * Filter the parsed entries to only keep the one that matches the given filepath\n */\n filter(entryPath: string, entry: Stats | ReadEntry) {\n if (!('type' in entry) || entry.type !== 'File') {\n return false;\n }\n\n return isPathEquivalent(entryPath, filePath);\n },\n\n async onReadEntry(entry: ReadEntry) {\n // Collect all the content of the entry stream (ReadEntry has no .collect() in tar v7)\n const chunks: Buffer[] = [];\n for await (const chunk of entry) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n try {\n // Parse from buffer array to string to JSON\n const parsedContent = JSON.parse(Buffer.concat(chunks).toString());\n\n // Resolve the Promise with the parsed content\n resolve(parsedContent);\n } catch (e) {\n reject(e);\n } finally {\n // Cleanup (close the stream associated to the entry)\n entry.destroy();\n }\n },\n }),\n ],\n () => {\n // If the promise hasn't been resolved and we've parsed all\n // the archive entries, then the file doesn't exist\n reject(new Error(`File \"${filePath}\" not found`));\n }\n );\n });\n }\n}\n"],"names":["METADATA_FILE_PATH","createLocalFileSourceProvider","options","LocalFileSourceProvider","bootstrap","diagnostics","path","filePath","file","e","encryption","enabled","ProviderInitializationError","getMetadata","getSchemas","schemaCollection","utils","createSchemasReadStream","isEmpty","schemas","keyBy","createEntitiesReadStream","createLinksReadStream","createConfigurationReadStream","createAssetsReadStream","inStream","outStream","PassThrough","objectMode","loadAssetMetadata","bind","activeAsyncEntries","runReadEntry","fn","pipeline","Parser","filter","entry","type","isFilePathInDirname","onReadEntry","size","normalizedPath","unknownPathToPosix","basename","metadata","error","Error","asset","filename","filepath","stats","stream","write","err","name","key","undefined","message","report","details","createdAt","Date","origin","kind","destroy","tick","end","setImmediate","backupStream","compression","streams","push","fs","createReadStream","zip","createGunzip","chain","directory","transforms","parser","checkErrors","line","value","pipe","chunk","ProviderTransferError","fileStream","Promise","resolve","reject","entryPath","isPathEquivalent","chunks","Buffer","isBuffer","from","parsedContent","JSON","parse","concat","toString"],"mappings":"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"}