@strapi/data-transfer 4.6.2 → 4.7.0-exp.117579f4c13806c2cd518e7d7d2f9d0c8a20107d
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/lib/engine/index.js +13 -3
- package/lib/file/providers/destination/index.js +7 -0
- package/lib/strapi/index.d.ts +0 -1
- package/lib/strapi/index.js +1 -6
- package/lib/strapi/providers/local-destination/index.d.ts +1 -1
- package/lib/strapi/providers/local-destination/index.js +9 -4
- package/lib/strapi/providers/remote-destination/index.d.ts +4 -7
- package/lib/strapi/providers/remote-destination/index.js +140 -57
- package/lib/strapi/providers/remote-destination/utils.js +2 -2
- package/lib/strapi/remote/constants.d.ts +2 -2
- package/lib/strapi/remote/constants.js +1 -1
- package/lib/strapi/remote/controllers/push.d.ts +1 -0
- package/lib/strapi/remote/controllers/push.js +53 -32
- package/lib/strapi/remote/flows/default.d.ts +3 -0
- package/lib/strapi/remote/flows/default.js +41 -0
- package/lib/strapi/remote/flows/index.d.ts +18 -0
- package/lib/strapi/remote/flows/index.js +59 -0
- package/lib/strapi/remote/handlers.d.ts +8 -1
- package/lib/strapi/remote/handlers.js +263 -171
- package/lib/strapi/remote/index.d.ts +1 -1
- package/lib/strapi/remote/index.js +2 -2
- package/lib/utils/transaction.js +21 -3
- package/package.json +4 -4
- package/lib/strapi/register.d.ts +0 -7
- package/lib/strapi/register.js +0 -13
- package/lib/strapi/remote/routes.d.ts +0 -21
- package/lib/strapi/remote/routes.js +0 -22
package/lib/engine/index.js
CHANGED
|
@@ -230,7 +230,7 @@ class TransferEngine {
|
|
|
230
230
|
const transform = __classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_createStageTransformStream).call(this, stage);
|
|
231
231
|
const tracker = __classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_progressTracker).call(this, stage, {
|
|
232
232
|
size: (value) => value.stats.size,
|
|
233
|
-
key: (value) => (0, path_1.extname)(value.filename)
|
|
233
|
+
key: (value) => (0, path_1.extname)(value.filename) || 'No extension',
|
|
234
234
|
});
|
|
235
235
|
await __classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_transferStage).call(this, { stage, source, destination, transform, tracker });
|
|
236
236
|
}
|
|
@@ -288,7 +288,7 @@ _TransferEngine_metadata = new WeakMap(), _TransferEngine_instances = new WeakSe
|
|
|
288
288
|
return stream;
|
|
289
289
|
}, _TransferEngine_updateTransferProgress = function _TransferEngine_updateTransferProgress(stage, data, aggregate) {
|
|
290
290
|
if (!this.progress.data[stage]) {
|
|
291
|
-
this.progress.data[stage] = { count: 0, bytes: 0 };
|
|
291
|
+
this.progress.data[stage] = { count: 0, bytes: 0, startTime: Date.now() };
|
|
292
292
|
}
|
|
293
293
|
const stageProgress = this.progress.data[stage];
|
|
294
294
|
if (!stageProgress) {
|
|
@@ -416,6 +416,12 @@ _TransferEngine_metadata = new WeakMap(), _TransferEngine_instances = new WeakSe
|
|
|
416
416
|
}
|
|
417
417
|
}, _TransferEngine_transferStage = async function _TransferEngine_transferStage(options) {
|
|
418
418
|
const { stage, source, destination, transform, tracker } = options;
|
|
419
|
+
const updateEndTime = () => {
|
|
420
|
+
const stageData = this.progress.data[stage];
|
|
421
|
+
if (stageData) {
|
|
422
|
+
stageData.endTime = Date.now();
|
|
423
|
+
}
|
|
424
|
+
};
|
|
419
425
|
if (!source || !destination || this.shouldSkipStage(stage)) {
|
|
420
426
|
// Wait until source and destination are closed
|
|
421
427
|
const results = await Promise.allSettled([source, destination].map((stream) => {
|
|
@@ -448,11 +454,15 @@ _TransferEngine_metadata = new WeakMap(), _TransferEngine_instances = new WeakSe
|
|
|
448
454
|
stream
|
|
449
455
|
.pipe(destination)
|
|
450
456
|
.on('error', (e) => {
|
|
457
|
+
updateEndTime();
|
|
451
458
|
__classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_reportError).call(this, e, 'error');
|
|
452
459
|
destination.destroy(e);
|
|
453
460
|
reject(e);
|
|
454
461
|
})
|
|
455
|
-
.on('close',
|
|
462
|
+
.on('close', () => {
|
|
463
|
+
updateEndTime();
|
|
464
|
+
resolve();
|
|
465
|
+
});
|
|
456
466
|
});
|
|
457
467
|
__classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_emitStageUpdate).call(this, 'finish', stage);
|
|
458
468
|
}, _TransferEngine_resolveProviderResource = async function _TransferEngine_resolveProviderResource() {
|
|
@@ -19,6 +19,7 @@ const stream_chain_1 = require("stream-chain");
|
|
|
19
19
|
const stream_1 = require("stream");
|
|
20
20
|
const encryption_1 = require("../../../utils/encryption");
|
|
21
21
|
const utils_1 = require("./utils");
|
|
22
|
+
const providers_1 = require("../../../errors/providers");
|
|
22
23
|
const createLocalFileDestinationProvider = (options) => {
|
|
23
24
|
return new LocalFileDestinationProvider(options);
|
|
24
25
|
};
|
|
@@ -47,6 +48,12 @@ class LocalFileDestinationProvider {
|
|
|
47
48
|
}
|
|
48
49
|
__classPrivateFieldGet(this, _LocalFileDestinationProvider_archive, "f").stream = tar_stream_1.default.pack();
|
|
49
50
|
const outStream = (0, fs_extra_1.createWriteStream)(__classPrivateFieldGet(this, _LocalFileDestinationProvider_instances, "a", _LocalFileDestinationProvider_archivePath_get));
|
|
51
|
+
outStream.on('error', (err) => {
|
|
52
|
+
if (err.code === 'ENOSPC') {
|
|
53
|
+
throw new providers_1.ProviderTransferError("Your server doesn't have space to proceed with the import.");
|
|
54
|
+
}
|
|
55
|
+
throw err;
|
|
56
|
+
});
|
|
50
57
|
const archiveTransforms = [];
|
|
51
58
|
if (compression.enabled) {
|
|
52
59
|
archiveTransforms.push(this.createGzip());
|
package/lib/strapi/index.d.ts
CHANGED
package/lib/strapi/index.js
CHANGED
|
@@ -22,14 +22,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
26
|
+
exports.remote = exports.queries = exports.providers = void 0;
|
|
30
27
|
exports.providers = __importStar(require("./providers"));
|
|
31
28
|
exports.queries = __importStar(require("./queries"));
|
|
32
29
|
exports.remote = __importStar(require("./remote"));
|
|
33
|
-
var register_1 = require("./register");
|
|
34
|
-
Object.defineProperty(exports, "register", { enumerable: true, get: function () { return __importDefault(register_1).default; } });
|
|
35
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -21,7 +21,7 @@ declare class LocalStrapiDestinationProvider implements IDestinationProvider {
|
|
|
21
21
|
constructor(options: ILocalStrapiDestinationProviderOptions);
|
|
22
22
|
bootstrap(): Promise<void>;
|
|
23
23
|
close(): Promise<void>;
|
|
24
|
-
rollback(): void
|
|
24
|
+
rollback(): Promise<void>;
|
|
25
25
|
beforeTransfer(): Promise<void>;
|
|
26
26
|
getMetadata(): IMetadata;
|
|
27
27
|
getSchemas(): import("lodash").Dictionary<Partial<import("@strapi/strapi").Schema>>;
|
|
@@ -73,8 +73,8 @@ class LocalStrapiDestinationProvider {
|
|
|
73
73
|
await this.strapi?.destroy();
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
rollback() {
|
|
77
|
-
this.transaction?.rollback();
|
|
76
|
+
async rollback() {
|
|
77
|
+
await this.transaction?.rollback();
|
|
78
78
|
}
|
|
79
79
|
async beforeTransfer() {
|
|
80
80
|
if (!this.strapi) {
|
|
@@ -151,12 +151,17 @@ class LocalStrapiDestinationProvider {
|
|
|
151
151
|
const writableStream = fse.createWriteStream(entryPath);
|
|
152
152
|
chunk.stream
|
|
153
153
|
.pipe(writableStream)
|
|
154
|
-
.on('close',
|
|
154
|
+
.on('close', () => {
|
|
155
|
+
callback(null);
|
|
156
|
+
})
|
|
155
157
|
.on('error', async (error) => {
|
|
158
|
+
const errorMessage = error.code === 'ENOSPC'
|
|
159
|
+
? " Your server doesn't have space to proceed with the import. "
|
|
160
|
+
: ' ';
|
|
156
161
|
try {
|
|
157
162
|
await fse.rm(assetsDirectory, { recursive: true, force: true });
|
|
158
163
|
await fse.move(backupDirectory, assetsDirectory);
|
|
159
|
-
this.destroy(new providers_1.ProviderTransferError(`There was an error during the transfer process
|
|
164
|
+
this.destroy(new providers_1.ProviderTransferError(`There was an error during the transfer process.${errorMessage}The original files have been restored to ${assetsDirectory}`));
|
|
160
165
|
}
|
|
161
166
|
catch (err) {
|
|
162
167
|
throw new providers_1.ProviderTransferError(`There was an error doing the rollback process. The original files are in ${backupDirectory}, but we failed to restore them to ${assetsDirectory}`);
|
|
@@ -4,18 +4,13 @@ import { Writable } from 'stream';
|
|
|
4
4
|
import { createDispatcher } from './utils';
|
|
5
5
|
import type { IDestinationProvider, IMetadata, ProviderType } from '../../../../types';
|
|
6
6
|
import type { ILocalStrapiDestinationProviderOptions } from '../local-destination';
|
|
7
|
-
interface
|
|
7
|
+
interface ITransferTokenAuth {
|
|
8
8
|
type: 'token';
|
|
9
9
|
token: string;
|
|
10
10
|
}
|
|
11
|
-
interface ICredentialsAuth {
|
|
12
|
-
type: 'credentials';
|
|
13
|
-
email: string;
|
|
14
|
-
password: string;
|
|
15
|
-
}
|
|
16
11
|
export interface IRemoteStrapiDestinationProviderOptions extends Pick<ILocalStrapiDestinationProviderOptions, 'restore' | 'strategy'> {
|
|
17
12
|
url: URL;
|
|
18
|
-
auth?:
|
|
13
|
+
auth?: ITransferTokenAuth;
|
|
19
14
|
}
|
|
20
15
|
declare class RemoteStrapiDestinationProvider implements IDestinationProvider {
|
|
21
16
|
#private;
|
|
@@ -24,12 +19,14 @@ declare class RemoteStrapiDestinationProvider implements IDestinationProvider {
|
|
|
24
19
|
options: IRemoteStrapiDestinationProviderOptions;
|
|
25
20
|
ws: WebSocket | null;
|
|
26
21
|
dispatcher: ReturnType<typeof createDispatcher> | null;
|
|
22
|
+
transferID: string | null;
|
|
27
23
|
constructor(options: IRemoteStrapiDestinationProviderOptions);
|
|
28
24
|
initTransfer(): Promise<string>;
|
|
29
25
|
bootstrap(): Promise<void>;
|
|
30
26
|
close(): Promise<void>;
|
|
31
27
|
getMetadata(): Promise<IMetadata | null> | null;
|
|
32
28
|
beforeTransfer(): Promise<void>;
|
|
29
|
+
rollback(): Promise<void>;
|
|
33
30
|
getSchemas(): Promise<Strapi.Schemas | null>;
|
|
34
31
|
createEntitiesWriteStream(): Writable;
|
|
35
32
|
createLinksWriteStream(): Writable;
|
|
@@ -4,15 +4,17 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
4
4
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
5
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
6
|
};
|
|
7
|
-
var _RemoteStrapiDestinationProvider_instances, _RemoteStrapiDestinationProvider_streamStep;
|
|
7
|
+
var _RemoteStrapiDestinationProvider_instances, _RemoteStrapiDestinationProvider_startStepOnce, _RemoteStrapiDestinationProvider_startStep, _RemoteStrapiDestinationProvider_endStep, _RemoteStrapiDestinationProvider_streamStep, _RemoteStrapiDestinationProvider_writeStream;
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.createRemoteStrapiDestinationProvider = void 0;
|
|
10
10
|
const ws_1 = require("ws");
|
|
11
11
|
const uuid_1 = require("uuid");
|
|
12
12
|
const stream_1 = require("stream");
|
|
13
|
+
const fp_1 = require("lodash/fp");
|
|
13
14
|
const utils_1 = require("./utils");
|
|
14
15
|
const constants_1 = require("../../remote/constants");
|
|
15
16
|
const providers_1 = require("../../../errors/providers");
|
|
17
|
+
const jsonLength = (obj) => Buffer.byteLength(JSON.stringify(obj));
|
|
16
18
|
class RemoteStrapiDestinationProvider {
|
|
17
19
|
constructor(options) {
|
|
18
20
|
_RemoteStrapiDestinationProvider_instances.add(this);
|
|
@@ -21,6 +23,7 @@ class RemoteStrapiDestinationProvider {
|
|
|
21
23
|
this.options = options;
|
|
22
24
|
this.ws = null;
|
|
23
25
|
this.dispatcher = null;
|
|
26
|
+
this.transferID = null;
|
|
24
27
|
}
|
|
25
28
|
async initTransfer() {
|
|
26
29
|
const { strategy, restore } = this.options;
|
|
@@ -28,17 +31,24 @@ class RemoteStrapiDestinationProvider {
|
|
|
28
31
|
return new Promise((resolve, reject) => {
|
|
29
32
|
this.ws
|
|
30
33
|
?.once('open', async () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
try {
|
|
35
|
+
const query = this.dispatcher?.dispatchCommand({
|
|
36
|
+
command: 'init',
|
|
37
|
+
params: { options: { strategy, restore }, transfer: 'push' },
|
|
38
|
+
});
|
|
39
|
+
const res = (await query);
|
|
40
|
+
if (!res?.transferID) {
|
|
41
|
+
throw new providers_1.ProviderTransferError('Init failed, invalid response from the server');
|
|
42
|
+
}
|
|
43
|
+
resolve(res.transferID);
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
reject(e);
|
|
38
47
|
}
|
|
39
|
-
resolve(res.transferID);
|
|
40
48
|
})
|
|
41
|
-
.once('error',
|
|
49
|
+
.once('error', (message) => {
|
|
50
|
+
reject(message);
|
|
51
|
+
});
|
|
42
52
|
});
|
|
43
53
|
}
|
|
44
54
|
async bootstrap() {
|
|
@@ -56,7 +66,6 @@ class RemoteStrapiDestinationProvider {
|
|
|
56
66
|
}
|
|
57
67
|
const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
58
68
|
const wsUrl = `${wsProtocol}//${url.host}${url.pathname}${constants_1.TRANSFER_PATH}`;
|
|
59
|
-
const validAuthMethods = ['token'];
|
|
60
69
|
// No auth defined, trying public access for transfer
|
|
61
70
|
if (!auth) {
|
|
62
71
|
ws = new ws_1.WebSocket(wsUrl);
|
|
@@ -68,22 +77,28 @@ class RemoteStrapiDestinationProvider {
|
|
|
68
77
|
}
|
|
69
78
|
// Invalid auth method provided
|
|
70
79
|
else {
|
|
71
|
-
throw new providers_1.ProviderValidationError('Auth method not
|
|
80
|
+
throw new providers_1.ProviderValidationError('Auth method not available', {
|
|
72
81
|
check: 'auth.type',
|
|
73
82
|
details: {
|
|
74
83
|
auth: auth.type,
|
|
75
|
-
validAuthMethods,
|
|
76
84
|
},
|
|
77
85
|
});
|
|
78
86
|
}
|
|
79
87
|
this.ws = ws;
|
|
80
88
|
this.dispatcher = (0, utils_1.createDispatcher)(this.ws);
|
|
81
|
-
|
|
82
|
-
this.dispatcher.setTransferProperties({ id: transferID, kind: 'push' });
|
|
89
|
+
this.transferID = await this.initTransfer();
|
|
90
|
+
this.dispatcher.setTransferProperties({ id: this.transferID, kind: 'push' });
|
|
83
91
|
await this.dispatcher.dispatchTransferAction('bootstrap');
|
|
84
92
|
}
|
|
85
93
|
async close() {
|
|
86
|
-
|
|
94
|
+
// Gracefully close the remote transfer process
|
|
95
|
+
if (this.transferID && this.dispatcher) {
|
|
96
|
+
await this.dispatcher.dispatchTransferAction('close');
|
|
97
|
+
await this.dispatcher.dispatchCommand({
|
|
98
|
+
command: 'end',
|
|
99
|
+
params: { transferID: this.transferID },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
87
102
|
await new Promise((resolve) => {
|
|
88
103
|
const { ws } = this;
|
|
89
104
|
if (!ws || ws.CLOSED) {
|
|
@@ -99,6 +114,9 @@ class RemoteStrapiDestinationProvider {
|
|
|
99
114
|
async beforeTransfer() {
|
|
100
115
|
await this.dispatcher?.dispatchTransferAction('beforeTransfer');
|
|
101
116
|
}
|
|
117
|
+
async rollback() {
|
|
118
|
+
await this.dispatcher?.dispatchTransferAction('rollback');
|
|
119
|
+
}
|
|
102
120
|
getSchemas() {
|
|
103
121
|
if (!this.dispatcher) {
|
|
104
122
|
return Promise.resolve(null);
|
|
@@ -106,65 +124,96 @@ class RemoteStrapiDestinationProvider {
|
|
|
106
124
|
return this.dispatcher.dispatchTransferAction('getSchemas');
|
|
107
125
|
}
|
|
108
126
|
createEntitiesWriteStream() {
|
|
109
|
-
return
|
|
110
|
-
objectMode: true,
|
|
111
|
-
write: async (entity, _encoding, callback) => {
|
|
112
|
-
const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'entities', entity);
|
|
113
|
-
callback(e);
|
|
114
|
-
},
|
|
115
|
-
});
|
|
127
|
+
return __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_writeStream).call(this, 'entities');
|
|
116
128
|
}
|
|
117
129
|
createLinksWriteStream() {
|
|
118
|
-
return
|
|
119
|
-
objectMode: true,
|
|
120
|
-
write: async (link, _encoding, callback) => {
|
|
121
|
-
const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'links', link);
|
|
122
|
-
callback(e);
|
|
123
|
-
},
|
|
124
|
-
});
|
|
130
|
+
return __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_writeStream).call(this, 'links');
|
|
125
131
|
}
|
|
126
132
|
createConfigurationWriteStream() {
|
|
127
|
-
return
|
|
128
|
-
objectMode: true,
|
|
129
|
-
write: async (configuration, _encoding, callback) => {
|
|
130
|
-
const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'configuration', configuration);
|
|
131
|
-
callback(e);
|
|
132
|
-
},
|
|
133
|
-
});
|
|
133
|
+
return __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_writeStream).call(this, 'configuration');
|
|
134
134
|
}
|
|
135
135
|
createAssetsWriteStream() {
|
|
136
|
+
let batch = [];
|
|
137
|
+
let hasStarted = false;
|
|
138
|
+
const batchSize = 1024 * 1024; // 1MB;
|
|
139
|
+
const batchLength = () => {
|
|
140
|
+
return batch.reduce((acc, chunk) => (chunk.action === 'stream' ? acc + chunk.data.byteLength : acc), 0);
|
|
141
|
+
};
|
|
142
|
+
const startAssetsTransferOnce = __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_startStepOnce).call(this, 'assets');
|
|
143
|
+
const flush = async () => {
|
|
144
|
+
await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', batch);
|
|
145
|
+
batch = [];
|
|
146
|
+
};
|
|
147
|
+
const safePush = async (chunk) => {
|
|
148
|
+
batch.push(chunk);
|
|
149
|
+
if (batchLength() >= batchSize) {
|
|
150
|
+
await flush();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
136
153
|
return new stream_1.Writable({
|
|
137
154
|
objectMode: true,
|
|
138
155
|
final: async (callback) => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
156
|
+
if (batch.length > 0) {
|
|
157
|
+
await flush();
|
|
158
|
+
}
|
|
159
|
+
if (hasStarted) {
|
|
160
|
+
await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', null);
|
|
161
|
+
const endStepError = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_endStep).call(this, 'assets');
|
|
162
|
+
if (endStepError) {
|
|
163
|
+
return callback(endStepError);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return callback(null);
|
|
142
167
|
},
|
|
143
|
-
|
|
144
|
-
const
|
|
168
|
+
async write(asset, _encoding, callback) {
|
|
169
|
+
const startError = await startAssetsTransferOnce();
|
|
170
|
+
if (startError) {
|
|
171
|
+
return callback(startError);
|
|
172
|
+
}
|
|
173
|
+
hasStarted = true;
|
|
145
174
|
const assetID = (0, uuid_1.v4)();
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
assetID,
|
|
149
|
-
data: { filename, filepath, stats },
|
|
150
|
-
});
|
|
175
|
+
const { filename, filepath, stats, stream } = asset;
|
|
176
|
+
await safePush({ action: 'start', assetID, data: { filename, filepath, stats } });
|
|
151
177
|
for await (const chunk of stream) {
|
|
152
|
-
await
|
|
153
|
-
action: 'stream',
|
|
154
|
-
assetID,
|
|
155
|
-
data: chunk,
|
|
156
|
-
});
|
|
178
|
+
await safePush({ action: 'stream', assetID, data: chunk });
|
|
157
179
|
}
|
|
158
|
-
await
|
|
159
|
-
action: 'end',
|
|
160
|
-
assetID,
|
|
161
|
-
});
|
|
180
|
+
await safePush({ action: 'end', assetID });
|
|
162
181
|
callback();
|
|
163
182
|
},
|
|
164
183
|
});
|
|
165
184
|
}
|
|
166
185
|
}
|
|
167
|
-
_RemoteStrapiDestinationProvider_instances = new WeakSet(),
|
|
186
|
+
_RemoteStrapiDestinationProvider_instances = new WeakSet(), _RemoteStrapiDestinationProvider_startStepOnce = function _RemoteStrapiDestinationProvider_startStepOnce(stage) {
|
|
187
|
+
return (0, fp_1.once)(() => __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_startStep).call(this, stage));
|
|
188
|
+
}, _RemoteStrapiDestinationProvider_startStep = async function _RemoteStrapiDestinationProvider_startStep(step) {
|
|
189
|
+
try {
|
|
190
|
+
await this.dispatcher?.dispatchTransferStep({ action: 'start', step });
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
if (e instanceof Error) {
|
|
194
|
+
return e;
|
|
195
|
+
}
|
|
196
|
+
if (typeof e === 'string') {
|
|
197
|
+
return new providers_1.ProviderTransferError(e);
|
|
198
|
+
}
|
|
199
|
+
return new providers_1.ProviderTransferError('Unexpected error');
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}, _RemoteStrapiDestinationProvider_endStep = async function _RemoteStrapiDestinationProvider_endStep(step) {
|
|
203
|
+
try {
|
|
204
|
+
await this.dispatcher?.dispatchTransferStep({ action: 'end', step });
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
if (e instanceof Error) {
|
|
208
|
+
return e;
|
|
209
|
+
}
|
|
210
|
+
if (typeof e === 'string') {
|
|
211
|
+
return new providers_1.ProviderTransferError(e);
|
|
212
|
+
}
|
|
213
|
+
return new providers_1.ProviderTransferError('Unexpected error');
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}, _RemoteStrapiDestinationProvider_streamStep = async function _RemoteStrapiDestinationProvider_streamStep(step, data) {
|
|
168
217
|
try {
|
|
169
218
|
await this.dispatcher?.dispatchTransferStep({ action: 'stream', step, data });
|
|
170
219
|
}
|
|
@@ -178,6 +227,40 @@ _RemoteStrapiDestinationProvider_instances = new WeakSet(), _RemoteStrapiDestina
|
|
|
178
227
|
return new providers_1.ProviderTransferError('Unexpected error');
|
|
179
228
|
}
|
|
180
229
|
return null;
|
|
230
|
+
}, _RemoteStrapiDestinationProvider_writeStream = function _RemoteStrapiDestinationProvider_writeStream(step) {
|
|
231
|
+
const batchSize = 1024 * 1024; // 1MB;
|
|
232
|
+
const startTransferOnce = __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_startStepOnce).call(this, step);
|
|
233
|
+
let batch = [];
|
|
234
|
+
const batchLength = () => jsonLength(batch);
|
|
235
|
+
return new stream_1.Writable({
|
|
236
|
+
objectMode: true,
|
|
237
|
+
final: async (callback) => {
|
|
238
|
+
if (batch.length > 0) {
|
|
239
|
+
const streamError = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, step, batch);
|
|
240
|
+
batch = [];
|
|
241
|
+
if (streamError) {
|
|
242
|
+
return callback(streamError);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_endStep).call(this, step);
|
|
246
|
+
callback(e);
|
|
247
|
+
},
|
|
248
|
+
write: async (chunk, _encoding, callback) => {
|
|
249
|
+
const startError = await startTransferOnce();
|
|
250
|
+
if (startError) {
|
|
251
|
+
return callback(startError);
|
|
252
|
+
}
|
|
253
|
+
batch.push(chunk);
|
|
254
|
+
if (batchLength() >= batchSize) {
|
|
255
|
+
const streamError = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, step, batch);
|
|
256
|
+
batch = [];
|
|
257
|
+
if (streamError) {
|
|
258
|
+
return callback(streamError);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
callback();
|
|
262
|
+
},
|
|
263
|
+
});
|
|
181
264
|
};
|
|
182
265
|
const createRemoteStrapiDestinationProvider = (options) => {
|
|
183
266
|
return new RemoteStrapiDestinationProvider(options);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createDispatcher = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
|
+
const providers_1 = require("../../../errors/providers");
|
|
5
6
|
const createDispatcher = (ws) => {
|
|
6
7
|
const state = {};
|
|
7
8
|
const dispatch = async (message, options = {}) => {
|
|
@@ -24,7 +25,7 @@ const createDispatcher = (ws) => {
|
|
|
24
25
|
const response = JSON.parse(raw.toString());
|
|
25
26
|
if (response.uuid === uuid) {
|
|
26
27
|
if (response.error) {
|
|
27
|
-
return reject(new
|
|
28
|
+
return reject(new providers_1.ProviderError('error', response.error.message));
|
|
28
29
|
}
|
|
29
30
|
resolve(response.data ?? null);
|
|
30
31
|
}
|
|
@@ -32,7 +33,6 @@ const createDispatcher = (ws) => {
|
|
|
32
33
|
ws.once('message', onResponse);
|
|
33
34
|
}
|
|
34
35
|
};
|
|
35
|
-
// TODO: What happens if the server sends another message (not a response to this message)
|
|
36
36
|
ws.once('message', onResponse);
|
|
37
37
|
});
|
|
38
38
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const TRANSFER_PATH
|
|
2
|
-
export declare const TRANSFER_METHODS:
|
|
1
|
+
export declare const TRANSFER_PATH: "/transfer/runner/connect";
|
|
2
|
+
export declare const TRANSFER_METHODS: readonly ["push", "pull"];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TRANSFER_METHODS = exports.TRANSFER_PATH = void 0;
|
|
4
|
-
exports.TRANSFER_PATH = '/transfer';
|
|
4
|
+
exports.TRANSFER_PATH = '/transfer/runner/connect';
|
|
5
5
|
exports.TRANSFER_METHODS = ['push', 'pull'];
|
|
6
6
|
//# sourceMappingURL=constants.js.map
|
|
@@ -34,58 +34,79 @@ const createPushController = (options) => {
|
|
|
34
34
|
async beforeTransfer() {
|
|
35
35
|
return provider.beforeTransfer();
|
|
36
36
|
},
|
|
37
|
+
async rollback() {
|
|
38
|
+
await provider.rollback();
|
|
39
|
+
},
|
|
37
40
|
},
|
|
38
41
|
transfer: {
|
|
39
|
-
async entities(
|
|
42
|
+
async entities(entities) {
|
|
40
43
|
if (!streams.entities) {
|
|
41
44
|
streams.entities = provider.createEntitiesWriteStream();
|
|
42
45
|
}
|
|
43
|
-
|
|
46
|
+
for (const entity of entities) {
|
|
47
|
+
if (streams.entities) {
|
|
48
|
+
await writeAsync(streams.entities, entity);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
44
51
|
},
|
|
45
|
-
async links(
|
|
52
|
+
async links(links) {
|
|
46
53
|
if (!streams.links) {
|
|
47
54
|
streams.links = await provider.createLinksWriteStream();
|
|
48
55
|
}
|
|
49
|
-
|
|
56
|
+
for (const link of links) {
|
|
57
|
+
if (streams.links) {
|
|
58
|
+
await writeAsync(streams.links, link);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
50
61
|
},
|
|
51
|
-
async configuration(
|
|
62
|
+
async configuration(configs) {
|
|
52
63
|
if (!streams.configuration) {
|
|
53
64
|
streams.configuration = await provider.createConfigurationWriteStream();
|
|
54
65
|
}
|
|
55
|
-
|
|
66
|
+
for (const config of configs) {
|
|
67
|
+
if (streams.configuration) {
|
|
68
|
+
await writeAsync(streams.configuration, config);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
56
71
|
},
|
|
57
|
-
async assets(
|
|
58
|
-
|
|
59
|
-
if (payload === null) {
|
|
72
|
+
async assets(payloads) {
|
|
73
|
+
if (payloads === null) {
|
|
60
74
|
streams.assets?.end();
|
|
61
75
|
return;
|
|
62
76
|
}
|
|
63
|
-
const { action, assetID } = payload;
|
|
64
77
|
if (!streams.assets) {
|
|
65
78
|
streams.assets = await provider.createAssetsWriteStream();
|
|
66
79
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
stream
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
for (const payload of payloads) {
|
|
81
|
+
if (streams.assets.closed) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const { action, assetID } = payload;
|
|
85
|
+
if (action === 'start' && streams.assets) {
|
|
86
|
+
assets[assetID] = { ...payload.data, stream: new stream_chain_1.PassThrough() };
|
|
87
|
+
writeAsync(streams.assets, assets[assetID]);
|
|
88
|
+
}
|
|
89
|
+
if (action === 'stream') {
|
|
90
|
+
// The buffer has gone through JSON operations and is now of shape { type: "Buffer"; data: UInt8Array }
|
|
91
|
+
// We need to transform it back into a Buffer instance
|
|
92
|
+
const rawBuffer = payload.data;
|
|
93
|
+
const chunk = Buffer.from(rawBuffer.data);
|
|
94
|
+
await writeAsync(assets[assetID].stream, chunk);
|
|
95
|
+
}
|
|
96
|
+
if (action === 'end') {
|
|
97
|
+
await new Promise((resolve, reject) => {
|
|
98
|
+
const { stream } = assets[assetID];
|
|
99
|
+
stream
|
|
100
|
+
.on('close', () => {
|
|
101
|
+
delete assets[assetID];
|
|
102
|
+
resolve();
|
|
103
|
+
})
|
|
104
|
+
.on('error', (e) => {
|
|
105
|
+
reject(e);
|
|
106
|
+
})
|
|
107
|
+
.end();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
89
110
|
}
|
|
90
111
|
},
|
|
91
112
|
},
|