@strapi/data-transfer 5.52.3 → 5.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/directory/providers/destination/index.d.ts.map +1 -1
- package/dist/directory/providers/destination/index.js +11 -1
- package/dist/directory/providers/destination/index.js.map +1 -1
- package/dist/directory/providers/destination/index.mjs +11 -1
- package/dist/directory/providers/destination/index.mjs.map +1 -1
- package/dist/directory/providers/source/index.d.ts +2 -1
- package/dist/directory/providers/source/index.d.ts.map +1 -1
- package/dist/directory/providers/source/index.js +45 -12
- package/dist/directory/providers/source/index.js.map +1 -1
- package/dist/directory/providers/source/index.mjs +47 -14
- package/dist/directory/providers/source/index.mjs.map +1 -1
- package/dist/engine/index.d.ts +1 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +62 -5
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/index.mjs +62 -5
- package/dist/engine/index.mjs.map +1 -1
- package/dist/file/providers/destination/index.d.ts.map +1 -1
- package/dist/file/providers/destination/index.js +11 -1
- package/dist/file/providers/destination/index.js.map +1 -1
- package/dist/file/providers/destination/index.mjs +11 -1
- package/dist/file/providers/destination/index.mjs.map +1 -1
- package/dist/file/providers/source/index.d.ts +2 -1
- package/dist/file/providers/source/index.d.ts.map +1 -1
- package/dist/file/providers/source/index.js +97 -8
- package/dist/file/providers/source/index.js.map +1 -1
- package/dist/file/providers/source/index.mjs +100 -11
- package/dist/file/providers/source/index.mjs.map +1 -1
- package/dist/file/providers/source/utils.d.ts +2 -0
- package/dist/file/providers/source/utils.d.ts.map +1 -1
- package/dist/file/providers/source/utils.js +43 -0
- package/dist/file/providers/source/utils.js.map +1 -1
- package/dist/file/providers/source/utils.mjs +43 -1
- package/dist/file/providers/source/utils.mjs.map +1 -1
- package/dist/strapi/index.d.ts +1 -0
- package/dist/strapi/index.d.ts.map +1 -1
- package/dist/strapi/index.js +9 -0
- package/dist/strapi/index.js.map +1 -1
- package/dist/strapi/index.mjs +1 -0
- package/dist/strapi/index.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.js +2 -2
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.js.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.mjs +2 -2
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.d.ts.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.js +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.js.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.mjs +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.mjs.map +1 -1
- package/dist/strapi/providers/local-source/assets.js +2 -2
- package/dist/strapi/providers/local-source/assets.js.map +1 -1
- package/dist/strapi/providers/local-source/assets.mjs +2 -2
- package/dist/strapi/providers/local-source/assets.mjs.map +1 -1
- package/dist/strapi/remote/handlers/push.d.ts +14 -0
- package/dist/strapi/remote/handlers/push.d.ts.map +1 -1
- package/dist/strapi/remote/handlers/push.js +104 -9
- package/dist/strapi/remote/handlers/push.js.map +1 -1
- package/dist/strapi/remote/handlers/push.mjs +103 -10
- package/dist/strapi/remote/handlers/push.mjs.map +1 -1
- package/dist/strapi/transfer-policy.d.ts +12 -0
- package/dist/strapi/transfer-policy.d.ts.map +1 -0
- package/dist/strapi/transfer-policy.js +163 -0
- package/dist/strapi/transfer-policy.js.map +1 -0
- package/dist/strapi/transfer-policy.mjs +154 -0
- package/dist/strapi/transfer-policy.mjs.map +1 -0
- package/dist/types/providers.d.ts +10 -0
- package/dist/types/providers.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -101,7 +101,7 @@ const missingAssetWarningMessage = (file, filepath, format)=>{
|
|
|
101
101
|
yield {
|
|
102
102
|
metadata: file,
|
|
103
103
|
filepath,
|
|
104
|
-
filename: file.hash
|
|
104
|
+
filename: `${file.hash}${file.ext ?? ''}`,
|
|
105
105
|
stream,
|
|
106
106
|
stats: {
|
|
107
107
|
size: stats.size
|
|
@@ -132,7 +132,7 @@ const missingAssetWarningMessage = (file, filepath, format)=>{
|
|
|
132
132
|
yield {
|
|
133
133
|
metadata,
|
|
134
134
|
filepath: fileFormatFilepath,
|
|
135
|
-
filename: fileFormat.hash
|
|
135
|
+
filename: `${fileFormat.hash}${fileFormat.ext ?? ''}`,
|
|
136
136
|
stream: fileFormatStream,
|
|
137
137
|
stats: {
|
|
138
138
|
size: fileFormatStats.size
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sources":["../../../../src/strapi/providers/local-source/assets.ts"],"sourcesContent":["import { join } from 'path';\nimport { Duplex, PassThrough, Readable } from 'stream';\nimport { stat, createReadStream, ReadStream } from 'fs-extra';\nimport * as webStream from 'stream/web';\nimport type { Core } from '@strapi/types';\n\nimport type { IAsset, IFile } from '../../../types';\n\nfunction getFileStream(\n filepath: string,\n strapi: Core.Strapi,\n isLocal = false\n): PassThrough | ReadStream {\n if (isLocal) {\n // Todo: handle errors\n return createReadStream(filepath);\n }\n\n const readableStream = new PassThrough();\n\n // fetch the image from remote url and stream it\n strapi\n .fetch(filepath)\n .then((res: Response) => {\n if (res.status !== 200) {\n readableStream.emit('error', new Error(`Request failed with status code ${res.status}`));\n return;\n }\n\n if (res.body) {\n // pipe the image data\n Readable.fromWeb(res.body as webStream.ReadableStream<Uint8Array>).pipe(readableStream);\n } else {\n readableStream.emit('error', new Error('Empty data found for file'));\n }\n })\n .catch((error: unknown) => {\n readableStream.emit('error', error);\n });\n\n return readableStream;\n}\n\nexport function getFileStatsForTransfer(\n filepath: string,\n strapi: Core.Strapi,\n isLocal = false\n): Promise<{ size: number }> {\n if (isLocal) {\n return stat(filepath);\n }\n return new Promise((resolve, reject) => {\n strapi\n .fetch(filepath)\n .then((res: Response) => {\n if (res.status !== 200) {\n reject(new Error(`Request failed with status code ${res.status}`));\n return;\n }\n\n const contentLength = res.headers.get('content-length');\n const stats = {\n size: contentLength ? parseInt(contentLength, 10) : 0,\n };\n\n resolve(stats);\n })\n .catch((error: unknown) => {\n reject(error);\n });\n });\n}\n\nexport async function signUploadFileForTransfer(strapi: Core.Strapi, file: IFile) {\n const { provider } = strapi.plugins.upload;\n const { provider: providerName } = strapi.config.get('plugin.upload') as { provider: string };\n const isPrivate = await provider.isPrivate();\n if (file?.provider === providerName && isPrivate) {\n const signUrl = async (f: IFile) => {\n const signedUrl = await provider.getSignedUrl(f);\n f.url = signedUrl.url;\n };\n\n await signUrl(file);\n if (file.formats) {\n for (const format of Object.keys(file.formats)) {\n await signUrl(file.formats[format]);\n }\n }\n }\n}\n\nconst missingAssetWarningMessage = (file: IFile, filepath: string, format?: string): string => {\n const formatPart = format ? ` (format: ${format})` : '';\n return `[Data transfer] Media item ${file.id} (hash: ${file.hash}) exists in database but no corresponding file was found to transfer${formatPart}. Path: ${filepath}`;\n};\n\n/**\n * Generate and consume assets streams in order to stream each file individually\n */\nexport const createAssetsStream = (\n strapi: Core.Strapi,\n options: { onWarning?: (message: string) => void } = {}\n): Duplex => {\n const warnMissingAsset = (message: string) => {\n strapi.log.warn(message);\n options.onWarning?.(message);\n };\n\n const generator: () => AsyncGenerator<IAsset, void> = async function* generateAssets() {\n const stream: Readable = strapi.db\n .queryBuilder('plugin::upload.file')\n // Create a query builder instance (default type is 'select')\n // Fetch all columns\n .select('*')\n // Get a readable stream\n .stream();\n\n for await (const file of stream) {\n const isLocalProvider = file.provider === 'local';\n if (!isLocalProvider) {\n await signUploadFileForTransfer(strapi, file);\n }\n const filepath = isLocalProvider ? join(strapi.dirs.static.public, file.url) : file.url;\n let stats: { size: number };\n try {\n stats = await getFileStatsForTransfer(filepath, strapi, isLocalProvider);\n } catch (err: unknown) {\n const code =\n err && typeof err === 'object' && 'code' in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === 'ENOENT') {\n warnMissingAsset(missingAssetWarningMessage(file, filepath));\n continue;\n }\n throw err;\n }\n const stream = getFileStream(filepath, strapi, isLocalProvider);\n\n yield {\n metadata: file,\n filepath,\n filename: file.hash + file.ext,\n stream,\n stats: { size: stats.size },\n };\n\n if (file.formats) {\n for (const format of Object.keys(file.formats)) {\n const fileFormat = file.formats[format];\n const fileFormatFilepath = isLocalProvider\n ? join(strapi.dirs.static.public, fileFormat.url)\n : fileFormat.url;\n let fileFormatStats: { size: number };\n try {\n fileFormatStats = await getFileStatsForTransfer(\n fileFormatFilepath,\n strapi,\n isLocalProvider\n );\n } catch (err: unknown) {\n const code =\n err && typeof err === 'object' && 'code' in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === 'ENOENT') {\n warnMissingAsset(missingAssetWarningMessage(file, fileFormatFilepath, format));\n continue;\n }\n throw err;\n }\n const fileFormatStream = getFileStream(fileFormatFilepath, strapi, isLocalProvider);\n const metadata = { ...fileFormat, type: format, id: file.id, mainHash: file.hash };\n yield {\n metadata,\n filepath: fileFormatFilepath,\n filename: fileFormat.hash + fileFormat.ext,\n stream: fileFormatStream,\n stats: { size: fileFormatStats.size },\n };\n }\n }\n }\n };\n\n return Duplex.from(generator());\n};\n"],"names":["getFileStream","filepath","strapi","isLocal","createReadStream","readableStream","PassThrough","fetch","then","res","status","emit","Error","body","Readable","fromWeb","pipe","catch","error","getFileStatsForTransfer","stat","Promise","resolve","reject","contentLength","headers","get","stats","size","parseInt","signUploadFileForTransfer","file","provider","plugins","upload","providerName","config","isPrivate","signUrl","f","signedUrl","getSignedUrl","url","formats","format","Object","keys","missingAssetWarningMessage","formatPart","id","hash","createAssetsStream","options","warnMissingAsset","message","log","warn","onWarning","generator","generateAssets","stream","db","queryBuilder","select","isLocalProvider","join","dirs","static","public","err","code","undefined","metadata","filename","ext","fileFormat","fileFormatFilepath","fileFormatStats","fileFormatStream","type","mainHash","Duplex","from"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"assets.js","sources":["../../../../src/strapi/providers/local-source/assets.ts"],"sourcesContent":["import { join } from 'path';\nimport { Duplex, PassThrough, Readable } from 'stream';\nimport { stat, createReadStream, ReadStream } from 'fs-extra';\nimport * as webStream from 'stream/web';\nimport type { Core } from '@strapi/types';\n\nimport type { IAsset, IFile } from '../../../types';\n\nfunction getFileStream(\n filepath: string,\n strapi: Core.Strapi,\n isLocal = false\n): PassThrough | ReadStream {\n if (isLocal) {\n // Todo: handle errors\n return createReadStream(filepath);\n }\n\n const readableStream = new PassThrough();\n\n // fetch the image from remote url and stream it\n strapi\n .fetch(filepath)\n .then((res: Response) => {\n if (res.status !== 200) {\n readableStream.emit('error', new Error(`Request failed with status code ${res.status}`));\n return;\n }\n\n if (res.body) {\n // pipe the image data\n Readable.fromWeb(res.body as webStream.ReadableStream<Uint8Array>).pipe(readableStream);\n } else {\n readableStream.emit('error', new Error('Empty data found for file'));\n }\n })\n .catch((error: unknown) => {\n readableStream.emit('error', error);\n });\n\n return readableStream;\n}\n\nexport function getFileStatsForTransfer(\n filepath: string,\n strapi: Core.Strapi,\n isLocal = false\n): Promise<{ size: number }> {\n if (isLocal) {\n return stat(filepath);\n }\n return new Promise((resolve, reject) => {\n strapi\n .fetch(filepath)\n .then((res: Response) => {\n if (res.status !== 200) {\n reject(new Error(`Request failed with status code ${res.status}`));\n return;\n }\n\n const contentLength = res.headers.get('content-length');\n const stats = {\n size: contentLength ? parseInt(contentLength, 10) : 0,\n };\n\n resolve(stats);\n })\n .catch((error: unknown) => {\n reject(error);\n });\n });\n}\n\nexport async function signUploadFileForTransfer(strapi: Core.Strapi, file: IFile) {\n const { provider } = strapi.plugins.upload;\n const { provider: providerName } = strapi.config.get('plugin.upload') as { provider: string };\n const isPrivate = await provider.isPrivate();\n if (file?.provider === providerName && isPrivate) {\n const signUrl = async (f: IFile) => {\n const signedUrl = await provider.getSignedUrl(f);\n f.url = signedUrl.url;\n };\n\n await signUrl(file);\n if (file.formats) {\n for (const format of Object.keys(file.formats)) {\n await signUrl(file.formats[format]);\n }\n }\n }\n}\n\nconst missingAssetWarningMessage = (file: IFile, filepath: string, format?: string): string => {\n const formatPart = format ? ` (format: ${format})` : '';\n return `[Data transfer] Media item ${file.id} (hash: ${file.hash}) exists in database but no corresponding file was found to transfer${formatPart}. Path: ${filepath}`;\n};\n\n/**\n * Generate and consume assets streams in order to stream each file individually\n */\nexport const createAssetsStream = (\n strapi: Core.Strapi,\n options: { onWarning?: (message: string) => void } = {}\n): Duplex => {\n const warnMissingAsset = (message: string) => {\n strapi.log.warn(message);\n options.onWarning?.(message);\n };\n\n const generator: () => AsyncGenerator<IAsset, void> = async function* generateAssets() {\n const stream: Readable = strapi.db\n .queryBuilder('plugin::upload.file')\n // Create a query builder instance (default type is 'select')\n // Fetch all columns\n .select('*')\n // Get a readable stream\n .stream();\n\n for await (const file of stream) {\n const isLocalProvider = file.provider === 'local';\n if (!isLocalProvider) {\n await signUploadFileForTransfer(strapi, file);\n }\n const filepath = isLocalProvider ? join(strapi.dirs.static.public, file.url) : file.url;\n let stats: { size: number };\n try {\n stats = await getFileStatsForTransfer(filepath, strapi, isLocalProvider);\n } catch (err: unknown) {\n const code =\n err && typeof err === 'object' && 'code' in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === 'ENOENT') {\n warnMissingAsset(missingAssetWarningMessage(file, filepath));\n continue;\n }\n throw err;\n }\n const stream = getFileStream(filepath, strapi, isLocalProvider);\n\n yield {\n metadata: file,\n filepath,\n filename: `${file.hash}${file.ext ?? ''}`,\n stream,\n stats: { size: stats.size },\n };\n\n if (file.formats) {\n for (const format of Object.keys(file.formats)) {\n const fileFormat = file.formats[format];\n const fileFormatFilepath = isLocalProvider\n ? join(strapi.dirs.static.public, fileFormat.url)\n : fileFormat.url;\n let fileFormatStats: { size: number };\n try {\n fileFormatStats = await getFileStatsForTransfer(\n fileFormatFilepath,\n strapi,\n isLocalProvider\n );\n } catch (err: unknown) {\n const code =\n err && typeof err === 'object' && 'code' in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === 'ENOENT') {\n warnMissingAsset(missingAssetWarningMessage(file, fileFormatFilepath, format));\n continue;\n }\n throw err;\n }\n const fileFormatStream = getFileStream(fileFormatFilepath, strapi, isLocalProvider);\n const metadata = { ...fileFormat, type: format, id: file.id, mainHash: file.hash };\n yield {\n metadata,\n filepath: fileFormatFilepath,\n filename: `${fileFormat.hash}${fileFormat.ext ?? ''}`,\n stream: fileFormatStream,\n stats: { size: fileFormatStats.size },\n };\n }\n }\n }\n };\n\n return Duplex.from(generator());\n};\n"],"names":["getFileStream","filepath","strapi","isLocal","createReadStream","readableStream","PassThrough","fetch","then","res","status","emit","Error","body","Readable","fromWeb","pipe","catch","error","getFileStatsForTransfer","stat","Promise","resolve","reject","contentLength","headers","get","stats","size","parseInt","signUploadFileForTransfer","file","provider","plugins","upload","providerName","config","isPrivate","signUrl","f","signedUrl","getSignedUrl","url","formats","format","Object","keys","missingAssetWarningMessage","formatPart","id","hash","createAssetsStream","options","warnMissingAsset","message","log","warn","onWarning","generator","generateAssets","stream","db","queryBuilder","select","isLocalProvider","join","dirs","static","public","err","code","undefined","metadata","filename","ext","fileFormat","fileFormatFilepath","fileFormatStats","fileFormatStream","type","mainHash","Duplex","from"],"mappings":"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"}
|
|
@@ -99,7 +99,7 @@ const missingAssetWarningMessage = (file, filepath, format)=>{
|
|
|
99
99
|
yield {
|
|
100
100
|
metadata: file,
|
|
101
101
|
filepath,
|
|
102
|
-
filename: file.hash
|
|
102
|
+
filename: `${file.hash}${file.ext ?? ''}`,
|
|
103
103
|
stream,
|
|
104
104
|
stats: {
|
|
105
105
|
size: stats.size
|
|
@@ -130,7 +130,7 @@ const missingAssetWarningMessage = (file, filepath, format)=>{
|
|
|
130
130
|
yield {
|
|
131
131
|
metadata,
|
|
132
132
|
filepath: fileFormatFilepath,
|
|
133
|
-
filename: fileFormat.hash
|
|
133
|
+
filename: `${fileFormat.hash}${fileFormat.ext ?? ''}`,
|
|
134
134
|
stream: fileFormatStream,
|
|
135
135
|
stats: {
|
|
136
136
|
size: fileFormatStats.size
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.mjs","sources":["../../../../src/strapi/providers/local-source/assets.ts"],"sourcesContent":["import { join } from 'path';\nimport { Duplex, PassThrough, Readable } from 'stream';\nimport { stat, createReadStream, ReadStream } from 'fs-extra';\nimport * as webStream from 'stream/web';\nimport type { Core } from '@strapi/types';\n\nimport type { IAsset, IFile } from '../../../types';\n\nfunction getFileStream(\n filepath: string,\n strapi: Core.Strapi,\n isLocal = false\n): PassThrough | ReadStream {\n if (isLocal) {\n // Todo: handle errors\n return createReadStream(filepath);\n }\n\n const readableStream = new PassThrough();\n\n // fetch the image from remote url and stream it\n strapi\n .fetch(filepath)\n .then((res: Response) => {\n if (res.status !== 200) {\n readableStream.emit('error', new Error(`Request failed with status code ${res.status}`));\n return;\n }\n\n if (res.body) {\n // pipe the image data\n Readable.fromWeb(res.body as webStream.ReadableStream<Uint8Array>).pipe(readableStream);\n } else {\n readableStream.emit('error', new Error('Empty data found for file'));\n }\n })\n .catch((error: unknown) => {\n readableStream.emit('error', error);\n });\n\n return readableStream;\n}\n\nexport function getFileStatsForTransfer(\n filepath: string,\n strapi: Core.Strapi,\n isLocal = false\n): Promise<{ size: number }> {\n if (isLocal) {\n return stat(filepath);\n }\n return new Promise((resolve, reject) => {\n strapi\n .fetch(filepath)\n .then((res: Response) => {\n if (res.status !== 200) {\n reject(new Error(`Request failed with status code ${res.status}`));\n return;\n }\n\n const contentLength = res.headers.get('content-length');\n const stats = {\n size: contentLength ? parseInt(contentLength, 10) : 0,\n };\n\n resolve(stats);\n })\n .catch((error: unknown) => {\n reject(error);\n });\n });\n}\n\nexport async function signUploadFileForTransfer(strapi: Core.Strapi, file: IFile) {\n const { provider } = strapi.plugins.upload;\n const { provider: providerName } = strapi.config.get('plugin.upload') as { provider: string };\n const isPrivate = await provider.isPrivate();\n if (file?.provider === providerName && isPrivate) {\n const signUrl = async (f: IFile) => {\n const signedUrl = await provider.getSignedUrl(f);\n f.url = signedUrl.url;\n };\n\n await signUrl(file);\n if (file.formats) {\n for (const format of Object.keys(file.formats)) {\n await signUrl(file.formats[format]);\n }\n }\n }\n}\n\nconst missingAssetWarningMessage = (file: IFile, filepath: string, format?: string): string => {\n const formatPart = format ? ` (format: ${format})` : '';\n return `[Data transfer] Media item ${file.id} (hash: ${file.hash}) exists in database but no corresponding file was found to transfer${formatPart}. Path: ${filepath}`;\n};\n\n/**\n * Generate and consume assets streams in order to stream each file individually\n */\nexport const createAssetsStream = (\n strapi: Core.Strapi,\n options: { onWarning?: (message: string) => void } = {}\n): Duplex => {\n const warnMissingAsset = (message: string) => {\n strapi.log.warn(message);\n options.onWarning?.(message);\n };\n\n const generator: () => AsyncGenerator<IAsset, void> = async function* generateAssets() {\n const stream: Readable = strapi.db\n .queryBuilder('plugin::upload.file')\n // Create a query builder instance (default type is 'select')\n // Fetch all columns\n .select('*')\n // Get a readable stream\n .stream();\n\n for await (const file of stream) {\n const isLocalProvider = file.provider === 'local';\n if (!isLocalProvider) {\n await signUploadFileForTransfer(strapi, file);\n }\n const filepath = isLocalProvider ? join(strapi.dirs.static.public, file.url) : file.url;\n let stats: { size: number };\n try {\n stats = await getFileStatsForTransfer(filepath, strapi, isLocalProvider);\n } catch (err: unknown) {\n const code =\n err && typeof err === 'object' && 'code' in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === 'ENOENT') {\n warnMissingAsset(missingAssetWarningMessage(file, filepath));\n continue;\n }\n throw err;\n }\n const stream = getFileStream(filepath, strapi, isLocalProvider);\n\n yield {\n metadata: file,\n filepath,\n filename: file.hash + file.ext,\n stream,\n stats: { size: stats.size },\n };\n\n if (file.formats) {\n for (const format of Object.keys(file.formats)) {\n const fileFormat = file.formats[format];\n const fileFormatFilepath = isLocalProvider\n ? join(strapi.dirs.static.public, fileFormat.url)\n : fileFormat.url;\n let fileFormatStats: { size: number };\n try {\n fileFormatStats = await getFileStatsForTransfer(\n fileFormatFilepath,\n strapi,\n isLocalProvider\n );\n } catch (err: unknown) {\n const code =\n err && typeof err === 'object' && 'code' in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === 'ENOENT') {\n warnMissingAsset(missingAssetWarningMessage(file, fileFormatFilepath, format));\n continue;\n }\n throw err;\n }\n const fileFormatStream = getFileStream(fileFormatFilepath, strapi, isLocalProvider);\n const metadata = { ...fileFormat, type: format, id: file.id, mainHash: file.hash };\n yield {\n metadata,\n filepath: fileFormatFilepath,\n filename: fileFormat.hash + fileFormat.ext,\n stream: fileFormatStream,\n stats: { size: fileFormatStats.size },\n };\n }\n }\n }\n };\n\n return Duplex.from(generator());\n};\n"],"names":["getFileStream","filepath","strapi","isLocal","createReadStream","readableStream","PassThrough","fetch","then","res","status","emit","Error","body","Readable","fromWeb","pipe","catch","error","getFileStatsForTransfer","stat","Promise","resolve","reject","contentLength","headers","get","stats","size","parseInt","signUploadFileForTransfer","file","provider","plugins","upload","providerName","config","isPrivate","signUrl","f","signedUrl","getSignedUrl","url","formats","format","Object","keys","missingAssetWarningMessage","formatPart","id","hash","createAssetsStream","options","warnMissingAsset","message","log","warn","onWarning","generator","generateAssets","stream","db","queryBuilder","select","isLocalProvider","join","dirs","static","public","err","code","undefined","metadata","filename","ext","fileFormat","fileFormatFilepath","fileFormatStats","fileFormatStream","type","mainHash","Duplex","from"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"assets.mjs","sources":["../../../../src/strapi/providers/local-source/assets.ts"],"sourcesContent":["import { join } from 'path';\nimport { Duplex, PassThrough, Readable } from 'stream';\nimport { stat, createReadStream, ReadStream } from 'fs-extra';\nimport * as webStream from 'stream/web';\nimport type { Core } from '@strapi/types';\n\nimport type { IAsset, IFile } from '../../../types';\n\nfunction getFileStream(\n filepath: string,\n strapi: Core.Strapi,\n isLocal = false\n): PassThrough | ReadStream {\n if (isLocal) {\n // Todo: handle errors\n return createReadStream(filepath);\n }\n\n const readableStream = new PassThrough();\n\n // fetch the image from remote url and stream it\n strapi\n .fetch(filepath)\n .then((res: Response) => {\n if (res.status !== 200) {\n readableStream.emit('error', new Error(`Request failed with status code ${res.status}`));\n return;\n }\n\n if (res.body) {\n // pipe the image data\n Readable.fromWeb(res.body as webStream.ReadableStream<Uint8Array>).pipe(readableStream);\n } else {\n readableStream.emit('error', new Error('Empty data found for file'));\n }\n })\n .catch((error: unknown) => {\n readableStream.emit('error', error);\n });\n\n return readableStream;\n}\n\nexport function getFileStatsForTransfer(\n filepath: string,\n strapi: Core.Strapi,\n isLocal = false\n): Promise<{ size: number }> {\n if (isLocal) {\n return stat(filepath);\n }\n return new Promise((resolve, reject) => {\n strapi\n .fetch(filepath)\n .then((res: Response) => {\n if (res.status !== 200) {\n reject(new Error(`Request failed with status code ${res.status}`));\n return;\n }\n\n const contentLength = res.headers.get('content-length');\n const stats = {\n size: contentLength ? parseInt(contentLength, 10) : 0,\n };\n\n resolve(stats);\n })\n .catch((error: unknown) => {\n reject(error);\n });\n });\n}\n\nexport async function signUploadFileForTransfer(strapi: Core.Strapi, file: IFile) {\n const { provider } = strapi.plugins.upload;\n const { provider: providerName } = strapi.config.get('plugin.upload') as { provider: string };\n const isPrivate = await provider.isPrivate();\n if (file?.provider === providerName && isPrivate) {\n const signUrl = async (f: IFile) => {\n const signedUrl = await provider.getSignedUrl(f);\n f.url = signedUrl.url;\n };\n\n await signUrl(file);\n if (file.formats) {\n for (const format of Object.keys(file.formats)) {\n await signUrl(file.formats[format]);\n }\n }\n }\n}\n\nconst missingAssetWarningMessage = (file: IFile, filepath: string, format?: string): string => {\n const formatPart = format ? ` (format: ${format})` : '';\n return `[Data transfer] Media item ${file.id} (hash: ${file.hash}) exists in database but no corresponding file was found to transfer${formatPart}. Path: ${filepath}`;\n};\n\n/**\n * Generate and consume assets streams in order to stream each file individually\n */\nexport const createAssetsStream = (\n strapi: Core.Strapi,\n options: { onWarning?: (message: string) => void } = {}\n): Duplex => {\n const warnMissingAsset = (message: string) => {\n strapi.log.warn(message);\n options.onWarning?.(message);\n };\n\n const generator: () => AsyncGenerator<IAsset, void> = async function* generateAssets() {\n const stream: Readable = strapi.db\n .queryBuilder('plugin::upload.file')\n // Create a query builder instance (default type is 'select')\n // Fetch all columns\n .select('*')\n // Get a readable stream\n .stream();\n\n for await (const file of stream) {\n const isLocalProvider = file.provider === 'local';\n if (!isLocalProvider) {\n await signUploadFileForTransfer(strapi, file);\n }\n const filepath = isLocalProvider ? join(strapi.dirs.static.public, file.url) : file.url;\n let stats: { size: number };\n try {\n stats = await getFileStatsForTransfer(filepath, strapi, isLocalProvider);\n } catch (err: unknown) {\n const code =\n err && typeof err === 'object' && 'code' in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === 'ENOENT') {\n warnMissingAsset(missingAssetWarningMessage(file, filepath));\n continue;\n }\n throw err;\n }\n const stream = getFileStream(filepath, strapi, isLocalProvider);\n\n yield {\n metadata: file,\n filepath,\n filename: `${file.hash}${file.ext ?? ''}`,\n stream,\n stats: { size: stats.size },\n };\n\n if (file.formats) {\n for (const format of Object.keys(file.formats)) {\n const fileFormat = file.formats[format];\n const fileFormatFilepath = isLocalProvider\n ? join(strapi.dirs.static.public, fileFormat.url)\n : fileFormat.url;\n let fileFormatStats: { size: number };\n try {\n fileFormatStats = await getFileStatsForTransfer(\n fileFormatFilepath,\n strapi,\n isLocalProvider\n );\n } catch (err: unknown) {\n const code =\n err && typeof err === 'object' && 'code' in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === 'ENOENT') {\n warnMissingAsset(missingAssetWarningMessage(file, fileFormatFilepath, format));\n continue;\n }\n throw err;\n }\n const fileFormatStream = getFileStream(fileFormatFilepath, strapi, isLocalProvider);\n const metadata = { ...fileFormat, type: format, id: file.id, mainHash: file.hash };\n yield {\n metadata,\n filepath: fileFormatFilepath,\n filename: `${fileFormat.hash}${fileFormat.ext ?? ''}`,\n stream: fileFormatStream,\n stats: { size: fileFormatStats.size },\n };\n }\n }\n }\n };\n\n return Duplex.from(generator());\n};\n"],"names":["getFileStream","filepath","strapi","isLocal","createReadStream","readableStream","PassThrough","fetch","then","res","status","emit","Error","body","Readable","fromWeb","pipe","catch","error","getFileStatsForTransfer","stat","Promise","resolve","reject","contentLength","headers","get","stats","size","parseInt","signUploadFileForTransfer","file","provider","plugins","upload","providerName","config","isPrivate","signUrl","f","signedUrl","getSignedUrl","url","formats","format","Object","keys","missingAssetWarningMessage","formatPart","id","hash","createAssetsStream","options","warnMissingAsset","message","log","warn","onWarning","generator","generateAssets","stream","db","queryBuilder","select","isLocalProvider","join","dirs","static","public","err","code","undefined","metadata","filename","ext","fileFormat","fileFormatFilepath","fileFormatStats","fileFormatStream","type","mainHash","Duplex","from"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Hash } from 'crypto';
|
|
2
2
|
import { Writable, PassThrough } from 'stream';
|
|
3
|
+
import type { Core } from '@strapi/types';
|
|
3
4
|
import type { TransferFlow } from '../flows';
|
|
4
5
|
import type { TransferStage, IAsset, Protocol } from '../../../types';
|
|
5
6
|
import { createLocalStrapiDestinationProvider } from '../../providers';
|
|
@@ -41,6 +42,12 @@ export interface PushHandler extends Handler {
|
|
|
41
42
|
* Interval for periodic destination memory logging during assets stage
|
|
42
43
|
*/
|
|
43
44
|
memoryLogInterval?: ReturnType<typeof setInterval>;
|
|
45
|
+
/** A rejected remote policy violation permanently invalidates this connection's transfer. */
|
|
46
|
+
terminal?: boolean;
|
|
47
|
+
/** Serialize WebSocket frames so a later close cannot race a policy rollback. */
|
|
48
|
+
messageQueue?: Promise<void>;
|
|
49
|
+
/** Shared teardown promise for policy rejection, errors, and socket close. */
|
|
50
|
+
abortPromise?: Promise<void>;
|
|
44
51
|
/**
|
|
45
52
|
* Checks that the given action is a valid push transfer action
|
|
46
53
|
*/
|
|
@@ -53,6 +60,8 @@ export interface PushHandler extends Handler {
|
|
|
53
60
|
* Simple override of the auth verification
|
|
54
61
|
*/
|
|
55
62
|
verifyAuth(): Promise<void>;
|
|
63
|
+
/** Process one already-serialized WebSocket frame. */
|
|
64
|
+
processMessage(raw: Parameters<Handler['onMessage']>[0]): Promise<void>;
|
|
56
65
|
/**
|
|
57
66
|
* Callback when receiving a regular transfer message
|
|
58
67
|
*/
|
|
@@ -81,7 +90,12 @@ export interface PushHandler extends Handler {
|
|
|
81
90
|
* Checks whether it's possible to stream a chunk for the given stage
|
|
82
91
|
*/
|
|
83
92
|
assertValidStreamTransferStep(stage: TransferStage): void;
|
|
93
|
+
abort(this: PushHandler, terminal?: boolean): Promise<void>;
|
|
84
94
|
}
|
|
95
|
+
type PushTransferTeardown = Pick<PushHandler, 'provider' | 'streams' | 'assets' | 'cleanup'>;
|
|
96
|
+
type ProtectedPushStreamStage = 'entities' | 'links';
|
|
97
|
+
export declare const abortPushTransfer: ({ provider, streams, assets, cleanup, }: PushTransferTeardown) => Promise<void>;
|
|
98
|
+
export declare const writeValidatedPushStreamBatch: (strapi: Core.Strapi, stage: ProtectedPushStreamStage, data: Protocol.Client.GetTransferPushStreamData<ProtectedPushStreamStage>, stream: Writable, stats: Protocol.Client.Stats) => Promise<void>;
|
|
85
99
|
export declare const createPushController: (options: import("./utils").HandlerOptions) => (ctx: import("koa").Context) => Promise<void>;
|
|
86
100
|
export {};
|
|
87
101
|
//# sourceMappingURL=push.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../../src/strapi/remote/handlers/push.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../../src/strapi/remote/handlers/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ require('fs-extra');
|
|
|
14
14
|
require('mime-types');
|
|
15
15
|
require('events');
|
|
16
16
|
require('ws');
|
|
17
|
+
var transferPolicy = require('../../transfer-policy.js');
|
|
17
18
|
var index = require('../flows/index.js');
|
|
18
19
|
var utils = require('./utils.js');
|
|
19
20
|
var _default = require('../flows/default.js');
|
|
@@ -27,6 +28,66 @@ const VALID_TRANSFER_ACTIONS = [
|
|
|
27
28
|
'getSchemas'
|
|
28
29
|
];
|
|
29
30
|
const TRANSFER_KIND = 'push';
|
|
31
|
+
const reportTeardownError = (error)=>{
|
|
32
|
+
strapi?.log?.error('[Data transfer] Failed to clean up push transfer');
|
|
33
|
+
strapi?.log?.error(error);
|
|
34
|
+
};
|
|
35
|
+
const abortPushTransfer = async ({ provider, streams, assets, cleanup })=>{
|
|
36
|
+
try {
|
|
37
|
+
for (const stream of Object.values(streams ?? {})){
|
|
38
|
+
try {
|
|
39
|
+
stream?.destroy();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
reportTeardownError(error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const asset of Object.values(assets ?? {})){
|
|
45
|
+
try {
|
|
46
|
+
asset.stream.destroy();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
reportTeardownError(error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (provider) {
|
|
52
|
+
try {
|
|
53
|
+
await provider.rollback();
|
|
54
|
+
} catch (error) {
|
|
55
|
+
reportTeardownError(error);
|
|
56
|
+
} finally{
|
|
57
|
+
// A local provider only owns Strapi lifecycle restoration after bootstrap.
|
|
58
|
+
if (provider.strapi) {
|
|
59
|
+
try {
|
|
60
|
+
await provider.close();
|
|
61
|
+
} catch (error) {
|
|
62
|
+
reportTeardownError(error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} finally{
|
|
68
|
+
try {
|
|
69
|
+
cleanup();
|
|
70
|
+
} catch (error) {
|
|
71
|
+
reportTeardownError(error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const writeValidatedPushStreamBatch = async (strapi1, stage, data, stream, stats)=>{
|
|
76
|
+
if (stage === 'entities') {
|
|
77
|
+
for (const entity of data){
|
|
78
|
+
transferPolicy.assertRemoteEntityAllowed(strapi1, entity);
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
for (const link of data){
|
|
82
|
+
transferPolicy.assertRemoteLinkAllowed(link);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
for (const item of data){
|
|
86
|
+
stats.started += 1;
|
|
87
|
+
await writableAsyncWrite.write(stream, item);
|
|
88
|
+
stats.finished += 1;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
30
91
|
const createPushController = utils.handlerControllerFactory((proto)=>({
|
|
31
92
|
isTransferStarted () {
|
|
32
93
|
return proto.isTransferStarted.call(this) && this.provider !== undefined;
|
|
@@ -67,14 +128,25 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
|
|
|
67
128
|
delete this.flow;
|
|
68
129
|
delete this.provider;
|
|
69
130
|
},
|
|
70
|
-
|
|
131
|
+
async abort (terminal = false) {
|
|
132
|
+
if (terminal) {
|
|
133
|
+
this.terminal = true;
|
|
134
|
+
}
|
|
135
|
+
if (this.abortPromise) {
|
|
136
|
+
return this.abortPromise;
|
|
137
|
+
}
|
|
138
|
+
this.abortPromise = abortPushTransfer({
|
|
139
|
+
...this,
|
|
140
|
+
cleanup: ()=>this.cleanup()
|
|
141
|
+
});
|
|
142
|
+
return this.abortPromise;
|
|
143
|
+
},
|
|
144
|
+
async teardown () {
|
|
71
145
|
if (this.memoryLogInterval) {
|
|
72
146
|
clearInterval(this.memoryLogInterval);
|
|
73
147
|
delete this.memoryLogInterval;
|
|
74
148
|
}
|
|
75
|
-
|
|
76
|
-
this.provider.rollback();
|
|
77
|
-
}
|
|
149
|
+
await this.abort();
|
|
78
150
|
proto.teardown.call(this);
|
|
79
151
|
},
|
|
80
152
|
assertValidTransfer () {
|
|
@@ -123,12 +195,23 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
|
|
|
123
195
|
this.streams[step] = await mapper[step]();
|
|
124
196
|
},
|
|
125
197
|
async onMessage (raw) {
|
|
198
|
+
const previousMessage = this.messageQueue ?? Promise.resolve();
|
|
199
|
+
const nextMessage = previousMessage.then(()=>this.processMessage(raw));
|
|
200
|
+
this.messageQueue = nextMessage.catch(()=>undefined);
|
|
201
|
+
return nextMessage;
|
|
202
|
+
},
|
|
203
|
+
async processMessage (raw) {
|
|
126
204
|
const msg = JSON.parse(raw.toString());
|
|
127
205
|
if (!utils.isDataTransferMessage(msg)) {
|
|
128
206
|
return;
|
|
129
207
|
}
|
|
130
208
|
if (!msg.uuid) {
|
|
131
209
|
await this.respond(undefined, new Error('Missing uuid in message'));
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (this.terminal) {
|
|
213
|
+
await this.respond(msg.uuid, new providers.ProviderTransferError('Transfer has been terminated'));
|
|
214
|
+
return;
|
|
132
215
|
}
|
|
133
216
|
if (proto.hasUUID(msg.uuid)) {
|
|
134
217
|
const previousResponse = proto.response;
|
|
@@ -248,6 +331,16 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
|
|
|
248
331
|
if (stage === 'assets') {
|
|
249
332
|
return this.streamAsset(msg.data);
|
|
250
333
|
}
|
|
334
|
+
try {
|
|
335
|
+
if (stage === 'entities' || stage === 'links') {
|
|
336
|
+
await writeValidatedPushStreamBatch(strapi, stage, msg.data, stream, this.stats[stage]);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
} catch (error) {
|
|
340
|
+
// Mark terminal before awaiting rollback so no queued WebSocket frame can commit.
|
|
341
|
+
await this.abort(true);
|
|
342
|
+
throw error;
|
|
343
|
+
}
|
|
251
344
|
// One objectMode Writable: do not overlap writes.
|
|
252
345
|
for (const item of msg.data){
|
|
253
346
|
this.stats[stage].started += 1;
|
|
@@ -361,11 +454,11 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
|
|
|
361
454
|
}
|
|
362
455
|
}
|
|
363
456
|
},
|
|
364
|
-
onClose () {
|
|
365
|
-
this.teardown();
|
|
457
|
+
async onClose () {
|
|
458
|
+
await this.teardown();
|
|
366
459
|
},
|
|
367
|
-
onError (err) {
|
|
368
|
-
this.teardown();
|
|
460
|
+
async onError (err) {
|
|
461
|
+
await this.teardown();
|
|
369
462
|
strapi.log.error(err);
|
|
370
463
|
},
|
|
371
464
|
// Commands
|
|
@@ -401,7 +494,7 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
|
|
|
401
494
|
this.flow = index.createFlow(_default);
|
|
402
495
|
this.provider = index$1.createLocalStrapiDestinationProvider({
|
|
403
496
|
strategy: params?.options?.strategy ?? 'restore',
|
|
404
|
-
restore: params?.options?.restore ?? {},
|
|
497
|
+
restore: transferPolicy.normalizeRemoteRestoreOptions(strapi, params?.options?.restore ?? {}),
|
|
405
498
|
autoDestroy: false,
|
|
406
499
|
getStrapi: ()=>strapi
|
|
407
500
|
});
|
|
@@ -450,5 +543,7 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
|
|
|
450
543
|
}
|
|
451
544
|
}));
|
|
452
545
|
|
|
546
|
+
exports.abortPushTransfer = abortPushTransfer;
|
|
453
547
|
exports.createPushController = createPushController;
|
|
548
|
+
exports.writeValidatedPushStreamBatch = writeValidatedPushStreamBatch;
|
|
454
549
|
//# sourceMappingURL=push.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.js","sources":["../../../../src/strapi/remote/handlers/push.ts"],"sourcesContent":["import { createHash, randomUUID, type Hash } from 'crypto';\nimport { Writable, PassThrough } from 'stream';\nimport type { Core } from '@strapi/types';\n\nimport type { TransferFlow, Step } from '../flows';\nimport type { TransferStage, IAsset, Protocol } from '../../../types';\n\nimport { ProviderTransferError } from '../../../errors/providers';\nimport { write } from '../../../utils/writable-async-write';\nimport { decodeTransferAssetStreamItem } from '../../../utils/transfer-asset-chunk';\nimport { createLocalStrapiDestinationProvider } from '../../providers';\nimport { createFlow, DEFAULT_TRANSFER_FLOW } from '../flows';\nimport { Handler } from './abstract';\nimport { handlerControllerFactory, isDataTransferMessage } from './utils';\n\nconst VALID_TRANSFER_ACTIONS = [\n 'bootstrap',\n 'close',\n 'rollback',\n 'beforeTransfer',\n 'getMetadata',\n 'getSchemas',\n] as const;\n\ntype PushTransferAction = (typeof VALID_TRANSFER_ACTIONS)[number];\n\nconst TRANSFER_KIND = 'push';\n\nexport interface PushHandler extends Handler {\n /**\n * Local Strapi Destination Provider used to write data to the current Strapi instance\n */\n provider?: ReturnType<typeof createLocalStrapiDestinationProvider>;\n\n /**\n * Holds all the stages' stream for the current transfer handler (one registry per connection)\n */\n streams?: { [stage in TransferStage]?: Writable };\n\n stats: {\n [stage in Exclude<TransferStage, 'schemas'>]: Protocol.Client.Stats;\n };\n\n /**\n * Holds all the transferred assets for the current transfer handler (one registry per connection)\n */\n assets: { [assetID: string]: IAsset & { stream: PassThrough } };\n /** Incremental checksum state keyed by transfer asset ID (only populated when checksums are enabled). */\n assetChecksums?: { [assetID: string]: Hash };\n checksumsEnabled?: boolean;\n\n /**\n * Orchestrate and manage the transfer messages' ordering\n */\n flow?: TransferFlow;\n\n /**\n * Interval for periodic destination memory logging during assets stage\n */\n memoryLogInterval?: ReturnType<typeof setInterval>;\n\n /**\n * Checks that the given action is a valid push transfer action\n */\n assertValidTransferAction(action: string): asserts action is PushTransferAction;\n\n /**\n * Create a new writable stream for the given step in the handler's stream registry\n */\n createWritableStreamForStep(step: TransferStage): Promise<void>;\n\n /**\n * Simple override of the auth verification\n */\n verifyAuth(): Promise<void>;\n\n /**\n * Callback when receiving a regular transfer message\n */\n onTransferMessage(msg: Protocol.Client.TransferMessage): Promise<unknown> | unknown;\n\n /**\n * Callback when receiving a transfer action message\n */\n onTransferAction(msg: Protocol.Client.Action): Promise<unknown> | unknown;\n\n /**\n * Callback when receiving a transfer step message\n */\n onTransferStep(msg: Protocol.Client.TransferPushMessage): Promise<unknown> | unknown;\n\n /**\n * Start streaming an asset\n */\n streamAsset(\n this: PushHandler,\n payload: Protocol.Client.GetTransferPushStreamData<'assets'>\n ): Promise<void>;\n\n // Transfer Flow\n\n /**\n * Try to move to a specific transfer stage & lock the step\n */\n lockTransferStep(stage: TransferStage): void;\n\n /**\n * Try to move to unlock the current step\n */\n unlockTransferStep(stage: TransferStage): void;\n\n /**\n * Checks whether it's possible to stream a chunk for the given stage\n */\n assertValidStreamTransferStep(stage: TransferStage): void;\n}\n\nexport const createPushController = handlerControllerFactory<Partial<PushHandler>>((proto) => ({\n isTransferStarted(this: PushHandler) {\n return proto.isTransferStarted.call(this) && this.provider !== undefined;\n },\n\n verifyAuth(this: PushHandler) {\n return proto.verifyAuth.call(this, TRANSFER_KIND);\n },\n onInfo(message) {\n this.diagnostics?.report({\n details: {\n message,\n origin: 'push-handler',\n createdAt: new Date(),\n },\n kind: 'info',\n });\n },\n onWarning(message) {\n this.diagnostics?.report({\n details: {\n message,\n createdAt: new Date(),\n origin: 'push-handler',\n },\n kind: 'warning',\n });\n },\n cleanup(this: PushHandler) {\n if (this.memoryLogInterval) {\n clearInterval(this.memoryLogInterval);\n delete this.memoryLogInterval;\n }\n proto.cleanup.call(this);\n\n this.streams = {};\n this.assets = {};\n this.assetChecksums = {};\n this.checksumsEnabled = false;\n\n delete this.flow;\n delete this.provider;\n },\n\n teardown(this: PushHandler) {\n if (this.memoryLogInterval) {\n clearInterval(this.memoryLogInterval);\n delete this.memoryLogInterval;\n }\n if (this.provider) {\n this.provider.rollback();\n }\n\n proto.teardown.call(this);\n },\n\n assertValidTransfer(this: PushHandler) {\n proto.assertValidTransfer.call(this);\n\n if (this.provider === undefined) {\n throw new Error('Invalid Transfer Process');\n }\n },\n\n assertValidTransferAction(this: PushHandler, action: PushTransferAction) {\n if (VALID_TRANSFER_ACTIONS.includes(action)) {\n return;\n }\n\n throw new ProviderTransferError(`Invalid action provided: \"${action}\"`, {\n action,\n validActions: Object.keys(VALID_TRANSFER_ACTIONS),\n });\n },\n\n assertValidStreamTransferStep(this: PushHandler, stage) {\n const currentStep = this.flow?.get();\n const nextStep: Step = { kind: 'transfer', stage };\n\n if (currentStep?.kind === 'transfer' && !currentStep.locked) {\n throw new ProviderTransferError(\n `You need to initialize the transfer stage (${nextStep}) before starting to stream data`\n );\n }\n\n if (this.flow?.cannot(nextStep)) {\n throw new ProviderTransferError(`Invalid stage (${nextStep}) provided for the current flow`, {\n step: nextStep,\n });\n }\n },\n\n async createWritableStreamForStep(this: PushHandler, step: Exclude<TransferStage, 'schemas'>) {\n const mapper = {\n entities: () => this.provider?.createEntitiesWriteStream(),\n links: () => this.provider?.createLinksWriteStream(),\n configuration: () => this.provider?.createConfigurationWriteStream(),\n assets: () => this.provider?.createAssetsWriteStream(),\n };\n\n if (!(step in mapper)) {\n throw new Error('Invalid transfer step, impossible to create a stream');\n }\n\n if (!this.streams) {\n throw new Error('Invalid transfer state');\n }\n\n this.streams[step] = await mapper[step]();\n },\n\n async onMessage(this: PushHandler, raw) {\n const msg = JSON.parse(raw.toString());\n\n if (!isDataTransferMessage(msg)) {\n return;\n }\n\n if (!msg.uuid) {\n await this.respond(undefined, new Error('Missing uuid in message'));\n }\n\n if (proto.hasUUID(msg.uuid)) {\n const previousResponse = proto.response;\n if (previousResponse?.uuid === msg.uuid) {\n await this.respond(previousResponse?.uuid, previousResponse.e, previousResponse.data);\n }\n return;\n }\n\n const { uuid, type } = msg;\n proto.addUUID(uuid);\n // Regular command message (init, end, status)\n if (type === 'command') {\n const { command } = msg;\n this.onInfo(`received command:${command} uuid:${uuid}`);\n await this.executeAndRespond(uuid, () => {\n this.assertValidTransferCommand(command);\n\n // The status command don't have params\n if (command === 'status') {\n return this.status();\n }\n return this[command](msg.params);\n });\n }\n\n // Transfer message (the transfer must be init first)\n else if (type === 'transfer') {\n this.onInfo(`received transfer action:${msg.action} step:${msg.kind} uuid:${uuid}`);\n await this.executeAndRespond(uuid, async () => {\n await this.verifyAuth();\n\n this.assertValidTransfer();\n\n return this.onTransferMessage(msg);\n });\n }\n\n // Invalid messages\n else {\n await this.respond(uuid, new Error('Bad Request'));\n }\n },\n\n async onTransferMessage(this: PushHandler, msg) {\n const { kind } = msg;\n\n if (kind === 'action') {\n return this.onTransferAction(msg);\n }\n\n if (kind === 'step') {\n return this.onTransferStep(msg as Protocol.Client.TransferPushMessage);\n }\n },\n\n lockTransferStep(stage: TransferStage) {\n const currentStep = this.flow?.get();\n const nextStep: Step = { kind: 'transfer', stage };\n\n if (currentStep?.kind === 'transfer' && currentStep.locked) {\n throw new ProviderTransferError(\n `It's not possible to start a new transfer stage (${stage}) while another one is in progress (${currentStep.stage})`\n );\n }\n\n if (this.flow?.cannot(nextStep)) {\n throw new ProviderTransferError(`Invalid stage (${stage}) provided for the current flow`, {\n step: nextStep,\n });\n }\n\n this.flow?.set({ ...nextStep, locked: true });\n },\n\n unlockTransferStep(stage: TransferStage) {\n const currentStep = this.flow?.get();\n const nextStep: Step = { kind: 'transfer', stage };\n\n // Cannot unlock if not locked (aka: started)\n if (currentStep?.kind === 'transfer' && !currentStep.locked) {\n throw new ProviderTransferError(\n `You need to initialize the transfer stage (${stage}) before ending it`\n );\n }\n\n // Cannot unlock if invalid step provided\n if (this.flow?.cannot(nextStep)) {\n throw new ProviderTransferError(`Invalid stage (${stage}) provided for the current flow`, {\n step: nextStep,\n });\n }\n\n this.flow?.set({ ...nextStep, locked: false });\n },\n\n async onTransferStep(this: PushHandler, msg) {\n const { step: stage } = msg;\n\n if (msg.action === 'start') {\n this.lockTransferStep(stage);\n\n if (this.streams?.[stage] instanceof Writable) {\n throw new Error('Stream already created, something went wrong');\n }\n\n await this.createWritableStreamForStep(stage);\n\n this.stats[stage] = { started: 0, finished: 0 };\n\n if (stage === 'assets') {\n strapi.log.debug(\n '[Transfer destination] Assets stage started; sampling memory usage every 5s until stage end'\n );\n this.memoryLogInterval = setInterval(() => {\n const mem = process.memoryUsage();\n const stats = this.stats?.assets;\n const rssMb = (mem.rss / 1024 / 1024).toFixed(1);\n const heapMb = (mem.heapUsed / 1024 / 1024).toFixed(1);\n strapi.log.debug(\n `[Transfer destination] memory RSS=${rssMb}MB heapUsed=${heapMb}MB | assets started=${stats?.started ?? 0} finished=${stats?.finished ?? 0}`\n );\n }, 5000);\n }\n\n return { ok: true };\n }\n\n if (msg.action === 'stream') {\n this.assertValidStreamTransferStep(stage);\n\n // Stream operation on the current transfer stage\n const stream = this.streams?.[stage];\n\n if (!stream) {\n throw new Error('You need to init first');\n }\n\n // Assets are nested streams\n if (stage === 'assets') {\n return this.streamAsset(msg.data);\n }\n\n // One objectMode Writable: do not overlap writes.\n for (const item of msg.data) {\n this.stats[stage].started += 1;\n await write(stream, item);\n this.stats[stage].finished += 1;\n }\n }\n\n if (msg.action === 'end') {\n if (stage === 'assets' && this.memoryLogInterval) {\n clearInterval(this.memoryLogInterval);\n delete this.memoryLogInterval;\n strapi.log.debug('[Transfer destination] Assets stage ended, stopped memory log');\n }\n this.unlockTransferStep(stage);\n const stream = this.streams?.[stage];\n\n if (stream && !stream.closed) {\n await new Promise((resolve, reject) => {\n stream.on('close', resolve).on('error', reject).end();\n });\n }\n\n delete this.streams?.[stage];\n\n return { ok: true, stats: this.stats[stage] };\n }\n },\n\n async onTransferAction(this: PushHandler, msg) {\n const { action } = msg;\n\n this.assertValidTransferAction(action);\n\n const step: Step = { kind: 'action', action };\n const isStepRegistered = this.flow?.has(step);\n\n if (isStepRegistered) {\n if (this.flow?.cannot(step)) {\n throw new ProviderTransferError(`Invalid action \"${action}\" found for the current flow `, {\n action,\n });\n }\n\n this.flow?.set(step);\n }\n if (action === 'bootstrap') {\n return this.provider?.[action](this.diagnostics);\n }\n return this.provider?.[action]();\n },\n\n async streamAsset(this: PushHandler, payload) {\n const assetsStream = this.streams?.assets;\n\n // TODO: close the stream upon receiving an 'end' event instead\n if (payload === null) {\n this.streams?.assets?.end();\n return;\n }\n\n for (const item of payload) {\n const { action, assetID } = item;\n\n if (!assetsStream) {\n throw new Error('Stream not defined');\n }\n\n if (action === 'start') {\n this.stats.assets.started += 1;\n this.assets[assetID] = { ...item.data, stream: new PassThrough() };\n if (this.checksumsEnabled) {\n this.assetChecksums ??= {};\n this.assetChecksums[assetID] = createHash('sha256');\n }\n const filename = item.data?.filename ?? assetID;\n strapi.log.debug(\n `[Transfer destination] Asset start #${this.stats.assets.started} id=${assetID} filename=${filename}`\n );\n // Wait for the assets stage to accept this row (same pattern as remote-source).\n await write(assetsStream, this.assets[assetID]);\n } else if (action === 'stream' || action === 'end') {\n if (!this.assets[assetID]) {\n throw new ProviderTransferError(\n `No asset \"${assetID}\" for ${action} action; send start before stream/end`\n );\n }\n\n if (action === 'stream') {\n const chunk = decodeTransferAssetStreamItem(item);\n this.assetChecksums?.[assetID]?.update(chunk);\n await write(this.assets[assetID].stream, chunk);\n } else {\n if (this.checksumsEnabled) {\n if (!item.checksum) {\n throw new ProviderTransferError(`Missing checksum for asset \"${assetID}\"`);\n }\n if (item.checksum.algorithm !== 'sha256') {\n throw new ProviderTransferError(\n `Unsupported checksum algorithm \"${item.checksum.algorithm}\" for asset ${assetID}`\n );\n }\n const checksum = this.assetChecksums?.[assetID]?.digest('hex');\n if (!checksum || checksum !== item.checksum.value) {\n throw new ProviderTransferError(\n `Checksum mismatch for asset \"${assetID}\" (expected ${item.checksum.value}, got ${checksum ?? 'none'})`\n );\n }\n }\n if (this.assetChecksums?.[assetID]) {\n delete this.assetChecksums[assetID];\n }\n strapi.log.debug(\n `[Transfer destination] Asset end id=${assetID} (finished=${this.stats.assets.finished + 1}/${this.stats.assets.started})`\n );\n await new Promise<void>((resolve, reject) => {\n const { stream: assetStream } = this.assets[assetID];\n assetStream\n .on('close', () => {\n this.stats.assets.finished += 1;\n delete this.assets[assetID];\n resolve();\n })\n .on('error', reject)\n .end();\n });\n }\n } else {\n throw new ProviderTransferError(\n `Invalid asset flow action: ${String((item as { action?: unknown }).action)}`\n );\n }\n }\n },\n\n onClose(this: Handler) {\n this.teardown();\n },\n\n onError(this: Handler, err) {\n this.teardown();\n strapi.log.error(err);\n },\n\n // Commands\n\n async init(\n this: PushHandler,\n params: Protocol.Client.GetCommandParams<'init'>\n ): Promise<Protocol.Server.Payload<Protocol.Server.InitMessage>> {\n if (this.transferID || this.provider) {\n throw new Error('Transfer already in progress');\n }\n\n await this.verifyAuth();\n\n this.transferID = randomUUID();\n this.startedAt = Date.now();\n\n this.assets = {};\n this.assetChecksums = {};\n this.checksumsEnabled = params?.checksums === true;\n this.streams = {};\n this.stats = {\n assets: { started: 0, finished: 0 },\n configuration: { started: 0, finished: 0 },\n entities: { started: 0, finished: 0 },\n links: { started: 0, finished: 0 },\n };\n\n this.flow = createFlow(DEFAULT_TRANSFER_FLOW);\n\n this.provider = createLocalStrapiDestinationProvider({\n strategy: params?.options?.strategy ?? 'restore',\n restore: params?.options?.restore ?? {},\n autoDestroy: false,\n getStrapi: () => strapi as Core.Strapi,\n });\n\n this.provider.onWarning = (message) => {\n this.onWarning(message);\n strapi.log.warn(message);\n };\n\n return {\n transferID: this.transferID,\n checksums: true,\n // Echo the client's requested asset wire format so it knows we can decode it. Older remotes\n // (pre-#23479) do `Buffer.from(item.data.data)` directly and will not echo this back — the\n // client treats the missing field as \"base64 unsupported\" and falls back to legacy shape.\n ...(params?.assetEncoding === 'base64' ? { assetEncoding: 'base64' as const } : {}),\n };\n },\n\n async status(this: PushHandler) {\n const isStarted = this.isTransferStarted();\n\n if (isStarted) {\n const startedAt = this.startedAt as number;\n\n return {\n active: true,\n kind: TRANSFER_KIND,\n startedAt,\n elapsed: Date.now() - startedAt,\n };\n }\n\n return { active: false, kind: null, elapsed: null, startedAt: null };\n },\n\n async end(\n this: PushHandler,\n params: Protocol.Client.GetCommandParams<'end'>\n ): Promise<Protocol.Server.Payload<Protocol.Server.EndMessage>> {\n await this.verifyAuth();\n\n if (this.transferID !== params?.transferID) {\n throw new ProviderTransferError('Bad transfer ID provided');\n }\n\n this.cleanup();\n\n return { ok: true };\n },\n}));\n"],"names":["VALID_TRANSFER_ACTIONS","TRANSFER_KIND","createPushController","handlerControllerFactory","proto","isTransferStarted","call","provider","undefined","verifyAuth","onInfo","message","diagnostics","report","details","origin","createdAt","Date","kind","onWarning","cleanup","memoryLogInterval","clearInterval","streams","assets","assetChecksums","checksumsEnabled","flow","teardown","rollback","assertValidTransfer","Error","assertValidTransferAction","action","includes","ProviderTransferError","validActions","Object","keys","assertValidStreamTransferStep","stage","currentStep","get","nextStep","locked","cannot","step","createWritableStreamForStep","mapper","entities","createEntitiesWriteStream","links","createLinksWriteStream","configuration","createConfigurationWriteStream","createAssetsWriteStream","onMessage","raw","msg","JSON","parse","toString","isDataTransferMessage","uuid","respond","hasUUID","previousResponse","response","e","data","type","addUUID","command","executeAndRespond","assertValidTransferCommand","status","params","onTransferMessage","onTransferAction","onTransferStep","lockTransferStep","set","unlockTransferStep","Writable","stats","started","finished","strapi","log","debug","setInterval","mem","process","memoryUsage","rssMb","rss","toFixed","heapMb","heapUsed","ok","stream","streamAsset","item","write","closed","Promise","resolve","reject","on","end","isStepRegistered","has","payload","assetsStream","assetID","PassThrough","createHash","filename","chunk","decodeTransferAssetStreamItem","update","checksum","algorithm","digest","value","assetStream","String","onClose","onError","err","error","init","transferID","randomUUID","startedAt","now","checksums","createFlow","DEFAULT_TRANSFER_FLOW","createLocalStrapiDestinationProvider","strategy","options","restore","autoDestroy","getStrapi","warn","assetEncoding","isStarted","active","elapsed"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"push.js","sources":["../../../../src/strapi/remote/handlers/push.ts"],"sourcesContent":["import { createHash, randomUUID, type Hash } from 'crypto';\nimport { Writable, PassThrough } from 'stream';\nimport type { Core } from '@strapi/types';\n\nimport type { TransferFlow, Step } from '../flows';\nimport type { TransferStage, IAsset, Protocol } from '../../../types';\n\nimport { ProviderTransferError } from '../../../errors/providers';\nimport { write } from '../../../utils/writable-async-write';\nimport { decodeTransferAssetStreamItem } from '../../../utils/transfer-asset-chunk';\nimport { createLocalStrapiDestinationProvider } from '../../providers';\nimport {\n assertRemoteEntityAllowed,\n assertRemoteLinkAllowed,\n normalizeRemoteRestoreOptions,\n} from '../../transfer-policy';\nimport { createFlow, DEFAULT_TRANSFER_FLOW } from '../flows';\nimport { Handler } from './abstract';\nimport { handlerControllerFactory, isDataTransferMessage } from './utils';\n\nconst VALID_TRANSFER_ACTIONS = [\n 'bootstrap',\n 'close',\n 'rollback',\n 'beforeTransfer',\n 'getMetadata',\n 'getSchemas',\n] as const;\n\ntype PushTransferAction = (typeof VALID_TRANSFER_ACTIONS)[number];\n\nconst TRANSFER_KIND = 'push';\n\nexport interface PushHandler extends Handler {\n /**\n * Local Strapi Destination Provider used to write data to the current Strapi instance\n */\n provider?: ReturnType<typeof createLocalStrapiDestinationProvider>;\n\n /**\n * Holds all the stages' stream for the current transfer handler (one registry per connection)\n */\n streams?: { [stage in TransferStage]?: Writable };\n\n stats: {\n [stage in Exclude<TransferStage, 'schemas'>]: Protocol.Client.Stats;\n };\n\n /**\n * Holds all the transferred assets for the current transfer handler (one registry per connection)\n */\n assets: { [assetID: string]: IAsset & { stream: PassThrough } };\n /** Incremental checksum state keyed by transfer asset ID (only populated when checksums are enabled). */\n assetChecksums?: { [assetID: string]: Hash };\n checksumsEnabled?: boolean;\n\n /**\n * Orchestrate and manage the transfer messages' ordering\n */\n flow?: TransferFlow;\n\n /**\n * Interval for periodic destination memory logging during assets stage\n */\n memoryLogInterval?: ReturnType<typeof setInterval>;\n\n /** A rejected remote policy violation permanently invalidates this connection's transfer. */\n terminal?: boolean;\n /** Serialize WebSocket frames so a later close cannot race a policy rollback. */\n messageQueue?: Promise<void>;\n /** Shared teardown promise for policy rejection, errors, and socket close. */\n abortPromise?: Promise<void>;\n\n /**\n * Checks that the given action is a valid push transfer action\n */\n assertValidTransferAction(action: string): asserts action is PushTransferAction;\n\n /**\n * Create a new writable stream for the given step in the handler's stream registry\n */\n createWritableStreamForStep(step: TransferStage): Promise<void>;\n\n /**\n * Simple override of the auth verification\n */\n verifyAuth(): Promise<void>;\n\n /** Process one already-serialized WebSocket frame. */\n processMessage(raw: Parameters<Handler['onMessage']>[0]): Promise<void>;\n\n /**\n * Callback when receiving a regular transfer message\n */\n onTransferMessage(msg: Protocol.Client.TransferMessage): Promise<unknown> | unknown;\n\n /**\n * Callback when receiving a transfer action message\n */\n onTransferAction(msg: Protocol.Client.Action): Promise<unknown> | unknown;\n\n /**\n * Callback when receiving a transfer step message\n */\n onTransferStep(msg: Protocol.Client.TransferPushMessage): Promise<unknown> | unknown;\n\n /**\n * Start streaming an asset\n */\n streamAsset(\n this: PushHandler,\n payload: Protocol.Client.GetTransferPushStreamData<'assets'>\n ): Promise<void>;\n\n // Transfer Flow\n\n /**\n * Try to move to a specific transfer stage & lock the step\n */\n lockTransferStep(stage: TransferStage): void;\n\n /**\n * Try to move to unlock the current step\n */\n unlockTransferStep(stage: TransferStage): void;\n\n /**\n * Checks whether it's possible to stream a chunk for the given stage\n */\n assertValidStreamTransferStep(stage: TransferStage): void;\n\n abort(this: PushHandler, terminal?: boolean): Promise<void>;\n}\n\ntype PushTransferTeardown = Pick<PushHandler, 'provider' | 'streams' | 'assets' | 'cleanup'>;\ntype ProtectedPushStreamStage = 'entities' | 'links';\n\nconst reportTeardownError = (error: unknown) => {\n strapi?.log?.error('[Data transfer] Failed to clean up push transfer');\n strapi?.log?.error(error);\n};\n\nexport const abortPushTransfer = async ({\n provider,\n streams,\n assets,\n cleanup,\n}: PushTransferTeardown): Promise<void> => {\n try {\n for (const stream of Object.values(streams ?? {})) {\n try {\n stream?.destroy();\n } catch (error) {\n reportTeardownError(error);\n }\n }\n for (const asset of Object.values(assets ?? {})) {\n try {\n asset.stream.destroy();\n } catch (error) {\n reportTeardownError(error);\n }\n }\n\n if (provider) {\n try {\n await provider.rollback();\n } catch (error) {\n reportTeardownError(error);\n } finally {\n // A local provider only owns Strapi lifecycle restoration after bootstrap.\n if (provider.strapi) {\n try {\n await provider.close();\n } catch (error) {\n reportTeardownError(error);\n }\n }\n }\n }\n } finally {\n try {\n cleanup();\n } catch (error) {\n reportTeardownError(error);\n }\n }\n};\n\nexport const writeValidatedPushStreamBatch = async (\n strapi: Core.Strapi,\n stage: ProtectedPushStreamStage,\n data: Protocol.Client.GetTransferPushStreamData<ProtectedPushStreamStage>,\n stream: Writable,\n stats: Protocol.Client.Stats\n): Promise<void> => {\n if (stage === 'entities') {\n for (const entity of data as Protocol.Client.GetTransferPushStreamData<'entities'>) {\n assertRemoteEntityAllowed(strapi, entity);\n }\n } else {\n for (const link of data as Protocol.Client.GetTransferPushStreamData<'links'>) {\n assertRemoteLinkAllowed(link);\n }\n }\n\n for (const item of data) {\n stats.started += 1;\n await write(stream, item);\n stats.finished += 1;\n }\n};\n\nexport const createPushController = handlerControllerFactory<Partial<PushHandler>>((proto) => ({\n isTransferStarted(this: PushHandler) {\n return proto.isTransferStarted.call(this) && this.provider !== undefined;\n },\n\n verifyAuth(this: PushHandler) {\n return proto.verifyAuth.call(this, TRANSFER_KIND);\n },\n onInfo(message) {\n this.diagnostics?.report({\n details: {\n message,\n origin: 'push-handler',\n createdAt: new Date(),\n },\n kind: 'info',\n });\n },\n onWarning(message) {\n this.diagnostics?.report({\n details: {\n message,\n createdAt: new Date(),\n origin: 'push-handler',\n },\n kind: 'warning',\n });\n },\n cleanup(this: PushHandler) {\n if (this.memoryLogInterval) {\n clearInterval(this.memoryLogInterval);\n delete this.memoryLogInterval;\n }\n proto.cleanup.call(this);\n\n this.streams = {};\n this.assets = {};\n this.assetChecksums = {};\n this.checksumsEnabled = false;\n\n delete this.flow;\n delete this.provider;\n },\n\n async abort(this: PushHandler, terminal = false) {\n if (terminal) {\n this.terminal = true;\n }\n\n if (this.abortPromise) {\n return this.abortPromise;\n }\n\n this.abortPromise = abortPushTransfer({ ...this, cleanup: () => this.cleanup() });\n\n return this.abortPromise;\n },\n\n async teardown(this: PushHandler) {\n if (this.memoryLogInterval) {\n clearInterval(this.memoryLogInterval);\n delete this.memoryLogInterval;\n }\n await this.abort();\n proto.teardown.call(this);\n },\n\n assertValidTransfer(this: PushHandler) {\n proto.assertValidTransfer.call(this);\n\n if (this.provider === undefined) {\n throw new Error('Invalid Transfer Process');\n }\n },\n\n assertValidTransferAction(this: PushHandler, action: PushTransferAction) {\n if (VALID_TRANSFER_ACTIONS.includes(action)) {\n return;\n }\n\n throw new ProviderTransferError(`Invalid action provided: \"${action}\"`, {\n action,\n validActions: Object.keys(VALID_TRANSFER_ACTIONS),\n });\n },\n\n assertValidStreamTransferStep(this: PushHandler, stage) {\n const currentStep = this.flow?.get();\n const nextStep: Step = { kind: 'transfer', stage };\n\n if (currentStep?.kind === 'transfer' && !currentStep.locked) {\n throw new ProviderTransferError(\n `You need to initialize the transfer stage (${nextStep}) before starting to stream data`\n );\n }\n\n if (this.flow?.cannot(nextStep)) {\n throw new ProviderTransferError(`Invalid stage (${nextStep}) provided for the current flow`, {\n step: nextStep,\n });\n }\n },\n\n async createWritableStreamForStep(this: PushHandler, step: Exclude<TransferStage, 'schemas'>) {\n const mapper = {\n entities: () => this.provider?.createEntitiesWriteStream(),\n links: () => this.provider?.createLinksWriteStream(),\n configuration: () => this.provider?.createConfigurationWriteStream(),\n assets: () => this.provider?.createAssetsWriteStream(),\n };\n\n if (!(step in mapper)) {\n throw new Error('Invalid transfer step, impossible to create a stream');\n }\n\n if (!this.streams) {\n throw new Error('Invalid transfer state');\n }\n\n this.streams[step] = await mapper[step]();\n },\n\n async onMessage(this: PushHandler, raw) {\n const previousMessage = this.messageQueue ?? Promise.resolve();\n const nextMessage = previousMessage.then(() => this.processMessage(raw));\n this.messageQueue = nextMessage.catch(() => undefined);\n return nextMessage;\n },\n\n async processMessage(this: PushHandler, raw) {\n const msg = JSON.parse(raw.toString());\n\n if (!isDataTransferMessage(msg)) {\n return;\n }\n\n if (!msg.uuid) {\n await this.respond(undefined, new Error('Missing uuid in message'));\n return;\n }\n\n if (this.terminal) {\n await this.respond(msg.uuid, new ProviderTransferError('Transfer has been terminated'));\n return;\n }\n\n if (proto.hasUUID(msg.uuid)) {\n const previousResponse = proto.response;\n if (previousResponse?.uuid === msg.uuid) {\n await this.respond(previousResponse?.uuid, previousResponse.e, previousResponse.data);\n }\n return;\n }\n\n const { uuid, type } = msg;\n proto.addUUID(uuid);\n // Regular command message (init, end, status)\n if (type === 'command') {\n const { command } = msg;\n this.onInfo(`received command:${command} uuid:${uuid}`);\n await this.executeAndRespond(uuid, () => {\n this.assertValidTransferCommand(command);\n\n // The status command don't have params\n if (command === 'status') {\n return this.status();\n }\n return this[command](msg.params);\n });\n }\n\n // Transfer message (the transfer must be init first)\n else if (type === 'transfer') {\n this.onInfo(`received transfer action:${msg.action} step:${msg.kind} uuid:${uuid}`);\n await this.executeAndRespond(uuid, async () => {\n await this.verifyAuth();\n\n this.assertValidTransfer();\n\n return this.onTransferMessage(msg);\n });\n }\n\n // Invalid messages\n else {\n await this.respond(uuid, new Error('Bad Request'));\n }\n },\n\n async onTransferMessage(this: PushHandler, msg) {\n const { kind } = msg;\n\n if (kind === 'action') {\n return this.onTransferAction(msg);\n }\n\n if (kind === 'step') {\n return this.onTransferStep(msg as Protocol.Client.TransferPushMessage);\n }\n },\n\n lockTransferStep(stage: TransferStage) {\n const currentStep = this.flow?.get();\n const nextStep: Step = { kind: 'transfer', stage };\n\n if (currentStep?.kind === 'transfer' && currentStep.locked) {\n throw new ProviderTransferError(\n `It's not possible to start a new transfer stage (${stage}) while another one is in progress (${currentStep.stage})`\n );\n }\n\n if (this.flow?.cannot(nextStep)) {\n throw new ProviderTransferError(`Invalid stage (${stage}) provided for the current flow`, {\n step: nextStep,\n });\n }\n\n this.flow?.set({ ...nextStep, locked: true });\n },\n\n unlockTransferStep(stage: TransferStage) {\n const currentStep = this.flow?.get();\n const nextStep: Step = { kind: 'transfer', stage };\n\n // Cannot unlock if not locked (aka: started)\n if (currentStep?.kind === 'transfer' && !currentStep.locked) {\n throw new ProviderTransferError(\n `You need to initialize the transfer stage (${stage}) before ending it`\n );\n }\n\n // Cannot unlock if invalid step provided\n if (this.flow?.cannot(nextStep)) {\n throw new ProviderTransferError(`Invalid stage (${stage}) provided for the current flow`, {\n step: nextStep,\n });\n }\n\n this.flow?.set({ ...nextStep, locked: false });\n },\n\n async onTransferStep(this: PushHandler, msg) {\n const { step: stage } = msg;\n\n if (msg.action === 'start') {\n this.lockTransferStep(stage);\n\n if (this.streams?.[stage] instanceof Writable) {\n throw new Error('Stream already created, something went wrong');\n }\n\n await this.createWritableStreamForStep(stage);\n\n this.stats[stage] = { started: 0, finished: 0 };\n\n if (stage === 'assets') {\n strapi.log.debug(\n '[Transfer destination] Assets stage started; sampling memory usage every 5s until stage end'\n );\n this.memoryLogInterval = setInterval(() => {\n const mem = process.memoryUsage();\n const stats = this.stats?.assets;\n const rssMb = (mem.rss / 1024 / 1024).toFixed(1);\n const heapMb = (mem.heapUsed / 1024 / 1024).toFixed(1);\n strapi.log.debug(\n `[Transfer destination] memory RSS=${rssMb}MB heapUsed=${heapMb}MB | assets started=${\n stats?.started ?? 0\n } finished=${stats?.finished ?? 0}`\n );\n }, 5000);\n }\n\n return { ok: true };\n }\n\n if (msg.action === 'stream') {\n this.assertValidStreamTransferStep(stage);\n\n // Stream operation on the current transfer stage\n const stream = this.streams?.[stage];\n\n if (!stream) {\n throw new Error('You need to init first');\n }\n\n // Assets are nested streams\n if (stage === 'assets') {\n return this.streamAsset(msg.data);\n }\n\n try {\n if (stage === 'entities' || stage === 'links') {\n await writeValidatedPushStreamBatch(\n strapi as Core.Strapi,\n stage,\n msg.data,\n stream,\n this.stats[stage]\n );\n return;\n }\n } catch (error) {\n // Mark terminal before awaiting rollback so no queued WebSocket frame can commit.\n await this.abort(true);\n throw error;\n }\n\n // One objectMode Writable: do not overlap writes.\n for (const item of msg.data) {\n this.stats[stage].started += 1;\n await write(stream, item);\n this.stats[stage].finished += 1;\n }\n }\n\n if (msg.action === 'end') {\n if (stage === 'assets' && this.memoryLogInterval) {\n clearInterval(this.memoryLogInterval);\n delete this.memoryLogInterval;\n strapi.log.debug('[Transfer destination] Assets stage ended, stopped memory log');\n }\n this.unlockTransferStep(stage);\n const stream = this.streams?.[stage];\n\n if (stream && !stream.closed) {\n await new Promise((resolve, reject) => {\n stream.on('close', resolve).on('error', reject).end();\n });\n }\n\n delete this.streams?.[stage];\n\n return { ok: true, stats: this.stats[stage] };\n }\n },\n\n async onTransferAction(this: PushHandler, msg) {\n const { action } = msg;\n\n this.assertValidTransferAction(action);\n\n const step: Step = { kind: 'action', action };\n const isStepRegistered = this.flow?.has(step);\n\n if (isStepRegistered) {\n if (this.flow?.cannot(step)) {\n throw new ProviderTransferError(`Invalid action \"${action}\" found for the current flow `, {\n action,\n });\n }\n\n this.flow?.set(step);\n }\n if (action === 'bootstrap') {\n return this.provider?.[action](this.diagnostics);\n }\n return this.provider?.[action]();\n },\n\n async streamAsset(this: PushHandler, payload) {\n const assetsStream = this.streams?.assets;\n\n // TODO: close the stream upon receiving an 'end' event instead\n if (payload === null) {\n this.streams?.assets?.end();\n return;\n }\n\n for (const item of payload) {\n const { action, assetID } = item;\n\n if (!assetsStream) {\n throw new Error('Stream not defined');\n }\n\n if (action === 'start') {\n this.stats.assets.started += 1;\n this.assets[assetID] = { ...item.data, stream: new PassThrough() };\n if (this.checksumsEnabled) {\n this.assetChecksums ??= {};\n this.assetChecksums[assetID] = createHash('sha256');\n }\n const filename = item.data?.filename ?? assetID;\n strapi.log.debug(\n `[Transfer destination] Asset start #${this.stats.assets.started} id=${assetID} filename=${filename}`\n );\n // Wait for the assets stage to accept this row (same pattern as remote-source).\n await write(assetsStream, this.assets[assetID]);\n } else if (action === 'stream' || action === 'end') {\n if (!this.assets[assetID]) {\n throw new ProviderTransferError(\n `No asset \"${assetID}\" for ${action} action; send start before stream/end`\n );\n }\n\n if (action === 'stream') {\n const chunk = decodeTransferAssetStreamItem(item);\n this.assetChecksums?.[assetID]?.update(chunk);\n await write(this.assets[assetID].stream, chunk);\n } else {\n if (this.checksumsEnabled) {\n if (!item.checksum) {\n throw new ProviderTransferError(`Missing checksum for asset \"${assetID}\"`);\n }\n if (item.checksum.algorithm !== 'sha256') {\n throw new ProviderTransferError(\n `Unsupported checksum algorithm \"${item.checksum.algorithm}\" for asset ${assetID}`\n );\n }\n const checksum = this.assetChecksums?.[assetID]?.digest('hex');\n if (!checksum || checksum !== item.checksum.value) {\n throw new ProviderTransferError(\n `Checksum mismatch for asset \"${assetID}\" (expected ${item.checksum.value}, got ${\n checksum ?? 'none'\n })`\n );\n }\n }\n if (this.assetChecksums?.[assetID]) {\n delete this.assetChecksums[assetID];\n }\n strapi.log.debug(\n `[Transfer destination] Asset end id=${assetID} (finished=${\n this.stats.assets.finished + 1\n }/${this.stats.assets.started})`\n );\n await new Promise<void>((resolve, reject) => {\n const { stream: assetStream } = this.assets[assetID];\n assetStream\n .on('close', () => {\n this.stats.assets.finished += 1;\n delete this.assets[assetID];\n resolve();\n })\n .on('error', reject)\n .end();\n });\n }\n } else {\n throw new ProviderTransferError(\n `Invalid asset flow action: ${String((item as { action?: unknown }).action)}`\n );\n }\n }\n },\n\n async onClose(this: PushHandler) {\n await this.teardown();\n },\n\n async onError(this: PushHandler, err) {\n await this.teardown();\n strapi.log.error(err);\n },\n\n // Commands\n\n async init(\n this: PushHandler,\n params: Protocol.Client.GetCommandParams<'init'>\n ): Promise<Protocol.Server.Payload<Protocol.Server.InitMessage>> {\n if (this.transferID || this.provider) {\n throw new Error('Transfer already in progress');\n }\n\n await this.verifyAuth();\n\n this.transferID = randomUUID();\n this.startedAt = Date.now();\n\n this.assets = {};\n this.assetChecksums = {};\n this.checksumsEnabled = params?.checksums === true;\n this.streams = {};\n this.stats = {\n assets: { started: 0, finished: 0 },\n configuration: { started: 0, finished: 0 },\n entities: { started: 0, finished: 0 },\n links: { started: 0, finished: 0 },\n };\n\n this.flow = createFlow(DEFAULT_TRANSFER_FLOW);\n\n this.provider = createLocalStrapiDestinationProvider({\n strategy: params?.options?.strategy ?? 'restore',\n restore: normalizeRemoteRestoreOptions(strapi as Core.Strapi, params?.options?.restore ?? {}),\n autoDestroy: false,\n getStrapi: () => strapi as Core.Strapi,\n });\n\n this.provider.onWarning = (message) => {\n this.onWarning(message);\n strapi.log.warn(message);\n };\n\n return {\n transferID: this.transferID,\n checksums: true,\n // Echo the client's requested asset wire format so it knows we can decode it. Older remotes\n // (pre-#23479) do `Buffer.from(item.data.data)` directly and will not echo this back — the\n // client treats the missing field as \"base64 unsupported\" and falls back to legacy shape.\n ...(params?.assetEncoding === 'base64' ? { assetEncoding: 'base64' as const } : {}),\n };\n },\n\n async status(this: PushHandler) {\n const isStarted = this.isTransferStarted();\n\n if (isStarted) {\n const startedAt = this.startedAt as number;\n\n return {\n active: true,\n kind: TRANSFER_KIND,\n startedAt,\n elapsed: Date.now() - startedAt,\n };\n }\n\n return { active: false, kind: null, elapsed: null, startedAt: null };\n },\n\n async end(\n this: PushHandler,\n params: Protocol.Client.GetCommandParams<'end'>\n ): Promise<Protocol.Server.Payload<Protocol.Server.EndMessage>> {\n await this.verifyAuth();\n\n if (this.transferID !== params?.transferID) {\n throw new ProviderTransferError('Bad transfer ID provided');\n }\n\n this.cleanup();\n\n return { ok: true };\n },\n}));\n"],"names":["VALID_TRANSFER_ACTIONS","TRANSFER_KIND","reportTeardownError","error","strapi","log","abortPushTransfer","provider","streams","assets","cleanup","stream","Object","values","destroy","asset","rollback","close","writeValidatedPushStreamBatch","stage","data","stats","entity","assertRemoteEntityAllowed","link","assertRemoteLinkAllowed","item","started","write","finished","createPushController","handlerControllerFactory","proto","isTransferStarted","call","undefined","verifyAuth","onInfo","message","diagnostics","report","details","origin","createdAt","Date","kind","onWarning","memoryLogInterval","clearInterval","assetChecksums","checksumsEnabled","flow","abort","terminal","abortPromise","teardown","assertValidTransfer","Error","assertValidTransferAction","action","includes","ProviderTransferError","validActions","keys","assertValidStreamTransferStep","currentStep","get","nextStep","locked","cannot","step","createWritableStreamForStep","mapper","entities","createEntitiesWriteStream","links","createLinksWriteStream","configuration","createConfigurationWriteStream","createAssetsWriteStream","onMessage","raw","previousMessage","messageQueue","Promise","resolve","nextMessage","then","processMessage","catch","msg","JSON","parse","toString","isDataTransferMessage","uuid","respond","hasUUID","previousResponse","response","e","type","addUUID","command","executeAndRespond","assertValidTransferCommand","status","params","onTransferMessage","onTransferAction","onTransferStep","lockTransferStep","set","unlockTransferStep","Writable","debug","setInterval","mem","process","memoryUsage","rssMb","rss","toFixed","heapMb","heapUsed","ok","streamAsset","closed","reject","on","end","isStepRegistered","has","payload","assetsStream","assetID","PassThrough","createHash","filename","chunk","decodeTransferAssetStreamItem","update","checksum","algorithm","digest","value","assetStream","String","onClose","onError","err","init","transferID","randomUUID","startedAt","now","checksums","createFlow","DEFAULT_TRANSFER_FLOW","createLocalStrapiDestinationProvider","strategy","options","restore","normalizeRemoteRestoreOptions","autoDestroy","getStrapi","warn","assetEncoding","isStarted","active","elapsed"],"mappings":"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"}
|