UNPKG

@strapi/data-transfer

Version:

Data transfer capabilities for Strapi

1 lines • 30.5 kB
{"version":3,"file":"index.mjs","sources":["../../../../src/strapi/providers/local-destination/index.ts"],"sourcesContent":["import { Writable, Readable } from 'stream';\nimport path from 'path';\nimport * as fse from 'fs-extra';\nimport type { Knex } from 'knex';\nimport type { Core, Struct } from '@strapi/types';\nimport type {\n IAsset,\n IDestinationProvider,\n IFile,\n IMetadata,\n ProviderType,\n Transaction,\n} from '../../../../types';\nimport type { IDiagnosticReporter } from '../../../utils/diagnostic';\n\nimport { restore } from './strategies';\nimport * as utils from '../../../utils';\nimport {\n ProviderInitializationError,\n ProviderTransferError,\n ProviderValidationError,\n} from '../../../errors/providers';\nimport { assertValidStrapi } from '../../../utils/providers';\n\nexport const VALID_CONFLICT_STRATEGIES = ['restore'];\nexport const DEFAULT_CONFLICT_STRATEGY = 'restore';\n\nexport interface ILocalStrapiDestinationProviderOptions {\n getStrapi(): Core.Strapi | Promise<Core.Strapi>; // return an initialized instance of Strapi\n\n autoDestroy?: boolean; // shut down the instance returned by getStrapi() at the end of the transfer\n restore?: restore.IRestoreOptions; // erase data in strapi database before transfer; required if strategy is 'restore'\n strategy: 'restore'; // conflict management strategy; only the restore strategy is available at this time\n}\n\nclass LocalStrapiDestinationProvider implements IDestinationProvider {\n name = 'destination::local-strapi';\n\n type: ProviderType = 'destination';\n\n options: ILocalStrapiDestinationProviderOptions;\n\n strapi?: Core.Strapi;\n\n transaction?: Transaction;\n\n uploadsBackupDirectoryName: string;\n\n onWarning?: ((message: string) => void) | undefined;\n\n #diagnostics?: IDiagnosticReporter;\n\n /**\n * The entities mapper is used to map old entities to their new IDs\n */\n #entitiesMapper: { [type: string]: { [id: number]: number } };\n\n constructor(options: ILocalStrapiDestinationProviderOptions) {\n this.options = options;\n this.#entitiesMapper = {};\n this.uploadsBackupDirectoryName = `uploads_backup_${Date.now()}`;\n }\n\n async bootstrap(diagnostics?: IDiagnosticReporter): Promise<void> {\n this.#diagnostics = diagnostics;\n this.#validateOptions();\n this.strapi = await this.options.getStrapi();\n if (!this.strapi) {\n throw new ProviderInitializationError('Could not access local strapi');\n }\n this.strapi.db.lifecycles.disable();\n this.transaction = utils.transaction.createTransaction(this.strapi);\n }\n\n // TODO: either move this to restore strategy, or restore strategy should given access to these instead of repeating the logic possibly in a different way\n #areAssetsIncluded = () => {\n return this.options.restore?.assets;\n };\n\n #isContentTypeIncluded = (type: string) => {\n const notIncluded =\n this.options.restore?.entities?.include &&\n !this.options.restore?.entities?.include?.includes(type);\n const excluded =\n this.options.restore?.entities?.exclude &&\n this.options.restore?.entities.exclude.includes(type);\n\n return !excluded && !notIncluded;\n };\n\n #reportInfo(message: string) {\n this.#diagnostics?.report({\n details: {\n createdAt: new Date(),\n message,\n origin: 'local-destination-provider',\n },\n kind: 'info',\n });\n }\n\n async close(): Promise<void> {\n const { autoDestroy } = this.options;\n assertValidStrapi(this.strapi);\n this.transaction?.end();\n this.strapi.db.lifecycles.enable();\n // Basically `!== false` but more deterministic\n if (autoDestroy === undefined || autoDestroy === true) {\n await this.strapi?.destroy();\n }\n }\n\n #validateOptions() {\n this.#reportInfo('validating options');\n if (!VALID_CONFLICT_STRATEGIES.includes(this.options.strategy)) {\n throw new ProviderValidationError(`Invalid strategy ${this.options.strategy}`, {\n check: 'strategy',\n strategy: this.options.strategy,\n validStrategies: VALID_CONFLICT_STRATEGIES,\n });\n }\n\n // require restore options when using restore\n if (this.options.strategy === 'restore' && !this.options.restore) {\n throw new ProviderValidationError('Missing restore options');\n }\n }\n\n async #deleteFromRestoreOptions() {\n assertValidStrapi(this.strapi);\n if (!this.options.restore) {\n throw new ProviderValidationError('Missing restore options');\n }\n this.#reportInfo('deleting record ');\n return restore.deleteRecords(this.strapi, this.options.restore);\n }\n\n async #deleteAllAssets(trx?: Knex.Transaction) {\n assertValidStrapi(this.strapi);\n this.#reportInfo('deleting all assets');\n // if we're not restoring files, don't touch the files\n if (!this.#areAssetsIncluded()) {\n return;\n }\n\n const stream: Readable = this.strapi.db\n // Create a query builder instance (default type is 'select')\n .queryBuilder('plugin::upload.file')\n // Fetch all columns\n .select('*')\n // Attach the transaction\n .transacting(trx)\n // Get a readable stream\n .stream();\n\n // TODO use bulk delete when exists in providers\n for await (const file of stream) {\n await this.strapi.plugin('upload').provider.delete(file);\n if (file.formats) {\n for (const fileFormat of Object.values(file.formats)) {\n await this.strapi.plugin('upload').provider.delete(fileFormat);\n }\n }\n }\n\n this.#reportInfo('deleted all assets');\n }\n\n async rollback() {\n this.#reportInfo('Rolling back transaction');\n await this.transaction?.rollback();\n this.#reportInfo('Rolled back transaction');\n }\n\n async beforeTransfer() {\n if (!this.strapi) {\n throw new Error('Strapi instance not found');\n }\n\n await this.transaction?.attach(async (trx) => {\n try {\n if (this.options.strategy === 'restore') {\n await this.#handleAssetsBackup();\n await this.#deleteAllAssets(trx);\n await this.#deleteFromRestoreOptions();\n }\n } catch (error) {\n throw new Error(`restore failed ${error}`);\n }\n });\n }\n\n getMetadata(): IMetadata {\n this.#reportInfo('getting metadata');\n assertValidStrapi(this.strapi, 'Not able to get Schemas');\n const strapiVersion = this.strapi.config.get<string>('info.strapi');\n const createdAt = new Date().toISOString();\n\n return {\n createdAt,\n strapi: {\n version: strapiVersion,\n },\n };\n }\n\n getSchemas(): Record<string, Struct.Schema> {\n this.#reportInfo('getting schema');\n assertValidStrapi(this.strapi, 'Not able to get Schemas');\n\n const schemas = utils.schema.schemasToValidJSON({\n ...this.strapi.contentTypes,\n ...this.strapi.components,\n });\n\n return utils.schema.mapSchemasValues(schemas);\n }\n\n createEntitiesWriteStream(): Writable {\n assertValidStrapi(this.strapi, 'Not able to import entities');\n this.#reportInfo('creating entities stream');\n const { strategy } = this.options;\n\n const updateMappingTable = (type: string, oldID: number, newID: number) => {\n if (!this.#entitiesMapper[type]) {\n this.#entitiesMapper[type] = {};\n }\n\n Object.assign(this.#entitiesMapper[type], { [oldID]: newID });\n };\n\n if (strategy === 'restore') {\n return restore.createEntitiesWriteStream({\n strapi: this.strapi,\n updateMappingTable,\n transaction: this.transaction,\n });\n }\n\n throw new ProviderValidationError(`Invalid strategy ${this.options.strategy}`, {\n check: 'strategy',\n strategy: this.options.strategy,\n validStrategies: VALID_CONFLICT_STRATEGIES,\n });\n }\n\n async #handleAssetsBackup() {\n assertValidStrapi(this.strapi, 'Not able to create the assets backup');\n\n // if we're not restoring assets, don't back them up because they won't be touched\n if (!this.#areAssetsIncluded()) {\n return;\n }\n\n if (this.strapi.config.get<{ provider: string }>('plugin::upload').provider === 'local') {\n this.#reportInfo('creating assets backup directory');\n const assetsDirectory = path.join(this.strapi.dirs.static.public, 'uploads');\n const backupDirectory = path.join(\n this.strapi.dirs.static.public,\n this.uploadsBackupDirectoryName\n );\n\n try {\n // Check access before attempting to do anything\n await fse.access(\n assetsDirectory,\n // eslint-disable-next-line no-bitwise\n fse.constants.W_OK | fse.constants.R_OK | fse.constants.F_OK\n );\n // eslint-disable-next-line no-bitwise\n await fse.access(path.join(assetsDirectory, '..'), fse.constants.W_OK | fse.constants.R_OK);\n\n await fse.move(assetsDirectory, backupDirectory);\n await fse.mkdir(assetsDirectory);\n // Create a .gitkeep file to ensure the directory is not empty\n await fse.outputFile(path.join(assetsDirectory, '.gitkeep'), '');\n this.#reportInfo(`created assets backup directory ${backupDirectory}`);\n } catch (err) {\n throw new ProviderTransferError(\n 'The backup folder for the assets could not be created inside the public folder. Please ensure Strapi has write permissions on the public directory',\n {\n code: 'ASSETS_DIRECTORY_ERR',\n }\n );\n }\n return backupDirectory;\n }\n }\n\n async #removeAssetsBackup() {\n assertValidStrapi(this.strapi, 'Not able to remove Assets');\n // if we're not restoring assets, don't back them up because they won't be touched\n if (!this.#areAssetsIncluded()) {\n return;\n }\n // TODO: this should catch all thrown errors and bubble it up to engine so it can be reported as a non-fatal diagnostic message telling the user they may need to manually delete assets\n if (this.strapi.config.get<{ provider: string }>('plugin::upload').provider === 'local') {\n this.#reportInfo('removing assets backup');\n assertValidStrapi(this.strapi);\n const backupDirectory = path.join(\n this.strapi.dirs.static.public,\n this.uploadsBackupDirectoryName\n );\n await fse.rm(backupDirectory, { recursive: true, force: true });\n this.#reportInfo('successfully removed assets backup');\n }\n }\n\n // TODO: Move this logic to the restore strategy\n async createAssetsWriteStream(): Promise<Writable> {\n assertValidStrapi(this.strapi, 'Not able to stream Assets');\n this.#reportInfo('creating assets write stream');\n if (!this.#areAssetsIncluded()) {\n throw new ProviderTransferError(\n 'Attempting to transfer assets when `assets` is not set in restore options'\n );\n }\n\n const removeAssetsBackup = this.#removeAssetsBackup.bind(this);\n const strapi = this.strapi;\n const transaction = this.transaction;\n const fileEntitiesMapper = this.#entitiesMapper['plugin::upload.file'];\n\n const restoreMediaEntitiesContent = this.#isContentTypeIncluded('plugin::upload.file');\n\n return new Writable({\n objectMode: true,\n async final(next) {\n // Delete the backup folder\n await removeAssetsBackup();\n next();\n },\n async write(chunk: IAsset, _encoding, callback) {\n await transaction?.attach(async () => {\n const uploadData = {\n ...chunk.metadata,\n stream: Readable.from(chunk.stream),\n buffer: chunk?.buffer,\n };\n\n const provider = strapi.config.get<{ provider: string }>('plugin::upload').provider;\n\n const fileId = fileEntitiesMapper?.[uploadData.id];\n if (!fileId) {\n return callback(new Error(`File ID not found for ID: ${uploadData.id}`));\n }\n\n try {\n await strapi.plugin('upload').provider.uploadStream(uploadData);\n\n // if we're not supposed to transfer the associated entities, stop here\n if (!restoreMediaEntitiesContent) {\n return callback();\n }\n\n // Files formats are stored within the parent file entity\n if (uploadData?.type) {\n const entry: IFile = await strapi.db.query('plugin::upload.file').findOne({\n where: { id: fileId },\n });\n if (!entry) {\n throw new Error('file not found');\n }\n const specificFormat = entry?.formats?.[uploadData.type];\n if (specificFormat) {\n specificFormat.url = uploadData.url;\n }\n await strapi.db.query('plugin::upload.file').update({\n where: { id: entry.id },\n data: {\n formats: entry.formats,\n provider,\n },\n });\n return callback();\n }\n\n const entry: IFile = await strapi.db.query('plugin::upload.file').findOne({\n where: { id: fileId },\n });\n if (!entry) {\n throw new Error('file not found');\n }\n entry.url = uploadData.url;\n await strapi.db.query('plugin::upload.file').update({\n where: { id: entry.id },\n data: {\n url: entry.url,\n provider,\n },\n });\n return callback();\n } catch (error) {\n return callback(new Error(`Error while uploading asset ${chunk.filename} ${error}`));\n }\n });\n },\n });\n }\n\n async createConfigurationWriteStream(): Promise<Writable> {\n assertValidStrapi(this.strapi, 'Not able to stream Configurations');\n this.#reportInfo('creating configuration write stream');\n const { strategy } = this.options;\n\n if (strategy === 'restore') {\n return restore.createConfigurationWriteStream(this.strapi, this.transaction);\n }\n\n throw new ProviderValidationError(`Invalid strategy ${strategy}`, {\n check: 'strategy',\n strategy,\n validStrategies: VALID_CONFLICT_STRATEGIES,\n });\n }\n\n async createLinksWriteStream(): Promise<Writable> {\n this.#reportInfo('creating links write stream');\n if (!this.strapi) {\n throw new Error('Not able to stream links. Strapi instance not found');\n }\n\n const { strategy } = this.options;\n const mapID = (uid: string, id: number): number | undefined => this.#entitiesMapper[uid]?.[id];\n\n if (strategy === 'restore') {\n return restore.createLinksWriteStream(mapID, this.strapi, this.transaction, this.onWarning);\n }\n\n throw new ProviderValidationError(`Invalid strategy ${strategy}`, {\n check: 'strategy',\n strategy,\n validStrategies: VALID_CONFLICT_STRATEGIES,\n });\n }\n}\n\nexport const createLocalStrapiDestinationProvider = (\n options: ILocalStrapiDestinationProviderOptions\n) => {\n return new LocalStrapiDestinationProvider(options);\n};\n"],"names":["VALID_CONFLICT_STRATEGIES","DEFAULT_CONFLICT_STRATEGY","LocalStrapiDestinationProvider","bootstrap","diagnostics","validateOptions","strapi","options","getStrapi","ProviderInitializationError","db","lifecycles","disable","transaction","utils","close","autoDestroy","assertValidStrapi","end","enable","undefined","destroy","rollback","reportInfo","beforeTransfer","Error","attach","trx","strategy","handleAssetsBackup","deleteAllAssets","deleteFromRestoreOptions","error","getMetadata","strapiVersion","config","get","createdAt","Date","toISOString","version","getSchemas","schemas","contentTypes","components","createEntitiesWriteStream","updateMappingTable","type","oldID","newID","entitiesMapper","Object","assign","restore","ProviderValidationError","check","validStrategies","createAssetsWriteStream","areAssetsIncluded","ProviderTransferError","removeAssetsBackup","bind","fileEntitiesMapper","restoreMediaEntitiesContent","isContentTypeIncluded","Writable","objectMode","final","next","write","chunk","_encoding","callback","uploadData","metadata","stream","Readable","from","buffer","provider","fileId","id","plugin","uploadStream","entry","query","findOne","where","specificFormat","formats","url","update","data","filename","createConfigurationWriteStream","createLinksWriteStream","mapID","uid","onWarning","constructor","name","assets","notIncluded","entities","include","includes","excluded","exclude","uploadsBackupDirectoryName","now","message","report","details","origin","kind","queryBuilder","select","transacting","file","delete","fileFormat","values","assetsDirectory","path","join","dirs","static","public","backupDirectory","fse","access","constants","W_OK","R_OK","F_OK","move","mkdir","outputFile","err","code","rm","recursive","force","createLocalStrapiDestinationProvider"],"mappings":"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"}