@strapi/data-transfer 5.42.1 → 5.43.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.
Files changed (126) hide show
  1. package/dist/directory/providers/source/index.d.ts.map +1 -1
  2. package/dist/directory/providers/source/index.js +3 -2
  3. package/dist/directory/providers/source/index.js.map +1 -1
  4. package/dist/directory/providers/source/index.mjs +3 -2
  5. package/dist/directory/providers/source/index.mjs.map +1 -1
  6. package/dist/engine/index.d.ts.map +1 -1
  7. package/dist/engine/index.js +130 -5
  8. package/dist/engine/index.js.map +1 -1
  9. package/dist/engine/index.mjs +130 -5
  10. package/dist/engine/index.mjs.map +1 -1
  11. package/dist/engine/validation/schemas/index.js +2 -0
  12. package/dist/engine/validation/schemas/index.js.map +1 -1
  13. package/dist/engine/validation/schemas/index.mjs +2 -0
  14. package/dist/engine/validation/schemas/index.mjs.map +1 -1
  15. package/dist/file/providers/source/index.d.ts.map +1 -1
  16. package/dist/file/providers/source/index.js +84 -45
  17. package/dist/file/providers/source/index.js.map +1 -1
  18. package/dist/file/providers/source/index.mjs +85 -46
  19. package/dist/file/providers/source/index.mjs.map +1 -1
  20. package/dist/strapi/providers/index.js +2 -0
  21. package/dist/strapi/providers/index.js.map +1 -1
  22. package/dist/strapi/providers/index.mjs +1 -0
  23. package/dist/strapi/providers/index.mjs.map +1 -1
  24. package/dist/strapi/providers/local-destination/assets-destination-writable.d.ts +22 -0
  25. package/dist/strapi/providers/local-destination/assets-destination-writable.d.ts.map +1 -0
  26. package/dist/strapi/providers/local-destination/assets-destination-writable.js +107 -0
  27. package/dist/strapi/providers/local-destination/assets-destination-writable.js.map +1 -0
  28. package/dist/strapi/providers/local-destination/assets-destination-writable.mjs +105 -0
  29. package/dist/strapi/providers/local-destination/assets-destination-writable.mjs.map +1 -0
  30. package/dist/strapi/providers/local-destination/index.d.ts +2 -0
  31. package/dist/strapi/providers/local-destination/index.d.ts.map +1 -1
  32. package/dist/strapi/providers/local-destination/index.js +18 -79
  33. package/dist/strapi/providers/local-destination/index.js.map +1 -1
  34. package/dist/strapi/providers/local-destination/index.mjs +18 -79
  35. package/dist/strapi/providers/local-destination/index.mjs.map +1 -1
  36. package/dist/strapi/providers/local-destination/strategies/restore/entities.js +2 -0
  37. package/dist/strapi/providers/local-destination/strategies/restore/entities.js.map +1 -1
  38. package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs +2 -0
  39. package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs.map +1 -1
  40. package/dist/strapi/providers/local-destination/strategies/restore/index.js +2 -0
  41. package/dist/strapi/providers/local-destination/strategies/restore/index.js.map +1 -1
  42. package/dist/strapi/providers/local-destination/strategies/restore/index.mjs +2 -0
  43. package/dist/strapi/providers/local-destination/strategies/restore/index.mjs.map +1 -1
  44. package/dist/strapi/providers/local-source/assets.d.ts +8 -1
  45. package/dist/strapi/providers/local-source/assets.d.ts.map +1 -1
  46. package/dist/strapi/providers/local-source/assets.js +47 -19
  47. package/dist/strapi/providers/local-source/assets.js.map +1 -1
  48. package/dist/strapi/providers/local-source/assets.mjs +46 -20
  49. package/dist/strapi/providers/local-source/assets.mjs.map +1 -1
  50. package/dist/strapi/providers/local-source/estimate-asset-totals.d.ts +11 -0
  51. package/dist/strapi/providers/local-source/estimate-asset-totals.d.ts.map +1 -0
  52. package/dist/strapi/providers/local-source/estimate-asset-totals.js +130 -0
  53. package/dist/strapi/providers/local-source/estimate-asset-totals.js.map +1 -0
  54. package/dist/strapi/providers/local-source/estimate-asset-totals.mjs +128 -0
  55. package/dist/strapi/providers/local-source/estimate-asset-totals.mjs.map +1 -0
  56. package/dist/strapi/providers/local-source/index.d.ts +3 -2
  57. package/dist/strapi/providers/local-source/index.d.ts.map +1 -1
  58. package/dist/strapi/providers/local-source/index.js +30 -3
  59. package/dist/strapi/providers/local-source/index.js.map +1 -1
  60. package/dist/strapi/providers/local-source/index.mjs +30 -4
  61. package/dist/strapi/providers/local-source/index.mjs.map +1 -1
  62. package/dist/strapi/providers/remote-destination/index.d.ts +3 -1
  63. package/dist/strapi/providers/remote-destination/index.d.ts.map +1 -1
  64. package/dist/strapi/providers/remote-destination/index.js +88 -19
  65. package/dist/strapi/providers/remote-destination/index.js.map +1 -1
  66. package/dist/strapi/providers/remote-destination/index.mjs +89 -20
  67. package/dist/strapi/providers/remote-destination/index.mjs.map +1 -1
  68. package/dist/strapi/providers/remote-source/index.d.ts +6 -3
  69. package/dist/strapi/providers/remote-source/index.d.ts.map +1 -1
  70. package/dist/strapi/providers/remote-source/index.js +180 -47
  71. package/dist/strapi/providers/remote-source/index.js.map +1 -1
  72. package/dist/strapi/providers/remote-source/index.mjs +181 -48
  73. package/dist/strapi/providers/remote-source/index.mjs.map +1 -1
  74. package/dist/strapi/providers/utils.d.ts +9 -6
  75. package/dist/strapi/providers/utils.d.ts.map +1 -1
  76. package/dist/strapi/providers/utils.js +9 -4
  77. package/dist/strapi/providers/utils.js.map +1 -1
  78. package/dist/strapi/providers/utils.mjs +9 -4
  79. package/dist/strapi/providers/utils.mjs.map +1 -1
  80. package/dist/strapi/remote/handlers/pull.d.ts +1 -0
  81. package/dist/strapi/remote/handlers/pull.d.ts.map +1 -1
  82. package/dist/strapi/remote/handlers/pull.js +36 -15
  83. package/dist/strapi/remote/handlers/pull.js.map +1 -1
  84. package/dist/strapi/remote/handlers/pull.mjs +37 -16
  85. package/dist/strapi/remote/handlers/pull.mjs.map +1 -1
  86. package/dist/strapi/remote/handlers/push.d.ts +13 -2
  87. package/dist/strapi/remote/handlers/push.d.ts.map +1 -1
  88. package/dist/strapi/remote/handlers/push.js +81 -34
  89. package/dist/strapi/remote/handlers/push.js.map +1 -1
  90. package/dist/strapi/remote/handlers/push.mjs +82 -35
  91. package/dist/strapi/remote/handlers/push.mjs.map +1 -1
  92. package/dist/strapi/remote/handlers/utils.d.ts.map +1 -1
  93. package/dist/strapi/remote/handlers/utils.js +5 -3
  94. package/dist/strapi/remote/handlers/utils.js.map +1 -1
  95. package/dist/strapi/remote/handlers/utils.mjs +5 -3
  96. package/dist/strapi/remote/handlers/utils.mjs.map +1 -1
  97. package/dist/utils/index.d.ts +2 -0
  98. package/dist/utils/index.d.ts.map +1 -1
  99. package/dist/utils/index.js +7 -0
  100. package/dist/utils/index.js.map +1 -1
  101. package/dist/utils/index.mjs +2 -0
  102. package/dist/utils/index.mjs.map +1 -1
  103. package/dist/utils/stream.d.ts.map +1 -1
  104. package/dist/utils/stream.js +40 -3
  105. package/dist/utils/stream.js.map +1 -1
  106. package/dist/utils/stream.mjs +40 -3
  107. package/dist/utils/stream.mjs.map +1 -1
  108. package/dist/utils/transfer-asset-chunk.d.ts +41 -0
  109. package/dist/utils/transfer-asset-chunk.d.ts.map +1 -0
  110. package/dist/utils/transfer-asset-chunk.js +93 -0
  111. package/dist/utils/transfer-asset-chunk.js.map +1 -0
  112. package/dist/utils/transfer-asset-chunk.mjs +88 -0
  113. package/dist/utils/transfer-asset-chunk.mjs.map +1 -0
  114. package/dist/utils/transfer-websocket-json.d.ts +24 -0
  115. package/dist/utils/transfer-websocket-json.d.ts.map +1 -0
  116. package/dist/utils/transfer-websocket-json.js +67 -0
  117. package/dist/utils/transfer-websocket-json.js.map +1 -0
  118. package/dist/utils/transfer-websocket-json.mjs +63 -0
  119. package/dist/utils/transfer-websocket-json.mjs.map +1 -0
  120. package/dist/utils/writable-async-write.d.ts +17 -0
  121. package/dist/utils/writable-async-write.d.ts.map +1 -0
  122. package/dist/utils/writable-async-write.js +61 -0
  123. package/dist/utils/writable-async-write.js.map +1 -0
  124. package/dist/utils/writable-async-write.mjs +59 -0
  125. package/dist/utils/writable-async-write.mjs.map +1 -0
  126. package/package.json +5 -5
