@strapi/data-transfer 5.10.4 → 5.11.1
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/engine/index.d.ts.map +1 -1
- package/dist/index.js +153 -105
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +157 -109
- package/dist/index.mjs.map +1 -1
- package/dist/strapi/providers/remote-source/index.d.ts +2 -0
- package/dist/strapi/providers/remote-source/index.d.ts.map +1 -1
- package/dist/strapi/queries/link.d.ts.map +1 -1
- package/dist/strapi/remote/handlers/pull.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Transform, PassThrough, Writable, Readable, Duplex, pipeline } from 'stream';
|
|
1
|
+
import { Transform, PassThrough, Writable, Readable, Duplex, pipeline as pipeline$1 } from 'stream';
|
|
2
|
+
import { pipeline } from 'stream/promises';
|
|
2
3
|
import path, { extname, join, posix } from 'path';
|
|
3
4
|
import { EOL } from 'os';
|
|
4
5
|
import { chain } from 'stream-chain';
|
|
@@ -633,8 +634,7 @@ const TRANSFER_STAGES = Object.freeze([
|
|
|
633
634
|
};
|
|
634
635
|
const DEFAULT_VERSION_STRATEGY = 'ignore';
|
|
635
636
|
const DEFAULT_SCHEMA_STRATEGY = 'strict';
|
|
636
|
-
var _metadata$1 = /*#__PURE__*/ _class_private_field_loose_key$6("_metadata"), _schema = /*#__PURE__*/ _class_private_field_loose_key$6("_schema"), _handlers = /*#__PURE__*/ _class_private_field_loose_key$6("_handlers"),
|
|
637
|
-
_currentStream = /*#__PURE__*/ _class_private_field_loose_key$6("_currentStream"), /**
|
|
637
|
+
var _metadata$1 = /*#__PURE__*/ _class_private_field_loose_key$6("_metadata"), _schema = /*#__PURE__*/ _class_private_field_loose_key$6("_schema"), _handlers = /*#__PURE__*/ _class_private_field_loose_key$6("_handlers"), _currentStreamController = /*#__PURE__*/ _class_private_field_loose_key$6("_currentStreamController"), _aborted = /*#__PURE__*/ _class_private_field_loose_key$6("_aborted"), /**
|
|
638
638
|
* Create and return a transform stream based on the given stage and options.
|
|
639
639
|
*
|
|
640
640
|
* Allowed transformations includes 'filter' and 'map'.
|
|
@@ -749,11 +749,9 @@ class TransferEngine {
|
|
|
749
749
|
}
|
|
750
750
|
// Cause an ongoing transfer to abort gracefully
|
|
751
751
|
async abortTransfer() {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
}
|
|
756
|
-
_class_private_field_loose_base$6(this, _currentStream)[_currentStream].destroy(err);
|
|
752
|
+
_class_private_field_loose_base$6(this, _aborted)[_aborted] = true;
|
|
753
|
+
_class_private_field_loose_base$6(this, _currentStreamController)[_currentStreamController]?.abort();
|
|
754
|
+
throw new TransferEngineError('fatal', 'Transfer aborted.');
|
|
757
755
|
}
|
|
758
756
|
async init() {
|
|
759
757
|
// Resolve providers' resource and store
|
|
@@ -1063,7 +1061,11 @@ class TransferEngine {
|
|
|
1063
1061
|
writable: true,
|
|
1064
1062
|
value: void 0
|
|
1065
1063
|
});
|
|
1066
|
-
Object.defineProperty(this,
|
|
1064
|
+
Object.defineProperty(this, _currentStreamController, {
|
|
1065
|
+
writable: true,
|
|
1066
|
+
value: void 0
|
|
1067
|
+
});
|
|
1068
|
+
Object.defineProperty(this, _aborted, {
|
|
1067
1069
|
writable: true,
|
|
1068
1070
|
value: void 0
|
|
1069
1071
|
});
|
|
@@ -1073,6 +1075,7 @@ class TransferEngine {
|
|
|
1073
1075
|
schemaDiff: [],
|
|
1074
1076
|
errors: {}
|
|
1075
1077
|
};
|
|
1078
|
+
_class_private_field_loose_base$6(this, _aborted)[_aborted] = false;
|
|
1076
1079
|
this.diagnostics = createDiagnosticReporter();
|
|
1077
1080
|
validateProvider('source', sourceProvider);
|
|
1078
1081
|
validateProvider('destination', destinationProvider);
|
|
@@ -1271,6 +1274,9 @@ function assertSchemasMatching(sourceSchemas, destinationSchemas) {
|
|
|
1271
1274
|
}
|
|
1272
1275
|
}
|
|
1273
1276
|
async function transferStage(options) {
|
|
1277
|
+
if (_class_private_field_loose_base$6(this, _aborted)[_aborted]) {
|
|
1278
|
+
throw new TransferEngineError('fatal', 'Transfer aborted.');
|
|
1279
|
+
}
|
|
1274
1280
|
const { stage, source, destination, transform, tracker } = options;
|
|
1275
1281
|
const updateEndTime = ()=>{
|
|
1276
1282
|
const stageData = this.progress.data[stage];
|
|
@@ -1302,27 +1308,42 @@ async function transferStage(options) {
|
|
|
1302
1308
|
return;
|
|
1303
1309
|
}
|
|
1304
1310
|
_class_private_field_loose_base$6(this, _emitStageUpdate)[_emitStageUpdate]('start', stage);
|
|
1305
|
-
|
|
1306
|
-
|
|
1311
|
+
try {
|
|
1312
|
+
const streams = [
|
|
1313
|
+
source
|
|
1314
|
+
];
|
|
1307
1315
|
if (transform) {
|
|
1308
|
-
|
|
1316
|
+
streams.push(transform);
|
|
1309
1317
|
}
|
|
1310
1318
|
if (tracker) {
|
|
1311
|
-
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1319
|
+
streams.push(tracker);
|
|
1320
|
+
}
|
|
1321
|
+
streams.push(destination);
|
|
1322
|
+
// NOTE: to debug/confirm backpressure issues from misbehaving stream, uncomment the following lines
|
|
1323
|
+
// source.on('pause', () => console.log(`[${stage}] Source paused due to backpressure`));
|
|
1324
|
+
// source.on('resume', () => console.log(`[${stage}] Source resumed`));
|
|
1325
|
+
// destination.on('drain', () =>
|
|
1326
|
+
// console.log(`[${stage}] Destination drained, resuming data flow`)
|
|
1327
|
+
// );
|
|
1328
|
+
// destination.on('error', (err) => console.error(`[${stage}] Destination error:`, err));
|
|
1329
|
+
const controller = new AbortController();
|
|
1330
|
+
const { signal } = controller;
|
|
1331
|
+
// Store the controller so you can cancel later
|
|
1332
|
+
_class_private_field_loose_base$6(this, _currentStreamController)[_currentStreamController] = controller;
|
|
1333
|
+
await pipeline(streams, {
|
|
1334
|
+
signal
|
|
1323
1335
|
});
|
|
1324
|
-
|
|
1325
|
-
|
|
1336
|
+
_class_private_field_loose_base$6(this, _emitStageUpdate)[_emitStageUpdate]('finish', stage);
|
|
1337
|
+
} catch (e) {
|
|
1338
|
+
updateEndTime();
|
|
1339
|
+
_class_private_field_loose_base$6(this, _emitStageUpdate)[_emitStageUpdate]('error', stage);
|
|
1340
|
+
this.reportError(e, 'error');
|
|
1341
|
+
if (!destination.destroyed) {
|
|
1342
|
+
destination.destroy(e);
|
|
1343
|
+
}
|
|
1344
|
+
} finally{
|
|
1345
|
+
updateEndTime();
|
|
1346
|
+
}
|
|
1326
1347
|
}
|
|
1327
1348
|
async function resolveProviderResource() {
|
|
1328
1349
|
const sourceMetadata = await this.sourceProvider.getMetadata();
|
|
@@ -1894,9 +1915,7 @@ const createLinkQuery = (strapi, trx)=>{
|
|
|
1894
1915
|
assignOrderColumns();
|
|
1895
1916
|
const qb = connection.insert(payload).into(addSchema(joinTable.name));
|
|
1896
1917
|
if (trx) {
|
|
1897
|
-
await
|
|
1898
|
-
await qb.transacting(nestedTrx);
|
|
1899
|
-
});
|
|
1918
|
+
await qb.transacting(trx);
|
|
1900
1919
|
}
|
|
1901
1920
|
}
|
|
1902
1921
|
if ('morphColumn' in attribute && attribute.morphColumn) {
|
|
@@ -2349,7 +2368,7 @@ class LocalStrapiDestinationProvider {
|
|
|
2349
2368
|
const provider = strapi.config.get('plugin::upload').provider;
|
|
2350
2369
|
const fileId = fileEntitiesMapper?.[uploadData.id];
|
|
2351
2370
|
if (!fileId) {
|
|
2352
|
-
callback(new Error(`File ID not found for ID: ${uploadData.id}`));
|
|
2371
|
+
return callback(new Error(`File ID not found for ID: ${uploadData.id}`));
|
|
2353
2372
|
}
|
|
2354
2373
|
try {
|
|
2355
2374
|
await strapi.plugin('upload').provider.uploadStream(uploadData);
|
|
@@ -2400,9 +2419,9 @@ class LocalStrapiDestinationProvider {
|
|
|
2400
2419
|
provider
|
|
2401
2420
|
}
|
|
2402
2421
|
});
|
|
2403
|
-
callback();
|
|
2422
|
+
return callback();
|
|
2404
2423
|
} catch (error) {
|
|
2405
|
-
callback(new Error(`Error while uploading asset ${chunk.filename} ${error}`));
|
|
2424
|
+
return callback(new Error(`Error while uploading asset ${chunk.filename} ${error}`));
|
|
2406
2425
|
}
|
|
2407
2426
|
});
|
|
2408
2427
|
}
|
|
@@ -2939,7 +2958,7 @@ function reportError(message, error) {
|
|
|
2939
2958
|
}
|
|
2940
2959
|
function handleStreamError(streamType, err) {
|
|
2941
2960
|
const { message, stack } = err;
|
|
2942
|
-
const errorMessage = `Error in ${streamType} read stream: ${message}`;
|
|
2961
|
+
const errorMessage = `[Data transfer] Error in ${streamType} read stream: ${message}`;
|
|
2943
2962
|
const formattedError = {
|
|
2944
2963
|
message: errorMessage,
|
|
2945
2964
|
stack,
|
|
@@ -3111,17 +3130,6 @@ const connectToWebsocket = (address, options, diagnostics)=>{
|
|
|
3111
3130
|
const trimTrailingSlash = (input)=>{
|
|
3112
3131
|
return input.replace(/\/$/, '');
|
|
3113
3132
|
};
|
|
3114
|
-
const wait = (ms)=>{
|
|
3115
|
-
return new Promise((resolve)=>{
|
|
3116
|
-
setTimeout(resolve, ms);
|
|
3117
|
-
});
|
|
3118
|
-
};
|
|
3119
|
-
const waitUntil = async (test, interval)=>{
|
|
3120
|
-
while(!test()){
|
|
3121
|
-
await wait(interval);
|
|
3122
|
-
}
|
|
3123
|
-
return Promise.resolve();
|
|
3124
|
-
};
|
|
3125
3133
|
|
|
3126
3134
|
const TRANSFER_PATH = '/transfer/runner';
|
|
3127
3135
|
const TRANSFER_METHODS = [
|
|
@@ -3542,6 +3550,17 @@ class RemoteStrapiSourceProvider {
|
|
|
3542
3550
|
});
|
|
3543
3551
|
// Init the asset map
|
|
3544
3552
|
const assets = {};
|
|
3553
|
+
// Watch for stalled assets; if we don't receive a chunk within timeout, abort transfer
|
|
3554
|
+
const resetTimeout = (assetID)=>{
|
|
3555
|
+
if (assets[assetID].timeout) {
|
|
3556
|
+
clearTimeout(assets[assetID].timeout);
|
|
3557
|
+
}
|
|
3558
|
+
assets[assetID].timeout = setTimeout(()=>{
|
|
3559
|
+
_class_private_field_loose_base$2(this, _reportInfo$2)[_reportInfo$2](`Asset ${assetID} transfer stalled, aborting.`);
|
|
3560
|
+
assets[assetID].status = 'errored';
|
|
3561
|
+
assets[assetID].stream.destroy(new Error(`Asset ${assetID} transfer timed out`));
|
|
3562
|
+
}, this.options.streamTimeout);
|
|
3563
|
+
};
|
|
3545
3564
|
stream/**
|
|
3546
3565
|
* Process a payload of many transfer assets and performs the following tasks:
|
|
3547
3566
|
* - Start: creates a stream for new assets.
|
|
@@ -3552,56 +3571,46 @@ class RemoteStrapiSourceProvider {
|
|
|
3552
3571
|
const { action, assetID } = item;
|
|
3553
3572
|
// Creates the stream to send the incoming asset through
|
|
3554
3573
|
if (action === 'start') {
|
|
3555
|
-
//
|
|
3574
|
+
// if a transfer has already been started for the same asset ID, something is wrong
|
|
3556
3575
|
if (assets[assetID]) {
|
|
3557
|
-
|
|
3576
|
+
throw new Error(`Asset ${assetID} already started`);
|
|
3558
3577
|
}
|
|
3578
|
+
_class_private_field_loose_base$2(this, _reportInfo$2)[_reportInfo$2](`Asset ${assetID} starting`);
|
|
3559
3579
|
// Register the asset
|
|
3560
3580
|
assets[assetID] = {
|
|
3561
3581
|
...item.data,
|
|
3562
3582
|
stream: new PassThrough(),
|
|
3563
|
-
status: '
|
|
3583
|
+
status: 'ok',
|
|
3564
3584
|
queue: []
|
|
3565
3585
|
};
|
|
3586
|
+
resetTimeout(assetID);
|
|
3566
3587
|
// Connect the individual asset stream to the main asset stage stream
|
|
3567
3588
|
// Note: nothing is transferred until data chunks are fed to the asset stream
|
|
3568
3589
|
await this.writeAsync(pass, assets[assetID]);
|
|
3569
|
-
} else if (action === 'stream') {
|
|
3570
|
-
// If the asset hasn't been registered, or if it's been closed already,
|
|
3590
|
+
} else if (action === 'stream' || action === 'end') {
|
|
3591
|
+
// If the asset hasn't been registered, or if it's been closed already, something is wrong
|
|
3571
3592
|
if (!assets[assetID]) {
|
|
3572
|
-
|
|
3593
|
+
throw new Error(`No id matching ${assetID} for stream action`);
|
|
3573
3594
|
}
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
// The resource is busy, queue the current chunk so that it gets transferred as soon as possible
|
|
3580
|
-
case 'busy':
|
|
3581
|
-
assets[assetID].queue.push(item);
|
|
3582
|
-
break;
|
|
3595
|
+
// On every action, reset the timeout timer
|
|
3596
|
+
if (action === 'stream') {
|
|
3597
|
+
resetTimeout(assetID);
|
|
3598
|
+
} else {
|
|
3599
|
+
clearTimeout(assets[assetID].timeout);
|
|
3583
3600
|
}
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
if (!assets[assetID]) {
|
|
3587
|
-
continue;
|
|
3601
|
+
if (assets[assetID].status === 'closed') {
|
|
3602
|
+
throw new Error(`Asset ${assetID} is closed`);
|
|
3588
3603
|
}
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
waitUntil(()=>assets[assetID].status !== 'busy', 100),
|
|
3600
|
-
// Or: if the last chunks are still not processed after ten seconds
|
|
3601
|
-
wait(10000)
|
|
3602
|
-
]);
|
|
3603
|
-
await closeAssetStream(assetID);
|
|
3604
|
-
break;
|
|
3604
|
+
assets[assetID].queue.push(item);
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
// each new payload will start new processQueue calls, which may cause some extra calls
|
|
3608
|
+
// it's essentially saying "start processing this asset again, I added more data to the queue"
|
|
3609
|
+
for(const assetID in assets){
|
|
3610
|
+
if (Object.prototype.hasOwnProperty.call(assets, assetID)) {
|
|
3611
|
+
const asset = assets[assetID];
|
|
3612
|
+
if (asset.queue?.length > 0) {
|
|
3613
|
+
await processQueue(assetID);
|
|
3605
3614
|
}
|
|
3606
3615
|
}
|
|
3607
3616
|
}
|
|
@@ -3609,38 +3618,48 @@ class RemoteStrapiSourceProvider {
|
|
|
3609
3618
|
pass.end();
|
|
3610
3619
|
});
|
|
3611
3620
|
/**
|
|
3612
|
-
*
|
|
3613
|
-
|
|
3621
|
+
* Start processing the queue for a given assetID
|
|
3622
|
+
*
|
|
3623
|
+
* Even though this is a loop that attempts to process the entire queue, it is safe to call this more than once
|
|
3624
|
+
* for the same asset id because the queue is shared globally, the items are shifted off, and immediately written
|
|
3625
|
+
*/ const processQueue = async (id)=>{
|
|
3614
3626
|
if (!assets[id]) {
|
|
3615
3627
|
throw new Error(`Failed to write asset chunk for "${id}". Asset not found.`);
|
|
3616
3628
|
}
|
|
3617
|
-
const
|
|
3618
|
-
|
|
3629
|
+
const asset = assets[id];
|
|
3630
|
+
const { status: currentStatus } = asset;
|
|
3631
|
+
if ([
|
|
3632
|
+
'closed',
|
|
3633
|
+
'errored'
|
|
3634
|
+
].includes(currentStatus)) {
|
|
3619
3635
|
throw new Error(`Failed to write asset chunk for "${id}". The asset is currently "${currentStatus}"`);
|
|
3620
3636
|
}
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3637
|
+
while(asset.queue.length > 0){
|
|
3638
|
+
const data = asset.queue.shift();
|
|
3639
|
+
if (!data) {
|
|
3640
|
+
throw new Error(`Invalid chunk found for ${id}`);
|
|
3641
|
+
}
|
|
3642
|
+
try {
|
|
3643
|
+
// if this is an end chunk, close the asset stream
|
|
3644
|
+
if (data.action === 'end') {
|
|
3645
|
+
_class_private_field_loose_base$2(this, _reportInfo$2)[_reportInfo$2](`Ending asset stream for ${id}`);
|
|
3646
|
+
await closeAssetStream(id);
|
|
3647
|
+
break; // Exit the loop after closing the stream
|
|
3648
|
+
}
|
|
3649
|
+
// Save the current chunk
|
|
3650
|
+
await writeChunkToStream(id, data);
|
|
3651
|
+
} catch {
|
|
3652
|
+
if (!assets[id]) {
|
|
3653
|
+
throw new Error(`No id matching ${id} for writeAssetChunk`);
|
|
3654
|
+
}
|
|
3632
3655
|
}
|
|
3633
|
-
// Unlock the asset
|
|
3634
|
-
assets[id].status = 'idle';
|
|
3635
|
-
} catch {
|
|
3636
|
-
assets[id].status = 'errored';
|
|
3637
3656
|
}
|
|
3638
3657
|
};
|
|
3639
3658
|
/**
|
|
3640
3659
|
* Writes a chunk of data to the asset's stream.
|
|
3641
3660
|
*
|
|
3642
3661
|
* Only check if the targeted asset exists, no other validation is done.
|
|
3643
|
-
*/ const
|
|
3662
|
+
*/ const writeChunkToStream = async (id, data)=>{
|
|
3644
3663
|
const asset = assets[id];
|
|
3645
3664
|
if (!asset) {
|
|
3646
3665
|
throw new Error(`Failed to write asset chunk for "${id}". Asset not found.`);
|
|
@@ -3661,9 +3680,11 @@ class RemoteStrapiSourceProvider {
|
|
|
3661
3680
|
await new Promise((resolve, reject)=>{
|
|
3662
3681
|
const { stream } = assets[id];
|
|
3663
3682
|
stream.on('close', ()=>{
|
|
3664
|
-
delete assets[id];
|
|
3665
3683
|
resolve();
|
|
3666
|
-
}).on('error',
|
|
3684
|
+
}).on('error', (e)=>{
|
|
3685
|
+
assets[id].status = 'errored';
|
|
3686
|
+
reject(new Error(`Failed to close asset "${id}". Asset stream error: ${e.toString()}`));
|
|
3687
|
+
}).end();
|
|
3667
3688
|
});
|
|
3668
3689
|
};
|
|
3669
3690
|
return pass;
|
|
@@ -3778,6 +3799,9 @@ class RemoteStrapiSourceProvider {
|
|
|
3778
3799
|
});
|
|
3779
3800
|
this.name = 'source::remote-strapi';
|
|
3780
3801
|
this.type = 'source';
|
|
3802
|
+
this.defaultOptions = {
|
|
3803
|
+
streamTimeout: 15000
|
|
3804
|
+
};
|
|
3781
3805
|
this.writeAsync = (stream, data)=>{
|
|
3782
3806
|
return new Promise((resolve, reject)=>{
|
|
3783
3807
|
stream.write(data, (error)=>{
|
|
@@ -3788,7 +3812,10 @@ class RemoteStrapiSourceProvider {
|
|
|
3788
3812
|
});
|
|
3789
3813
|
});
|
|
3790
3814
|
};
|
|
3791
|
-
this.options =
|
|
3815
|
+
this.options = {
|
|
3816
|
+
...this.defaultOptions,
|
|
3817
|
+
...options
|
|
3818
|
+
};
|
|
3792
3819
|
this.ws = null;
|
|
3793
3820
|
this.dispatcher = null;
|
|
3794
3821
|
}
|
|
@@ -4721,6 +4748,18 @@ const createPullController = handlerControllerFactory((proto)=>({
|
|
|
4721
4748
|
kind: 'warning'
|
|
4722
4749
|
});
|
|
4723
4750
|
},
|
|
4751
|
+
onError (error) {
|
|
4752
|
+
this.diagnostics?.report({
|
|
4753
|
+
details: {
|
|
4754
|
+
message: error.message,
|
|
4755
|
+
error,
|
|
4756
|
+
createdAt: new Date(),
|
|
4757
|
+
name: error.name,
|
|
4758
|
+
severity: 'fatal'
|
|
4759
|
+
},
|
|
4760
|
+
kind: 'error'
|
|
4761
|
+
});
|
|
4762
|
+
},
|
|
4724
4763
|
assertValidTransferAction (action) {
|
|
4725
4764
|
// Abstract the constant to string[] to allow looser check on the given action
|
|
4726
4765
|
const validActions = VALID_TRANSFER_ACTIONS;
|
|
@@ -4794,6 +4833,15 @@ const createPullController = handlerControllerFactory((proto)=>({
|
|
|
4794
4833
|
let batch = [];
|
|
4795
4834
|
const stream = this.streams?.[stage];
|
|
4796
4835
|
const batchLength = ()=>Buffer.byteLength(JSON.stringify(batch));
|
|
4836
|
+
const maybeConfirm = async (data)=>{
|
|
4837
|
+
try {
|
|
4838
|
+
await this.confirm(data);
|
|
4839
|
+
} catch (error) {
|
|
4840
|
+
// Handle the error, log it, or take other appropriate actions
|
|
4841
|
+
strapi?.log.error(`[Data transfer] Message confirmation failed: ${error?.message}`);
|
|
4842
|
+
this.onError(error);
|
|
4843
|
+
}
|
|
4844
|
+
};
|
|
4797
4845
|
const sendBatch = async ()=>{
|
|
4798
4846
|
await this.confirm({
|
|
4799
4847
|
type: 'transfer',
|
|
@@ -4802,6 +4850,7 @@ const createPullController = handlerControllerFactory((proto)=>({
|
|
|
4802
4850
|
error: null,
|
|
4803
4851
|
id
|
|
4804
4852
|
});
|
|
4853
|
+
batch = [];
|
|
4805
4854
|
};
|
|
4806
4855
|
if (!stream) {
|
|
4807
4856
|
throw new ProviderTransferError(`No available stream found for ${stage}`);
|
|
@@ -4812,7 +4861,6 @@ const createPullController = handlerControllerFactory((proto)=>({
|
|
|
4812
4861
|
batch.push(chunk);
|
|
4813
4862
|
if (batchLength() >= batchSize) {
|
|
4814
4863
|
await sendBatch();
|
|
4815
|
-
batch = [];
|
|
4816
4864
|
}
|
|
4817
4865
|
} else {
|
|
4818
4866
|
await this.confirm({
|
|
@@ -4828,7 +4876,6 @@ const createPullController = handlerControllerFactory((proto)=>({
|
|
|
4828
4876
|
}
|
|
4829
4877
|
if (batch.length > 0 && stage !== 'assets') {
|
|
4830
4878
|
await sendBatch();
|
|
4831
|
-
batch = [];
|
|
4832
4879
|
}
|
|
4833
4880
|
await this.confirm({
|
|
4834
4881
|
type: 'transfer',
|
|
@@ -4838,7 +4885,8 @@ const createPullController = handlerControllerFactory((proto)=>({
|
|
|
4838
4885
|
id
|
|
4839
4886
|
});
|
|
4840
4887
|
} catch (e) {
|
|
4841
|
-
|
|
4888
|
+
// TODO: if this confirm fails, can we abort the whole transfer?
|
|
4889
|
+
await maybeConfirm({
|
|
4842
4890
|
type: 'transfer',
|
|
4843
4891
|
data: null,
|
|
4844
4892
|
ended: true,
|
|
@@ -4887,7 +4935,7 @@ const createPullController = handlerControllerFactory((proto)=>({
|
|
|
4887
4935
|
};
|
|
4888
4936
|
const BATCH_MAX_SIZE = 1024 * 1024; // 1MB
|
|
4889
4937
|
if (!assets) {
|
|
4890
|
-
throw new Error('
|
|
4938
|
+
throw new Error('Assets read stream could not be created');
|
|
4891
4939
|
}
|
|
4892
4940
|
/**
|
|
4893
4941
|
* Generates batches of 1MB of data from the assets stream to avoid
|
|
@@ -5138,7 +5186,7 @@ class LocalFileSourceProvider {
|
|
|
5138
5186
|
});
|
|
5139
5187
|
const loadAssetMetadata = _class_private_field_loose_base$1(this, _loadAssetMetadata)[_loadAssetMetadata].bind(this);
|
|
5140
5188
|
_class_private_field_loose_base$1(this, _reportInfo$1)[_reportInfo$1]('creating assets read stream');
|
|
5141
|
-
pipeline([
|
|
5189
|
+
pipeline$1([
|
|
5142
5190
|
inStream,
|
|
5143
5191
|
new tar.Parse({
|
|
5144
5192
|
// find only files in the assets/uploads folder
|
|
@@ -5249,7 +5297,7 @@ function streamJsonlDirectory(directory) {
|
|
|
5249
5297
|
const outStream = new PassThrough({
|
|
5250
5298
|
objectMode: true
|
|
5251
5299
|
});
|
|
5252
|
-
pipeline([
|
|
5300
|
+
pipeline$1([
|
|
5253
5301
|
inStream,
|
|
5254
5302
|
new tar.Parse({
|
|
5255
5303
|
filter (filePath, entry) {
|
|
@@ -5290,7 +5338,7 @@ function streamJsonlDirectory(directory) {
|
|
|
5290
5338
|
}
|
|
5291
5339
|
async function parseJSONFile(fileStream, filePath) {
|
|
5292
5340
|
return new Promise((resolve, reject)=>{
|
|
5293
|
-
pipeline([
|
|
5341
|
+
pipeline$1([
|
|
5294
5342
|
fileStream,
|
|
5295
5343
|
// Custom backup archive parsing
|
|
5296
5344
|
new tar.Parse({
|