@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.
- package/dist/directory/providers/source/index.d.ts.map +1 -1
- package/dist/directory/providers/source/index.js +3 -2
- package/dist/directory/providers/source/index.js.map +1 -1
- package/dist/directory/providers/source/index.mjs +3 -2
- package/dist/directory/providers/source/index.mjs.map +1 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +130 -5
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/index.mjs +130 -5
- package/dist/engine/index.mjs.map +1 -1
- package/dist/engine/validation/schemas/index.js +2 -0
- package/dist/engine/validation/schemas/index.js.map +1 -1
- package/dist/engine/validation/schemas/index.mjs +2 -0
- package/dist/engine/validation/schemas/index.mjs.map +1 -1
- package/dist/file/providers/source/index.d.ts.map +1 -1
- package/dist/file/providers/source/index.js +84 -45
- package/dist/file/providers/source/index.js.map +1 -1
- package/dist/file/providers/source/index.mjs +85 -46
- package/dist/file/providers/source/index.mjs.map +1 -1
- package/dist/strapi/providers/index.js +2 -0
- package/dist/strapi/providers/index.js.map +1 -1
- package/dist/strapi/providers/index.mjs +1 -0
- package/dist/strapi/providers/index.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/assets-destination-writable.d.ts +22 -0
- package/dist/strapi/providers/local-destination/assets-destination-writable.d.ts.map +1 -0
- package/dist/strapi/providers/local-destination/assets-destination-writable.js +107 -0
- package/dist/strapi/providers/local-destination/assets-destination-writable.js.map +1 -0
- package/dist/strapi/providers/local-destination/assets-destination-writable.mjs +105 -0
- package/dist/strapi/providers/local-destination/assets-destination-writable.mjs.map +1 -0
- package/dist/strapi/providers/local-destination/index.d.ts +2 -0
- package/dist/strapi/providers/local-destination/index.d.ts.map +1 -1
- package/dist/strapi/providers/local-destination/index.js +18 -79
- package/dist/strapi/providers/local-destination/index.js.map +1 -1
- package/dist/strapi/providers/local-destination/index.mjs +18 -79
- package/dist/strapi/providers/local-destination/index.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/entities.js +2 -0
- package/dist/strapi/providers/local-destination/strategies/restore/entities.js.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs +2 -0
- package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.js +2 -0
- package/dist/strapi/providers/local-destination/strategies/restore/index.js.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.mjs +2 -0
- package/dist/strapi/providers/local-destination/strategies/restore/index.mjs.map +1 -1
- package/dist/strapi/providers/local-source/assets.d.ts +8 -1
- package/dist/strapi/providers/local-source/assets.d.ts.map +1 -1
- package/dist/strapi/providers/local-source/assets.js +47 -19
- package/dist/strapi/providers/local-source/assets.js.map +1 -1
- package/dist/strapi/providers/local-source/assets.mjs +46 -20
- package/dist/strapi/providers/local-source/assets.mjs.map +1 -1
- package/dist/strapi/providers/local-source/estimate-asset-totals.d.ts +11 -0
- package/dist/strapi/providers/local-source/estimate-asset-totals.d.ts.map +1 -0
- package/dist/strapi/providers/local-source/estimate-asset-totals.js +130 -0
- package/dist/strapi/providers/local-source/estimate-asset-totals.js.map +1 -0
- package/dist/strapi/providers/local-source/estimate-asset-totals.mjs +128 -0
- package/dist/strapi/providers/local-source/estimate-asset-totals.mjs.map +1 -0
- package/dist/strapi/providers/local-source/index.d.ts +3 -2
- package/dist/strapi/providers/local-source/index.d.ts.map +1 -1
- package/dist/strapi/providers/local-source/index.js +30 -3
- package/dist/strapi/providers/local-source/index.js.map +1 -1
- package/dist/strapi/providers/local-source/index.mjs +30 -4
- package/dist/strapi/providers/local-source/index.mjs.map +1 -1
- package/dist/strapi/providers/remote-destination/index.d.ts +3 -1
- package/dist/strapi/providers/remote-destination/index.d.ts.map +1 -1
- package/dist/strapi/providers/remote-destination/index.js +88 -19
- package/dist/strapi/providers/remote-destination/index.js.map +1 -1
- package/dist/strapi/providers/remote-destination/index.mjs +89 -20
- package/dist/strapi/providers/remote-destination/index.mjs.map +1 -1
- package/dist/strapi/providers/remote-source/index.d.ts +6 -3
- package/dist/strapi/providers/remote-source/index.d.ts.map +1 -1
- package/dist/strapi/providers/remote-source/index.js +180 -47
- package/dist/strapi/providers/remote-source/index.js.map +1 -1
- package/dist/strapi/providers/remote-source/index.mjs +181 -48
- package/dist/strapi/providers/remote-source/index.mjs.map +1 -1
- package/dist/strapi/providers/utils.d.ts +9 -6
- package/dist/strapi/providers/utils.d.ts.map +1 -1
- package/dist/strapi/providers/utils.js +9 -4
- package/dist/strapi/providers/utils.js.map +1 -1
- package/dist/strapi/providers/utils.mjs +9 -4
- package/dist/strapi/providers/utils.mjs.map +1 -1
- package/dist/strapi/remote/handlers/pull.d.ts +1 -0
- package/dist/strapi/remote/handlers/pull.d.ts.map +1 -1
- package/dist/strapi/remote/handlers/pull.js +36 -15
- package/dist/strapi/remote/handlers/pull.js.map +1 -1
- package/dist/strapi/remote/handlers/pull.mjs +37 -16
- package/dist/strapi/remote/handlers/pull.mjs.map +1 -1
- package/dist/strapi/remote/handlers/push.d.ts +13 -2
- package/dist/strapi/remote/handlers/push.d.ts.map +1 -1
- package/dist/strapi/remote/handlers/push.js +81 -34
- package/dist/strapi/remote/handlers/push.js.map +1 -1
- package/dist/strapi/remote/handlers/push.mjs +82 -35
- package/dist/strapi/remote/handlers/push.mjs.map +1 -1
- package/dist/strapi/remote/handlers/utils.d.ts.map +1 -1
- package/dist/strapi/remote/handlers/utils.js +5 -3
- package/dist/strapi/remote/handlers/utils.js.map +1 -1
- package/dist/strapi/remote/handlers/utils.mjs +5 -3
- package/dist/strapi/remote/handlers/utils.mjs.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +2 -0
- package/dist/utils/index.mjs.map +1 -1
- package/dist/utils/stream.d.ts.map +1 -1
- package/dist/utils/stream.js +40 -3
- package/dist/utils/stream.js.map +1 -1
- package/dist/utils/stream.mjs +40 -3
- package/dist/utils/stream.mjs.map +1 -1
- package/dist/utils/transfer-asset-chunk.d.ts +41 -0
- package/dist/utils/transfer-asset-chunk.d.ts.map +1 -0
- package/dist/utils/transfer-asset-chunk.js +93 -0
- package/dist/utils/transfer-asset-chunk.js.map +1 -0
- package/dist/utils/transfer-asset-chunk.mjs +88 -0
- package/dist/utils/transfer-asset-chunk.mjs.map +1 -0
- package/dist/utils/transfer-websocket-json.d.ts +24 -0
- package/dist/utils/transfer-websocket-json.d.ts.map +1 -0
- package/dist/utils/transfer-websocket-json.js +67 -0
- package/dist/utils/transfer-websocket-json.js.map +1 -0
- package/dist/utils/transfer-websocket-json.mjs +63 -0
- package/dist/utils/transfer-websocket-json.mjs.map +1 -0
- package/dist/utils/writable-async-write.d.ts +17 -0
- package/dist/utils/writable-async-write.d.ts.map +1 -0
- package/dist/utils/writable-async-write.js +61 -0
- package/dist/utils/writable-async-write.js.map +1 -0
- package/dist/utils/writable-async-write.mjs +59 -0
- package/dist/utils/writable-async-write.mjs.map +1 -0
- 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)=>
|
|
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
|
-
|
|
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
|
-
[
|
|
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
|
-
*
|
|
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":"
|
|
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
|
-
//
|
|
239
|
-
|
|
250
|
+
// One objectMode Writable: do not overlap writes.
|
|
251
|
+
for (const item of msg.data){
|
|
240
252
|
this.stats[stage].started += 1;
|
|
241
|
-
await
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
await
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
|
|
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 () {
|