@@ -1,17 +1,21 @@
1
1
  import { Readable } from 'stream';
2
- import { randomUUID } from 'crypto';
2
+ import { randomUUID, createHash } from 'crypto';
3
3
  import { handlerControllerFactory, isDataTransferMessage } from './utils.mjs';
4
+ import { createTransferAssetStreamChunk, transferAssetStreamChunkByteLength } from '../../../utils/transfer-asset-chunk.mjs';
4
5
  import 'path';
5
6
  import 'fs-extra';
6
7
  import { ProviderTransferError } from '../../../errors/providers.mjs';
7
8
  import '../../queries/entity.mjs';
8
9
  import 'lodash/fp';
10
+ import 'node:events';
11
+ import 'node:stream/promises';
9
12
  import 'events';
10
13
  import 'lodash';
11
14
  import '@strapi/utils';
12
15
  import '../../providers/local-destination/strategies/restore/configuration.mjs';
13
16
  import { createLocalStrapiSourceProvider } from '../../providers/local-source/index.mjs';
14
17
  import 'ws';
18
+ import { estimateAssetTotals } from '../../providers/local-source/estimate-asset-totals.mjs';
15
19
 
16
20
  const TRANSFER_KIND = 'pull';
17
21
  const VALID_TRANSFER_ACTIONS = [
@@ -30,6 +34,7 @@ const createPullController = handlerControllerFactory((proto)=>({
30
34
  cleanup () {
31
35
  proto.cleanup.call(this);
32
36
  this.streams = {};
37
+ this.checksumsEnabled = false;
33
38
  delete this.provider;
34
39
  },
35
40
  onInfo (message) {
@@ -156,10 +161,10 @@ const createPullController = handlerControllerFactory((proto)=>({
156
161
  });
157
162
  batch = [];
158
163
  };
159
- if (!stream) {
160
- throw new ProviderTransferError(`No available stream found for ${stage}`);
161
- }
162
164
  try {
165
+ if (!stream) {
166
+ throw new ProviderTransferError(`No available stream found for ${stage}`);
167
+ }
163
168
  for await (const chunk of stream){
164
169
  if (stage !== 'assets') {
165
170
  batch.push(chunk);
@@ -206,11 +211,20 @@ const createPullController = handlerControllerFactory((proto)=>({
206
211
  throw new Error('Stream already created, something went wrong');
207
212
  }
208
213
  const flushUUID = randomUUID();
214
+ let totals;
215
+ if (step === 'assets') {
216
+ totals = await estimateAssetTotals(strapi);
217
+ }
209
218
  await this.createReadableStreamForStep(step);
210
- this.flush(step, flushUUID);
219
+ Promise.resolve(this.flush(step, flushUUID)).catch((err)=>{
220
+ this.onError(err instanceof Error ? err : new Error(String(err)));
221
+ });
211
222
  return {
212
223
  ok: true,
213
- id: flushUUID
224
+ id: flushUUID,
225
+ ...totals !== undefined ? {
226
+ totals
227
+ } : {}
214
228
  };
215
229
  }
216
230
  if (action === 'end') {
@@ -234,8 +248,9 @@ const createPullController = handlerControllerFactory((proto)=>({
234
248
  assets: ()=>{
235
249
  const assets = this.provider?.createAssetsReadStream();
236
250
  let batch = [];
251
+ const checksumsEnabled = this.checksumsEnabled === true;
237
252
  const batchLength = ()=>{
238
- return batch.reduce((acc, chunk)=>chunk.action === 'stream' ? acc + chunk.data.byteLength : acc, 0);
253
+ return batch.reduce((acc, chunk)=>acc + transferAssetStreamChunkByteLength(chunk), 0);
239
254
  };
240
255
  const BATCH_MAX_SIZE = 1024 * 1024; // 1MB
241
256
  if (!assets) {
@@ -249,10 +264,12 @@ const createPullController = handlerControllerFactory((proto)=>({
249
264
  */ async function* generator(stream) {
250
265
  let hasStarted = false;
251
266
  let assetID = '';
267
+ let assetChecksum;
252
268
  for await (const chunk of stream){
253
269
  const { stream: assetStream, ...assetData } = chunk;
254
270
  if (!hasStarted) {
255
271
  assetID = randomUUID();
272
+ assetChecksum = checksumsEnabled ? createHash('sha256') : undefined;
256
273
  // Start the transfer of a new asset
257
274
  batch.push({
258
275
  action: 'start',
@@ -262,12 +279,8 @@ const createPullController = handlerControllerFactory((proto)=>({
262
279
  hasStarted = true;
263
280
  }
264
281
  for await (const assetChunk of assetStream){
265
- // Add the asset data to the batch
266
- batch.push({
267
- action: 'stream',
268
- assetID,
269
- data: assetChunk
270
- });
282
+ assetChecksum?.update(assetChunk);
283
+ batch.push(createTransferAssetStreamChunk(assetID, assetChunk));
271
284
  // if the batch size is bigger than BATCH_MAX_SIZE stream the batch
272
285
  if (batchLength() >= BATCH_MAX_SIZE) {
273
286
  yield batch;
@@ -278,7 +291,13 @@ const createPullController = handlerControllerFactory((proto)=>({
278
291
  hasStarted = false;
279
292
  batch.push({
280
293
  action: 'end',
281
- assetID
294
+ assetID,
295
+ ...assetChecksum ? {
296
+ checksum: {
297
+ algorithm: 'sha256',
298
+ value: assetChecksum.digest('hex')
299
+ }
300
+ } : {}
282
301
  });
283
302
  yield batch;
284
303
  batch = [];
@@ -296,20 +315,22 @@ const createPullController = handlerControllerFactory((proto)=>({
296
315
  this.streams[step] = await mapper[step]();
297
316
  },
298
317
  // Commands
299
- async init () {
318
+ async init (params) {
300
319
  if (this.transferID || this.provider) {
301
320
  throw new Error('Transfer already in progress');
302
321
  }
303
322
  await this.verifyAuth();
304
323
  this.transferID = randomUUID();
305
324
  this.startedAt = Date.now();
325
+ this.checksumsEnabled = params?.checksums === true;
306
326
  this.streams = {};
307
327
  this.provider = createLocalStrapiSourceProvider({
308
328
  autoDestroy: false,
309
329
  getStrapi: ()=>strapi
310
330
  });
311
331
  return {
312
- transferID: this.transferID
332
+ transferID: this.transferID,
333
+ checksums: true
313
334
  };
314
335
  },
315
336
  async end (params) {
@@ -1 +1 @@
1
- {"version":3,"file":"pull.mjs","sources":["../../../../src/strapi/remote/handlers/pull.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport { randomUUID } from 'crypto';\nimport type { Core } from '@strapi/types';\n\nimport { Handler } from './abstract';\nimport { handlerControllerFactory, isDataTransferMessage } from './utils';\nimport { createLocalStrapiSourceProvider, ILocalStrapiSourceProvider } from '../../providers';\nimport { ProviderTransferError } from '../../../errors/providers';\nimport type { IAsset, TransferStage, Protocol } from '../../../../types';\nimport { Client } from '../../../../types/remote/protocol';\n\nconst TRANSFER_KIND = 'pull';\nconst VALID_TRANSFER_ACTIONS = ['bootstrap', 'close', 'getMetadata', 'getSchemas'] as const;\n\ntype PullTransferAction = (typeof VALID_TRANSFER_ACTIONS)[number];\n\nexport interface PullHandler extends Handler {\n provider?: ILocalStrapiSourceProvider;\n\n streams?: { [stage in TransferStage]?: Readable };\n\n assertValidTransferAction(action: string): asserts action is PullTransferAction;\n\n onTransferMessage(msg: Protocol.Client.TransferMessage): Promise<unknown> | unknown;\n onTransferAction(msg: Protocol.Client.Action): Promise<unknown> | unknown;\n onTransferStep(msg: Protocol.Client.TransferPullMessage): Promise<unknown> | unknown;\n\n createReadableStreamForStep(step: TransferStage): Promise<void>;\n\n flush(stage: TransferStage, id: string): Promise<void> | void;\n}\n\nexport const createPullController = handlerControllerFactory<Partial<PullHandler>>((proto) => ({\n isTransferStarted(this: PullHandler) {\n return proto.isTransferStarted.call(this) && this.provider !== undefined;\n },\n\n verifyAuth(this: PullHandler) {\n return proto.verifyAuth.call(this, TRANSFER_KIND);\n },\n\n cleanup(this: PullHandler) {\n proto.cleanup.call(this);\n\n this.streams = {};\n\n delete this.provider;\n },\n\n onInfo(message) {\n this.diagnostics?.report({\n details: {\n message,\n origin: 'pull-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: 'pull-handler',\n },\n kind: 'warning',\n });\n },\n\n onError(error) {\n this.diagnostics?.report({\n details: {\n message: error.message,\n error,\n createdAt: new Date(),\n name: error.name,\n severity: 'fatal',\n },\n kind: 'error',\n });\n },\n\n assertValidTransferAction(this: PullHandler, action) {\n // Abstract the constant to string[] to allow looser check on the given action\n const validActions = VALID_TRANSFER_ACTIONS as unknown as string[];\n\n if (validActions.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 async onMessage(this: PullHandler, 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\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: PullHandler, 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.TransferPullMessage);\n }\n },\n\n async onTransferAction(this: PullHandler, msg) {\n const { action } = msg;\n\n this.assertValidTransferAction(action);\n\n if (action === 'bootstrap') {\n return this.provider?.[action](this.diagnostics);\n }\n return this.provider?.[action]();\n },\n\n async flush(this: PullHandler, stage: Client.TransferPullStep, id) {\n type Stage = typeof stage;\n const batchSize = 1024 * 1024;\n let batch = [] as Client.GetTransferPullStreamData<Stage>;\n const stream = this.streams?.[stage];\n\n const batchLength = () => Buffer.byteLength(JSON.stringify(batch));\n\n const maybeConfirm = async (data: any) => {\n try {\n await this.confirm(data);\n } catch (error) {\n // Handle the error, log it, or take other appropriate actions\n\n strapi?.log.error(\n `[Data transfer] Message confirmation failed: ${(error as Error)?.message}`\n );\n this.onError(error as Error);\n }\n };\n\n const sendBatch = async () => {\n await this.confirm({\n type: 'transfer',\n data: batch,\n ended: false,\n error: null,\n id,\n });\n batch = [];\n };\n\n if (!stream) {\n throw new ProviderTransferError(`No available stream found for ${stage}`);\n }\n\n try {\n for await (const chunk of stream) {\n if (stage !== 'assets') {\n batch.push(chunk);\n if (batchLength() >= batchSize) {\n await sendBatch();\n }\n } else {\n await this.confirm({\n type: 'transfer',\n data: [chunk],\n ended: false,\n error: null,\n id,\n });\n }\n }\n\n if (batch.length > 0 && stage !== 'assets') {\n await sendBatch();\n }\n await this.confirm({ type: 'transfer', data: null, ended: true, error: null, id });\n } catch (e) {\n // TODO: if this confirm fails, can we abort the whole transfer?\n await maybeConfirm({ type: 'transfer', data: null, ended: true, error: e, id });\n }\n },\n\n async onTransferStep(this: PullHandler, msg) {\n const { step, action } = msg;\n\n if (action === 'start') {\n if (this.streams?.[step] instanceof Readable) {\n throw new Error('Stream already created, something went wrong');\n }\n\n const flushUUID = randomUUID();\n\n await this.createReadableStreamForStep(step);\n this.flush(step, flushUUID);\n\n return { ok: true, id: flushUUID };\n }\n\n if (action === 'end') {\n const stream = this.streams?.[step];\n\n if (stream?.readableEnded === false) {\n await new Promise((resolve) => {\n stream?.on('close', resolve).destroy();\n });\n }\n\n delete this.streams?.[step];\n\n return { ok: true };\n }\n },\n\n async createReadableStreamForStep(this: PullHandler, step: Exclude<TransferStage, 'schemas'>) {\n const mapper = {\n entities: () => this.provider?.createEntitiesReadStream(),\n links: () => this.provider?.createLinksReadStream(),\n configuration: () => this.provider?.createConfigurationReadStream(),\n assets: () => {\n const assets = this.provider?.createAssetsReadStream();\n let batch: Protocol.Client.TransferAssetFlow[] = [];\n\n const batchLength = () => {\n return batch.reduce(\n (acc, chunk) => (chunk.action === 'stream' ? acc + chunk.data.byteLength : acc),\n 0\n );\n };\n\n const BATCH_MAX_SIZE = 1024 * 1024; // 1MB\n\n if (!assets) {\n throw new Error('Assets read stream could not be created');\n }\n /**\n * Generates batches of 1MB of data from the assets stream to avoid\n * sending too many small chunks\n *\n * @param stream Assets stream from the local source provider\n */\n async function* generator(stream: Readable) {\n let hasStarted = false;\n let assetID = '';\n\n for await (const chunk of stream) {\n const { stream: assetStream, ...assetData } = chunk as IAsset;\n if (!hasStarted) {\n assetID = randomUUID();\n // Start the transfer of a new asset\n batch.push({ action: 'start', assetID, data: assetData });\n hasStarted = true;\n }\n\n for await (const assetChunk of assetStream) {\n // Add the asset data to the batch\n batch.push({ action: 'stream', assetID, data: assetChunk });\n\n // if the batch size is bigger than BATCH_MAX_SIZE stream the batch\n if (batchLength() >= BATCH_MAX_SIZE) {\n yield batch;\n batch = [];\n }\n }\n\n // All the asset data has been streamed and gets ready for the next one\n hasStarted = false;\n batch.push({ action: 'end', assetID });\n yield batch;\n batch = [];\n }\n }\n\n return Readable.from(generator(assets));\n },\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 // Commands\n async init(this: PullHandler) {\n if (this.transferID || this.provider) {\n throw new Error('Transfer already in progress');\n }\n await this.verifyAuth();\n\n this.transferID = randomUUID();\n this.startedAt = Date.now();\n\n this.streams = {};\n\n this.provider = createLocalStrapiSourceProvider({\n autoDestroy: false,\n getStrapi: () => strapi as Core.Strapi,\n });\n\n return { transferID: this.transferID };\n },\n\n async end(\n this: PullHandler,\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 async status(this: PullHandler) {\n const isStarted = this.isTransferStarted();\n\n if (!isStarted) {\n const startedAt = this.startedAt as number;\n return {\n active: true,\n kind: TRANSFER_KIND,\n startedAt,\n elapsed: Date.now() - startedAt,\n };\n }\n return { active: false, kind: null, elapsed: null, startedAt: null };\n },\n}));\n"],"names":["TRANSFER_KIND","VALID_TRANSFER_ACTIONS","createPullController","handlerControllerFactory","proto","isTransferStarted","call","provider","undefined","verifyAuth","cleanup","streams","onInfo","message","diagnostics","report","details","origin","createdAt","Date","kind","onWarning","onError","error","name","severity","assertValidTransferAction","action","validActions","includes","ProviderTransferError","Object","keys","onMessage","raw","msg","JSON","parse","toString","isDataTransferMessage","uuid","respond","Error","hasUUID","previousResponse","response","e","data","type","addUUID","command","executeAndRespond","assertValidTransferCommand","status","params","assertValidTransfer","onTransferMessage","onTransferAction","onTransferStep","flush","stage","id","batchSize","batch","stream","batchLength","Buffer","byteLength","stringify","maybeConfirm","confirm","strapi","log","sendBatch","ended","chunk","push","length","step","Readable","flushUUID","randomUUID","createReadableStreamForStep","ok","readableEnded","Promise","resolve","on","destroy","mapper","entities","createEntitiesReadStream","links","createLinksReadStream","configuration","createConfigurationReadStream","assets","createAssetsReadStream","reduce","acc","BATCH_MAX_SIZE","generator","hasStarted","assetID","assetStream","assetData","assetChunk","from","init","transferID","startedAt","now","createLocalStrapiSourceProvider","autoDestroy","getStrapi","end","isStarted","active","elapsed"],"mappings":"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"}
1
+ {"version":3,"file":"pull.mjs","sources":["../../../../src/strapi/remote/handlers/pull.ts"],"sourcesContent":["import { Readable } from 'stream';\nimport { randomUUID, createHash } from 'crypto';\nimport type { Core } from '@strapi/types';\n\nimport { Handler } from './abstract';\nimport { handlerControllerFactory, isDataTransferMessage } from './utils';\nimport {\n createTransferAssetStreamChunk,\n transferAssetStreamChunkByteLength,\n} from '../../../utils/transfer-asset-chunk';\nimport {\n createLocalStrapiSourceProvider,\n estimateAssetTotals,\n ILocalStrapiSourceProvider,\n} from '../../providers';\nimport { ProviderTransferError } from '../../../errors/providers';\nimport type { IAsset, StageTotalsEstimate, TransferStage, Protocol } from '../../../../types';\nimport { Client } from '../../../../types/remote/protocol';\n\nconst TRANSFER_KIND = 'pull';\nconst VALID_TRANSFER_ACTIONS = ['bootstrap', 'close', 'getMetadata', 'getSchemas'] as const;\n\ntype PullTransferAction = (typeof VALID_TRANSFER_ACTIONS)[number];\n\nexport interface PullHandler extends Handler {\n provider?: ILocalStrapiSourceProvider;\n\n streams?: { [stage in TransferStage]?: Readable };\n checksumsEnabled?: boolean;\n\n assertValidTransferAction(action: string): asserts action is PullTransferAction;\n\n onTransferMessage(msg: Protocol.Client.TransferMessage): Promise<unknown> | unknown;\n onTransferAction(msg: Protocol.Client.Action): Promise<unknown> | unknown;\n onTransferStep(msg: Protocol.Client.TransferPullMessage): Promise<unknown> | unknown;\n\n createReadableStreamForStep(step: TransferStage): Promise<void>;\n\n flush(stage: TransferStage, id: string): Promise<void> | void;\n}\n\nexport const createPullController = handlerControllerFactory<Partial<PullHandler>>((proto) => ({\n isTransferStarted(this: PullHandler) {\n return proto.isTransferStarted.call(this) && this.provider !== undefined;\n },\n\n verifyAuth(this: PullHandler) {\n return proto.verifyAuth.call(this, TRANSFER_KIND);\n },\n\n cleanup(this: PullHandler) {\n proto.cleanup.call(this);\n\n this.streams = {};\n this.checksumsEnabled = false;\n\n delete this.provider;\n },\n\n onInfo(message) {\n this.diagnostics?.report({\n details: {\n message,\n origin: 'pull-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: 'pull-handler',\n },\n kind: 'warning',\n });\n },\n\n onError(error) {\n this.diagnostics?.report({\n details: {\n message: error.message,\n error,\n createdAt: new Date(),\n name: error.name,\n severity: 'fatal',\n },\n kind: 'error',\n });\n },\n\n assertValidTransferAction(this: PullHandler, action) {\n // Abstract the constant to string[] to allow looser check on the given action\n const validActions = VALID_TRANSFER_ACTIONS as unknown as string[];\n\n if (validActions.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 async onMessage(this: PullHandler, 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\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: PullHandler, 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.TransferPullMessage);\n }\n },\n\n async onTransferAction(this: PullHandler, msg) {\n const { action } = msg;\n\n this.assertValidTransferAction(action);\n\n if (action === 'bootstrap') {\n return this.provider?.[action](this.diagnostics);\n }\n return this.provider?.[action]();\n },\n\n async flush(this: PullHandler, stage: Client.TransferPullStep, id) {\n type Stage = typeof stage;\n const batchSize = 1024 * 1024;\n let batch = [] as Client.GetTransferPullStreamData<Stage>;\n const stream = this.streams?.[stage];\n\n const batchLength = () => Buffer.byteLength(JSON.stringify(batch));\n\n const maybeConfirm = async (data: any) => {\n try {\n await this.confirm(data);\n } catch (error) {\n // Handle the error, log it, or take other appropriate actions\n\n strapi?.log.error(\n `[Data transfer] Message confirmation failed: ${(error as Error)?.message}`\n );\n this.onError(error as Error);\n }\n };\n\n const sendBatch = async () => {\n await this.confirm({\n type: 'transfer',\n data: batch,\n ended: false,\n error: null,\n id,\n });\n batch = [];\n };\n\n try {\n if (!stream) {\n throw new ProviderTransferError(`No available stream found for ${stage}`);\n }\n\n for await (const chunk of stream) {\n if (stage !== 'assets') {\n batch.push(chunk);\n if (batchLength() >= batchSize) {\n await sendBatch();\n }\n } else {\n await this.confirm({\n type: 'transfer',\n data: [chunk],\n ended: false,\n error: null,\n id,\n });\n }\n }\n\n if (batch.length > 0 && stage !== 'assets') {\n await sendBatch();\n }\n await this.confirm({ type: 'transfer', data: null, ended: true, error: null, id });\n } catch (e) {\n // TODO: if this confirm fails, can we abort the whole transfer?\n await maybeConfirm({ type: 'transfer', data: null, ended: true, error: e, id });\n }\n },\n\n async onTransferStep(this: PullHandler, msg) {\n const { step, action } = msg;\n\n if (action === 'start') {\n if (this.streams?.[step] instanceof Readable) {\n throw new Error('Stream already created, something went wrong');\n }\n\n const flushUUID = randomUUID();\n\n let totals: StageTotalsEstimate | undefined;\n if (step === 'assets') {\n totals = await estimateAssetTotals(strapi as Core.Strapi);\n }\n await this.createReadableStreamForStep(step);\n Promise.resolve(this.flush(step, flushUUID)).catch((err: unknown) => {\n this.onError(err instanceof Error ? err : new Error(String(err)));\n });\n\n return {\n ok: true,\n id: flushUUID,\n ...(totals !== undefined ? { totals } : {}),\n };\n }\n\n if (action === 'end') {\n const stream = this.streams?.[step];\n\n if (stream?.readableEnded === false) {\n await new Promise((resolve) => {\n stream?.on('close', resolve).destroy();\n });\n }\n\n delete this.streams?.[step];\n\n return { ok: true };\n }\n },\n\n async createReadableStreamForStep(this: PullHandler, step: Exclude<TransferStage, 'schemas'>) {\n const mapper = {\n entities: () => this.provider?.createEntitiesReadStream(),\n links: () => this.provider?.createLinksReadStream(),\n configuration: () => this.provider?.createConfigurationReadStream(),\n assets: () => {\n const assets = this.provider?.createAssetsReadStream();\n let batch: Protocol.Client.TransferAssetFlow[] = [];\n const checksumsEnabled = this.checksumsEnabled === true;\n\n const batchLength = () => {\n return batch.reduce((acc, chunk) => acc + transferAssetStreamChunkByteLength(chunk), 0);\n };\n\n const BATCH_MAX_SIZE = 1024 * 1024; // 1MB\n\n if (!assets) {\n throw new Error('Assets read stream could not be created');\n }\n /**\n * Generates batches of 1MB of data from the assets stream to avoid\n * sending too many small chunks\n *\n * @param stream Assets stream from the local source provider\n */\n async function* generator(stream: Readable) {\n let hasStarted = false;\n let assetID = '';\n let assetChecksum: ReturnType<typeof createHash> | undefined;\n\n for await (const chunk of stream) {\n const { stream: assetStream, ...assetData } = chunk as IAsset;\n if (!hasStarted) {\n assetID = randomUUID();\n assetChecksum = checksumsEnabled ? createHash('sha256') : undefined;\n // Start the transfer of a new asset\n batch.push({ action: 'start', assetID, data: assetData });\n hasStarted = true;\n }\n\n for await (const assetChunk of assetStream) {\n assetChecksum?.update(assetChunk);\n batch.push(createTransferAssetStreamChunk(assetID, assetChunk));\n\n // if the batch size is bigger than BATCH_MAX_SIZE stream the batch\n if (batchLength() >= BATCH_MAX_SIZE) {\n yield batch;\n batch = [];\n }\n }\n\n // All the asset data has been streamed and gets ready for the next one\n hasStarted = false;\n batch.push({\n action: 'end',\n assetID,\n ...(assetChecksum\n ? { checksum: { algorithm: 'sha256' as const, value: assetChecksum.digest('hex') } }\n : {}),\n });\n yield batch;\n batch = [];\n }\n }\n\n return Readable.from(generator(assets));\n },\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 // Commands\n async init(this: PullHandler, params?: Protocol.Client.GetCommandParams<'init'>) {\n if (this.transferID || this.provider) {\n throw new Error('Transfer already in progress');\n }\n await this.verifyAuth();\n\n this.transferID = randomUUID();\n this.startedAt = Date.now();\n this.checksumsEnabled = params?.checksums === true;\n\n this.streams = {};\n\n this.provider = createLocalStrapiSourceProvider({\n autoDestroy: false,\n getStrapi: () => strapi as Core.Strapi,\n });\n\n return { transferID: this.transferID, checksums: true };\n },\n\n async end(\n this: PullHandler,\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 async status(this: PullHandler) {\n const isStarted = this.isTransferStarted();\n\n if (!isStarted) {\n const startedAt = this.startedAt as number;\n return {\n active: true,\n kind: TRANSFER_KIND,\n startedAt,\n elapsed: Date.now() - startedAt,\n };\n }\n return { active: false, kind: null, elapsed: null, startedAt: null };\n },\n}));\n"],"names":["TRANSFER_KIND","VALID_TRANSFER_ACTIONS","createPullController","handlerControllerFactory","proto","isTransferStarted","call","provider","undefined","verifyAuth","cleanup","streams","checksumsEnabled","onInfo","message","diagnostics","report","details","origin","createdAt","Date","kind","onWarning","onError","error","name","severity","assertValidTransferAction","action","validActions","includes","ProviderTransferError","Object","keys","onMessage","raw","msg","JSON","parse","toString","isDataTransferMessage","uuid","respond","Error","hasUUID","previousResponse","response","e","data","type","addUUID","command","executeAndRespond","assertValidTransferCommand","status","params","assertValidTransfer","onTransferMessage","onTransferAction","onTransferStep","flush","stage","id","batchSize","batch","stream","batchLength","Buffer","byteLength","stringify","maybeConfirm","confirm","strapi","log","sendBatch","ended","chunk","push","length","step","Readable","flushUUID","randomUUID","totals","estimateAssetTotals","createReadableStreamForStep","Promise","resolve","catch","err","String","ok","readableEnded","on","destroy","mapper","entities","createEntitiesReadStream","links","createLinksReadStream","configuration","createConfigurationReadStream","assets","createAssetsReadStream","reduce","acc","transferAssetStreamChunkByteLength","BATCH_MAX_SIZE","generator","hasStarted","assetID","assetChecksum","assetStream","assetData","createHash","assetChunk","update","createTransferAssetStreamChunk","checksum","algorithm","value","digest","from","init","transferID","startedAt","now","checksums","createLocalStrapiSourceProvider","autoDestroy","getStrapi","end","isStarted","active","elapsed"],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  /// <reference types="koa" />
4
+ import { type Hash } from 'crypto';
3
5
  import { Writable, PassThrough } from 'stream';
4
6
  import type { TransferFlow } from '../flows';
5
7
  import type { TransferStage, IAsset, Protocol } from '../../../../types';
@@ -25,14 +27,23 @@ export interface PushHandler extends Handler {
25
27
  * Holds all the transferred assets for the current transfer handler (one registry per connection)
26
28
  */
27
29
  assets: {
28
- [filepath: string]: IAsset & {
30
+ [assetID: string]: IAsset & {
29
31
  stream: PassThrough;
30
32
  };
31
33
  };
34
+ /** Incremental checksum state keyed by transfer asset ID (only populated when checksums are enabled). */
35
+ assetChecksums?: {
36
+ [assetID: string]: Hash;
37
+ };
38
+ checksumsEnabled?: boolean;
32
39
  /**
33
- * Ochestrate and manage the transfer messages' ordering
40
+ * Orchestrate and manage the transfer messages' ordering
34
41
  */
35
42
  flow?: TransferFlow;
43
+ /**
44
+ * Interval for periodic destination memory logging during assets stage
45
+ */
46
+ memoryLogInterval?: ReturnType<typeof setInterval>;
36
47
  /**
37
48
  * Checks that the given action is a valid push transfer action
38
49
  */
@@ -1 +1 @@
1
- {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../../src/strapi/remote/handlers/push.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,KAAK,EAAE,YAAY,EAAQ,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGzE,OAAO,EAAE,oCAAoC,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,QAAA,MAAM,sBAAsB,4FAOlB,CAAC;AAEX,KAAK,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIlE,MAAM,WAAW,WAAY,SAAQ,OAAO;IAC1C;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,oCAAoC,CAAC,CAAC;IAEnE;;OAEG;IACH,OAAO,CAAC,EAAE;SAAG,KAAK,IAAI,aAAa,CAAC,CAAC,EAAE,QAAQ;KAAE,CAAC;IAElD,KAAK,EAAE;SACJ,KAAK,IAAI,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK;KACpE,CAAC;IAEF;;OAEG;IACH,MAAM,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG;YAAE,MAAM,EAAE,WAAW,CAAA;SAAE,CAAA;KAAE,CAAC;IAEjE;;OAEG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IAEpB;;OAEG;IACH,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAAC;IAEhF;;OAEG;IACH,2BAA2B,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAEpF;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAE1E;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAErF;;OAEG;IACH,WAAW,CACT,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,yBAAyB,CAAC,QAAQ,CAAC,GAC3D,OAAO,CAAC,IAAI,CAAC,CAAC;IAIjB;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAE7C;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAE/C;;OAEG;IACH,6BAA6B,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;CAC3D;AAcD,eAAO,MAAM,oBAAoB,8FA8Z9B,CAAC"}
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;AAG/C,OAAO,KAAK,EAAE,YAAY,EAAQ,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAKzE,OAAO,EAAE,oCAAoC,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,QAAA,MAAM,sBAAsB,4FAOlB,CAAC;AAEX,KAAK,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIlE,MAAM,WAAW,WAAY,SAAQ,OAAO;IAC1C;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,oCAAoC,CAAC,CAAC;IAEnE;;OAEG;IACH,OAAO,CAAC,EAAE;SAAG,KAAK,IAAI,aAAa,CAAC,CAAC,EAAE,QAAQ;KAAE,CAAC;IAElD,KAAK,EAAE;SACJ,KAAK,IAAI,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK;KACpE,CAAC;IAEF;;OAEG;IACH,MAAM,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG;YAAE,MAAM,EAAE,WAAW,CAAA;SAAE,CAAA;KAAE,CAAC;IAChE,yGAAyG;IACzG,cAAc,CAAC,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC7C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IAEpB;;OAEG;IACH,iBAAiB,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IAEnD;;OAEG;IACH,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAAC;IAEhF;;OAEG;IACH,2BAA2B,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAEpF;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAE1E;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAErF;;OAEG;IACH,WAAW,CACT,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,yBAAyB,CAAC,QAAQ,CAAC,GAC3D,OAAO,CAAC,IAAI,CAAC,CAAC;IAIjB;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAE7C;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAE/C;;OAEG;IACH,6BAA6B,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;CAC3D;AAED,eAAO,MAAM,oBAAoB,8FAke9B,CAAC"}
@@ -3,6 +3,8 @@
3
3
  var crypto = require('crypto');
4
4
  var stream = require('stream');
5
5
  var providers = require('../../../errors/providers.js');
6
+ var writableAsyncWrite = require('../../../utils/writable-async-write.js');
7
+ var transferAssetChunk = require('../../../utils/transfer-asset-chunk.js');
6
8
  var index$1 = require('../../providers/local-destination/index.js');
7
9
  require('stream-chain');
8
10
  require('../../queries/entity.js');
@@ -24,16 +26,6 @@ const VALID_TRANSFER_ACTIONS = [
24
26
  'getSchemas'
25
27
  ];
26
28
  const TRANSFER_KIND = 'push';
27
- const writeAsync = (stream, data)=>{
28
- return new Promise((resolve, reject)=>{
29
- stream.write(data, (error)=>{
30
- if (error) {
31
- reject(error);
32
- }
33
- resolve();
34
- });
35
- });
36
- };
37
29
  const createPushController = utils.handlerControllerFactory((proto)=>({
38
30
  isTransferStarted () {
39
31
  return proto.isTransferStarted.call(this) && this.provider !== undefined;
@@ -62,13 +54,23 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
62
54
  });
63
55
  },
64
56
  cleanup () {
57
+ if (this.memoryLogInterval) {
58
+ clearInterval(this.memoryLogInterval);
59
+ delete this.memoryLogInterval;
60
+ }
65
61
  proto.cleanup.call(this);
66
62
  this.streams = {};
67
63
  this.assets = {};
64
+ this.assetChecksums = {};
65
+ this.checksumsEnabled = false;
68
66
  delete this.flow;
69
67
  delete this.provider;
70
68
  },
71
69
  teardown () {
70
+ if (this.memoryLogInterval) {
71
+ clearInterval(this.memoryLogInterval);
72
+ delete this.memoryLogInterval;
73
+ }
72
74
  if (this.provider) {
73
75
  this.provider.rollback();
74
76
  }
@@ -220,6 +222,16 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
220
222
  started: 0,
221
223
  finished: 0
222
224
  };
225
+ if (stage === 'assets') {
226
+ strapi.log.debug('[Transfer destination] Assets stage started; sampling memory usage every 5s until stage end');
227
+ this.memoryLogInterval = setInterval(()=>{
228
+ const mem = process.memoryUsage();
229
+ const stats = this.stats?.assets;
230
+ const rssMb = (mem.rss / 1024 / 1024).toFixed(1);
231
+ const heapMb = (mem.heapUsed / 1024 / 1024).toFixed(1);
232
+ strapi.log.debug(`[Transfer destination] memory RSS=${rssMb}MB heapUsed=${heapMb}MB | assets started=${stats?.started ?? 0} finished=${stats?.finished ?? 0}`);
233
+ }, 5000);
234
+ }
223
235
  return {
224
236
  ok: true
225
237
  };
@@ -235,14 +247,19 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
235
247
  if (stage === 'assets') {
236
248
  return this.streamAsset(msg.data);
237
249
  }
238
- // For all other steps
239
- await Promise.all(msg.data.map(async (item)=>{
250
+ // One objectMode Writable: do not overlap writes.
251
+ for (const item of msg.data){
240
252
  this.stats[stage].started += 1;
241
- await writeAsync(stream, item);
253
+ await writableAsyncWrite.write(stream, item);
242
254
  this.stats[stage].finished += 1;
243
- }));
255
+ }
244
256
  }
245
257
  if (msg.action === 'end') {
258
+ if (stage === 'assets' && this.memoryLogInterval) {
259
+ clearInterval(this.memoryLogInterval);
260
+ delete this.memoryLogInterval;
261
+ strapi.log.debug('[Transfer destination] Assets stage ended, stopped memory log');
262
+ }
246
263
  this.unlockTransferStep(stage);
247
264
  const stream = this.streams?.[stage];
248
265
  if (stream && !stream.closed) {
@@ -296,24 +313,50 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
296
313
  ...item.data,
297
314
  stream: new stream.PassThrough()
298
315
  };
299
- writeAsync(assetsStream, this.assets[assetID]);
300
- }
301
- if (action === 'stream') {
302
- // The buffer has gone through JSON operations and is now of shape { type: "Buffer"; data: UInt8Array }
303
- // We need to transform it back into a Buffer instance
304
- const rawBuffer = item.data;
305
- const chunk = Buffer.from(rawBuffer.data);
306
- await writeAsync(this.assets[assetID].stream, chunk);
307
- }
308
- if (action === 'end') {
309
- await new Promise((resolve, reject)=>{
310
- const { stream: assetStream } = this.assets[assetID];
311
- assetStream.on('close', ()=>{
312
- this.stats.assets.finished += 1;
313
- delete this.assets[assetID];
314
- resolve();
315
- }).on('error', reject).end();
316
- });
316
+ if (this.checksumsEnabled) {
317
+ this.assetChecksums ?? (this.assetChecksums = {});
318
+ this.assetChecksums[assetID] = crypto.createHash('sha256');
319
+ }
320
+ const filename = item.data?.filename ?? assetID;
321
+ strapi.log.debug(`[Transfer destination] Asset start #${this.stats.assets.started} id=${assetID} filename=${filename}`);
322
+ // Wait for the assets stage to accept this row (same pattern as remote-source).
323
+ await writableAsyncWrite.write(assetsStream, this.assets[assetID]);
324
+ } else if (action === 'stream' || action === 'end') {
325
+ if (!this.assets[assetID]) {
326
+ throw new providers.ProviderTransferError(`No asset "${assetID}" for ${action} action; send start before stream/end`);
327
+ }
328
+ if (action === 'stream') {
329
+ const chunk = transferAssetChunk.decodeTransferAssetStreamItem(item);
330
+ this.assetChecksums?.[assetID]?.update(chunk);
331
+ await writableAsyncWrite.write(this.assets[assetID].stream, chunk);
332
+ } else {
333
+ if (this.checksumsEnabled) {
334
+ if (!item.checksum) {
335
+ throw new providers.ProviderTransferError(`Missing checksum for asset "${assetID}"`);
336
+ }
337
+ if (item.checksum.algorithm !== 'sha256') {
338
+ throw new providers.ProviderTransferError(`Unsupported checksum algorithm "${item.checksum.algorithm}" for asset ${assetID}`);
339
+ }
340
+ const checksum = this.assetChecksums?.[assetID]?.digest('hex');
341
+ if (!checksum || checksum !== item.checksum.value) {
342
+ throw new providers.ProviderTransferError(`Checksum mismatch for asset "${assetID}" (expected ${item.checksum.value}, got ${checksum ?? 'none'})`);
343
+ }
344
+ }
345
+ if (this.assetChecksums?.[assetID]) {
346
+ delete this.assetChecksums[assetID];
347
+ }
348
+ strapi.log.debug(`[Transfer destination] Asset end id=${assetID} (finished=${this.stats.assets.finished + 1}/${this.stats.assets.started})`);
349
+ await new Promise((resolve, reject)=>{
350
+ const { stream: assetStream } = this.assets[assetID];
351
+ assetStream.on('close', ()=>{
352
+ this.stats.assets.finished += 1;
353
+ delete this.assets[assetID];
354
+ resolve();
355
+ }).on('error', reject).end();
356
+ });
357
+ }
358
+ } else {
359
+ throw new providers.ProviderTransferError(`Invalid asset flow action: ${String(item.action)}`);
317
360
  }
318
361
  }
319
362
  },
@@ -333,6 +376,8 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
333
376
  this.transferID = crypto.randomUUID();
334
377
  this.startedAt = Date.now();
335
378
  this.assets = {};
379
+ this.assetChecksums = {};
380
+ this.checksumsEnabled = params?.checksums === true;
336
381
  this.streams = {};
337
382
  this.stats = {
338
383
  assets: {
@@ -354,7 +399,8 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
354
399
  };
355
400
  this.flow = index.createFlow(_default);
356
401
  this.provider = index$1.createLocalStrapiDestinationProvider({
357
- ...params.options,
402
+ strategy: params?.options?.strategy ?? 'restore',
403
+ restore: params?.options?.restore ?? {},
358
404
  autoDestroy: false,
359
405
  getStrapi: ()=>strapi
360
406
  });
@@ -363,7 +409,8 @@ const createPushController = utils.handlerControllerFactory((proto)=>({
363
409
  strapi.log.warn(message);
364
410
  };
365
411
  return {
366
- transferID: this.transferID
412
+ transferID: this.transferID,
413
+ checksums: true
367
414
  };
368
415
  },
369
416
  async status () {