@strapi/data-transfer 5.12.0 → 5.12.2
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/errors.js +39 -0
- package/dist/engine/errors.js.map +1 -0
- package/dist/engine/errors.mjs +34 -0
- package/dist/engine/errors.mjs.map +1 -0
- package/dist/engine/index.js +797 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/index.mjs +792 -0
- package/dist/engine/index.mjs.map +1 -0
- package/dist/engine/validation/provider.js +19 -0
- package/dist/engine/validation/provider.js.map +1 -0
- package/dist/engine/validation/provider.mjs +17 -0
- package/dist/engine/validation/provider.mjs.map +1 -0
- package/dist/engine/validation/schemas/index.js +57 -0
- package/dist/engine/validation/schemas/index.js.map +1 -0
- package/dist/engine/validation/schemas/index.mjs +55 -0
- package/dist/engine/validation/schemas/index.mjs.map +1 -0
- package/dist/errors/base.js +13 -0
- package/dist/errors/base.js.map +1 -0
- package/dist/errors/base.mjs +11 -0
- package/dist/errors/base.mjs.map +1 -0
- package/dist/errors/constants.js +10 -0
- package/dist/errors/constants.js.map +1 -0
- package/dist/errors/constants.mjs +8 -0
- package/dist/errors/constants.mjs.map +1 -0
- package/dist/errors/providers.js +41 -0
- package/dist/errors/providers.js.map +1 -0
- package/dist/errors/providers.mjs +36 -0
- package/dist/errors/providers.mjs.map +1 -0
- package/dist/file/index.js +8 -0
- package/dist/file/index.js.map +1 -0
- package/dist/file/index.mjs +3 -0
- package/dist/file/index.mjs.map +1 -0
- package/dist/file/providers/destination/index.js +248 -0
- package/dist/file/providers/destination/index.js.map +1 -0
- package/dist/file/providers/destination/index.mjs +246 -0
- package/dist/file/providers/destination/index.mjs.map +1 -0
- package/dist/file/providers/destination/utils.js +63 -0
- package/dist/file/providers/destination/utils.js.map +1 -0
- package/dist/file/providers/destination/utils.mjs +60 -0
- package/dist/file/providers/destination/utils.mjs.map +1 -0
- package/dist/file/providers/index.js +10 -0
- package/dist/file/providers/index.js.map +1 -0
- package/dist/file/providers/index.mjs +3 -0
- package/dist/file/providers/index.mjs.map +1 -0
- package/dist/file/providers/source/index.js +288 -0
- package/dist/file/providers/source/index.js.map +1 -0
- package/dist/file/providers/source/index.mjs +286 -0
- package/dist/file/providers/source/index.mjs.map +1 -0
- package/dist/file/providers/source/utils.js +56 -0
- package/dist/file/providers/source/utils.js.map +1 -0
- package/dist/file/providers/source/utils.mjs +52 -0
- package/dist/file/providers/source/utils.mjs.map +1 -0
- package/dist/index.js +8 -5692
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -5674
- package/dist/index.mjs.map +1 -1
- package/dist/strapi/index.js +12 -0
- package/dist/strapi/index.js.map +1 -0
- package/dist/strapi/index.mjs +7 -0
- package/dist/strapi/index.mjs.map +1 -0
- package/dist/strapi/providers/index.js +16 -0
- package/dist/strapi/providers/index.js.map +1 -0
- package/dist/strapi/providers/index.mjs +7 -0
- package/dist/strapi/providers/index.mjs.map +1 -0
- package/dist/strapi/providers/local-destination/index.js +419 -0
- package/dist/strapi/providers/local-destination/index.js.map +1 -0
- package/dist/strapi/providers/local-destination/index.mjs +396 -0
- package/dist/strapi/providers/local-destination/index.mjs.map +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.js +52 -0
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.js.map +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.mjs +49 -0
- package/dist/strapi/providers/local-destination/strategies/restore/configuration.mjs.map +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/entities.js +64 -0
- package/dist/strapi/providers/local-destination/strategies/restore/entities.js.map +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs +62 -0
- package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs.map +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/index.js +126 -0
- package/dist/strapi/providers/local-destination/strategies/restore/index.js.map +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/index.mjs +122 -0
- package/dist/strapi/providers/local-destination/strategies/restore/index.mjs.map +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/links.js +60 -0
- package/dist/strapi/providers/local-destination/strategies/restore/links.js.map +1 -0
- package/dist/strapi/providers/local-destination/strategies/restore/links.mjs +58 -0
- package/dist/strapi/providers/local-destination/strategies/restore/links.mjs.map +1 -0
- package/dist/strapi/providers/local-source/assets.js +123 -0
- package/dist/strapi/providers/local-source/assets.js.map +1 -0
- package/dist/strapi/providers/local-source/assets.mjs +121 -0
- package/dist/strapi/providers/local-source/assets.mjs.map +1 -0
- package/dist/strapi/providers/local-source/configuration.js +39 -0
- package/dist/strapi/providers/local-source/configuration.js.map +1 -0
- package/dist/strapi/providers/local-source/configuration.mjs +37 -0
- package/dist/strapi/providers/local-source/configuration.mjs.map +1 -0
- package/dist/strapi/providers/local-source/entities.js +62 -0
- package/dist/strapi/providers/local-source/entities.js.map +1 -0
- package/dist/strapi/providers/local-source/entities.mjs +59 -0
- package/dist/strapi/providers/local-source/entities.mjs.map +1 -0
- package/dist/strapi/providers/local-source/index.js +154 -0
- package/dist/strapi/providers/local-source/index.js.map +1 -0
- package/dist/strapi/providers/local-source/index.mjs +152 -0
- package/dist/strapi/providers/local-source/index.mjs.map +1 -0
- package/dist/strapi/providers/local-source/links.js +26 -0
- package/dist/strapi/providers/local-source/links.js.map +1 -0
- package/dist/strapi/providers/local-source/links.mjs +24 -0
- package/dist/strapi/providers/local-source/links.mjs.map +1 -0
- package/dist/strapi/providers/remote-destination/index.js +392 -0
- package/dist/strapi/providers/remote-destination/index.js.map +1 -0
- package/dist/strapi/providers/remote-destination/index.mjs +390 -0
- package/dist/strapi/providers/remote-destination/index.mjs.map +1 -0
- package/dist/strapi/providers/remote-source/index.js +405 -0
- package/dist/strapi/providers/remote-source/index.js.map +1 -0
- package/dist/strapi/providers/remote-source/index.mjs +403 -0
- package/dist/strapi/providers/remote-source/index.mjs.map +1 -0
- package/dist/strapi/providers/utils.js +173 -0
- package/dist/strapi/providers/utils.js.map +1 -0
- package/dist/strapi/providers/utils.mjs +169 -0
- package/dist/strapi/providers/utils.mjs.map +1 -0
- package/dist/strapi/queries/entity.js +125 -0
- package/dist/strapi/queries/entity.js.map +1 -0
- package/dist/strapi/queries/entity.mjs +123 -0
- package/dist/strapi/queries/entity.mjs.map +1 -0
- package/dist/strapi/queries/index.js +10 -0
- package/dist/strapi/queries/index.js.map +1 -0
- package/dist/strapi/queries/index.mjs +5 -0
- package/dist/strapi/queries/index.mjs.map +1 -0
- package/dist/strapi/queries/link.js +298 -0
- package/dist/strapi/queries/link.js.map +1 -0
- package/dist/strapi/queries/link.mjs +295 -0
- package/dist/strapi/queries/link.mjs.map +1 -0
- package/dist/strapi/remote/constants.js +11 -0
- package/dist/strapi/remote/constants.js.map +1 -0
- package/dist/strapi/remote/constants.mjs +8 -0
- package/dist/strapi/remote/constants.mjs.map +1 -0
- package/dist/strapi/remote/flows/default.js +43 -0
- package/dist/strapi/remote/flows/default.js.map +1 -0
- package/dist/strapi/remote/flows/default.mjs +41 -0
- package/dist/strapi/remote/flows/default.mjs.map +1 -0
- package/dist/strapi/remote/flows/index.js +54 -0
- package/dist/strapi/remote/flows/index.js.map +1 -0
- package/dist/strapi/remote/flows/index.mjs +52 -0
- package/dist/strapi/remote/flows/index.mjs.map +1 -0
- package/dist/strapi/remote/handlers/constants.js +10 -0
- package/dist/strapi/remote/handlers/constants.js.map +1 -0
- package/dist/strapi/remote/handlers/constants.mjs +8 -0
- package/dist/strapi/remote/handlers/constants.mjs.map +1 -0
- package/dist/strapi/remote/handlers/index.js +12 -0
- package/dist/strapi/remote/handlers/index.js.map +1 -0
- package/dist/strapi/remote/handlers/index.mjs +4 -0
- package/dist/strapi/remote/handlers/index.mjs.map +1 -0
- package/dist/strapi/remote/handlers/pull.js +348 -0
- package/dist/strapi/remote/handlers/pull.js.map +1 -0
- package/dist/strapi/remote/handlers/pull.mjs +346 -0
- package/dist/strapi/remote/handlers/pull.mjs.map +1 -0
- package/dist/strapi/remote/handlers/push.js +400 -0
- package/dist/strapi/remote/handlers/push.js.map +1 -0
- package/dist/strapi/remote/handlers/push.mjs +398 -0
- package/dist/strapi/remote/handlers/push.mjs.map +1 -0
- package/dist/strapi/remote/handlers/utils.js +316 -0
- package/dist/strapi/remote/handlers/utils.js.map +1 -0
- package/dist/strapi/remote/handlers/utils.mjs +310 -0
- package/dist/strapi/remote/handlers/utils.mjs.map +1 -0
- package/dist/strapi/remote/index.js +10 -0
- package/dist/strapi/remote/index.js.map +1 -0
- package/dist/strapi/remote/index.mjs +5 -0
- package/dist/strapi/remote/index.mjs.map +1 -0
- package/dist/utils/components.js +178 -0
- package/dist/utils/components.js.map +1 -0
- package/dist/utils/components.mjs +171 -0
- package/dist/utils/components.mjs.map +1 -0
- package/dist/utils/diagnostic.js +51 -0
- package/dist/utils/diagnostic.js.map +1 -0
- package/dist/utils/diagnostic.mjs +49 -0
- package/dist/utils/diagnostic.mjs.map +1 -0
- package/dist/utils/encryption/decrypt.js +47 -0
- package/dist/utils/encryption/decrypt.js.map +1 -0
- package/dist/utils/encryption/decrypt.mjs +45 -0
- package/dist/utils/encryption/decrypt.mjs.map +1 -0
- package/dist/utils/encryption/encrypt.js +47 -0
- package/dist/utils/encryption/encrypt.js.map +1 -0
- package/dist/utils/encryption/encrypt.mjs +45 -0
- package/dist/utils/encryption/encrypt.mjs.map +1 -0
- package/dist/utils/encryption/index.js +10 -0
- package/dist/utils/encryption/index.js.map +1 -0
- package/dist/utils/encryption/index.mjs +3 -0
- package/dist/utils/encryption/index.mjs.map +1 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +15 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils/json.js +96 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/json.mjs +94 -0
- package/dist/utils/json.mjs.map +1 -0
- package/dist/utils/middleware.js +14 -0
- package/dist/utils/middleware.js.map +1 -0
- package/dist/utils/middleware.mjs +12 -0
- package/dist/utils/middleware.mjs.map +1 -0
- package/dist/utils/providers.js +12 -0
- package/dist/utils/providers.js.map +1 -0
- package/dist/utils/providers.mjs +10 -0
- package/dist/utils/providers.mjs.map +1 -0
- package/dist/utils/schema.js +32 -0
- package/dist/utils/schema.js.map +1 -0
- package/dist/utils/schema.mjs +29 -0
- package/dist/utils/schema.mjs.map +1 -0
- package/dist/utils/stream.js +59 -0
- package/dist/utils/stream.js.map +1 -0
- package/dist/utils/stream.mjs +55 -0
- package/dist/utils/stream.mjs.map +1 -0
- package/dist/utils/transaction.js +93 -0
- package/dist/utils/transaction.js.map +1 -0
- package/dist/utils/transaction.mjs +91 -0
- package/dist/utils/transaction.mjs.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var stream = require('stream');
|
|
4
|
+
var crypto = require('crypto');
|
|
5
|
+
var utils = require('./utils.js');
|
|
6
|
+
require('path');
|
|
7
|
+
require('fs-extra');
|
|
8
|
+
var providers = require('../../../errors/providers.js');
|
|
9
|
+
require('../../queries/entity.js');
|
|
10
|
+
require('lodash/fp');
|
|
11
|
+
require('events');
|
|
12
|
+
require('lodash');
|
|
13
|
+
require('@strapi/utils');
|
|
14
|
+
require('../../providers/local-destination/strategies/restore/configuration.js');
|
|
15
|
+
var index = require('../../providers/local-source/index.js');
|
|
16
|
+
require('ws');
|
|
17
|
+
|
|
18
|
+
const TRANSFER_KIND = 'pull';
|
|
19
|
+
const VALID_TRANSFER_ACTIONS = [
|
|
20
|
+
'bootstrap',
|
|
21
|
+
'close',
|
|
22
|
+
'getMetadata',
|
|
23
|
+
'getSchemas'
|
|
24
|
+
];
|
|
25
|
+
const createPullController = utils.handlerControllerFactory((proto)=>({
|
|
26
|
+
isTransferStarted () {
|
|
27
|
+
return proto.isTransferStarted.call(this) && this.provider !== undefined;
|
|
28
|
+
},
|
|
29
|
+
verifyAuth () {
|
|
30
|
+
return proto.verifyAuth.call(this, TRANSFER_KIND);
|
|
31
|
+
},
|
|
32
|
+
cleanup () {
|
|
33
|
+
proto.cleanup.call(this);
|
|
34
|
+
this.streams = {};
|
|
35
|
+
delete this.provider;
|
|
36
|
+
},
|
|
37
|
+
onInfo (message) {
|
|
38
|
+
this.diagnostics?.report({
|
|
39
|
+
details: {
|
|
40
|
+
message,
|
|
41
|
+
origin: 'pull-handler',
|
|
42
|
+
createdAt: new Date()
|
|
43
|
+
},
|
|
44
|
+
kind: 'info'
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
onWarning (message) {
|
|
48
|
+
this.diagnostics?.report({
|
|
49
|
+
details: {
|
|
50
|
+
message,
|
|
51
|
+
createdAt: new Date(),
|
|
52
|
+
origin: 'pull-handler'
|
|
53
|
+
},
|
|
54
|
+
kind: 'warning'
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
onError (error) {
|
|
58
|
+
this.diagnostics?.report({
|
|
59
|
+
details: {
|
|
60
|
+
message: error.message,
|
|
61
|
+
error,
|
|
62
|
+
createdAt: new Date(),
|
|
63
|
+
name: error.name,
|
|
64
|
+
severity: 'fatal'
|
|
65
|
+
},
|
|
66
|
+
kind: 'error'
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
assertValidTransferAction (action) {
|
|
70
|
+
// Abstract the constant to string[] to allow looser check on the given action
|
|
71
|
+
const validActions = VALID_TRANSFER_ACTIONS;
|
|
72
|
+
if (validActions.includes(action)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
throw new providers.ProviderTransferError(`Invalid action provided: "${action}"`, {
|
|
76
|
+
action,
|
|
77
|
+
validActions: Object.keys(VALID_TRANSFER_ACTIONS)
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
async onMessage (raw) {
|
|
81
|
+
const msg = JSON.parse(raw.toString());
|
|
82
|
+
if (!utils.isDataTransferMessage(msg)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!msg.uuid) {
|
|
86
|
+
await this.respond(undefined, new Error('Missing uuid in message'));
|
|
87
|
+
}
|
|
88
|
+
if (proto.hasUUID(msg.uuid)) {
|
|
89
|
+
const previousResponse = proto.response;
|
|
90
|
+
if (previousResponse?.uuid === msg.uuid) {
|
|
91
|
+
await this.respond(previousResponse?.uuid, previousResponse.e, previousResponse.data);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const { uuid, type } = msg;
|
|
96
|
+
proto.addUUID(uuid);
|
|
97
|
+
// Regular command message (init, end, status)
|
|
98
|
+
if (type === 'command') {
|
|
99
|
+
const { command } = msg;
|
|
100
|
+
this.onInfo(`received command:${command} uuid:${uuid}`);
|
|
101
|
+
await this.executeAndRespond(uuid, ()=>{
|
|
102
|
+
this.assertValidTransferCommand(command);
|
|
103
|
+
// The status command don't have params
|
|
104
|
+
if (command === 'status') {
|
|
105
|
+
return this.status();
|
|
106
|
+
}
|
|
107
|
+
return this[command](msg.params);
|
|
108
|
+
});
|
|
109
|
+
} else if (type === 'transfer') {
|
|
110
|
+
this.onInfo(`received transfer action:${msg.action} step:${msg.kind} uuid:${uuid}`);
|
|
111
|
+
await this.executeAndRespond(uuid, async ()=>{
|
|
112
|
+
await this.verifyAuth();
|
|
113
|
+
this.assertValidTransfer();
|
|
114
|
+
return this.onTransferMessage(msg);
|
|
115
|
+
});
|
|
116
|
+
} else {
|
|
117
|
+
await this.respond(uuid, new Error('Bad Request'));
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
async onTransferMessage (msg) {
|
|
121
|
+
const { kind } = msg;
|
|
122
|
+
if (kind === 'action') {
|
|
123
|
+
return this.onTransferAction(msg);
|
|
124
|
+
}
|
|
125
|
+
if (kind === 'step') {
|
|
126
|
+
return this.onTransferStep(msg);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
async onTransferAction (msg) {
|
|
130
|
+
const { action } = msg;
|
|
131
|
+
this.assertValidTransferAction(action);
|
|
132
|
+
if (action === 'bootstrap') {
|
|
133
|
+
return this.provider?.[action](this.diagnostics);
|
|
134
|
+
}
|
|
135
|
+
return this.provider?.[action]();
|
|
136
|
+
},
|
|
137
|
+
async flush (stage, id) {
|
|
138
|
+
const batchSize = 1024 * 1024;
|
|
139
|
+
let batch = [];
|
|
140
|
+
const stream = this.streams?.[stage];
|
|
141
|
+
const batchLength = ()=>Buffer.byteLength(JSON.stringify(batch));
|
|
142
|
+
const maybeConfirm = async (data)=>{
|
|
143
|
+
try {
|
|
144
|
+
await this.confirm(data);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
// Handle the error, log it, or take other appropriate actions
|
|
147
|
+
strapi?.log.error(`[Data transfer] Message confirmation failed: ${error?.message}`);
|
|
148
|
+
this.onError(error);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
const sendBatch = async ()=>{
|
|
152
|
+
await this.confirm({
|
|
153
|
+
type: 'transfer',
|
|
154
|
+
data: batch,
|
|
155
|
+
ended: false,
|
|
156
|
+
error: null,
|
|
157
|
+
id
|
|
158
|
+
});
|
|
159
|
+
batch = [];
|
|
160
|
+
};
|
|
161
|
+
if (!stream) {
|
|
162
|
+
throw new providers.ProviderTransferError(`No available stream found for ${stage}`);
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
for await (const chunk of stream){
|
|
166
|
+
if (stage !== 'assets') {
|
|
167
|
+
batch.push(chunk);
|
|
168
|
+
if (batchLength() >= batchSize) {
|
|
169
|
+
await sendBatch();
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
await this.confirm({
|
|
173
|
+
type: 'transfer',
|
|
174
|
+
data: [
|
|
175
|
+
chunk
|
|
176
|
+
],
|
|
177
|
+
ended: false,
|
|
178
|
+
error: null,
|
|
179
|
+
id
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (batch.length > 0 && stage !== 'assets') {
|
|
184
|
+
await sendBatch();
|
|
185
|
+
}
|
|
186
|
+
await this.confirm({
|
|
187
|
+
type: 'transfer',
|
|
188
|
+
data: null,
|
|
189
|
+
ended: true,
|
|
190
|
+
error: null,
|
|
191
|
+
id
|
|
192
|
+
});
|
|
193
|
+
} catch (e) {
|
|
194
|
+
// TODO: if this confirm fails, can we abort the whole transfer?
|
|
195
|
+
await maybeConfirm({
|
|
196
|
+
type: 'transfer',
|
|
197
|
+
data: null,
|
|
198
|
+
ended: true,
|
|
199
|
+
error: e,
|
|
200
|
+
id
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
async onTransferStep (msg) {
|
|
205
|
+
const { step, action } = msg;
|
|
206
|
+
if (action === 'start') {
|
|
207
|
+
if (this.streams?.[step] instanceof stream.Readable) {
|
|
208
|
+
throw new Error('Stream already created, something went wrong');
|
|
209
|
+
}
|
|
210
|
+
const flushUUID = crypto.randomUUID();
|
|
211
|
+
await this.createReadableStreamForStep(step);
|
|
212
|
+
this.flush(step, flushUUID);
|
|
213
|
+
return {
|
|
214
|
+
ok: true,
|
|
215
|
+
id: flushUUID
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
if (action === 'end') {
|
|
219
|
+
const stream = this.streams?.[step];
|
|
220
|
+
if (stream?.readableEnded === false) {
|
|
221
|
+
await new Promise((resolve)=>{
|
|
222
|
+
stream?.on('close', resolve).destroy();
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
delete this.streams?.[step];
|
|
226
|
+
return {
|
|
227
|
+
ok: true
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
async createReadableStreamForStep (step) {
|
|
232
|
+
const mapper = {
|
|
233
|
+
entities: ()=>this.provider?.createEntitiesReadStream(),
|
|
234
|
+
links: ()=>this.provider?.createLinksReadStream(),
|
|
235
|
+
configuration: ()=>this.provider?.createConfigurationReadStream(),
|
|
236
|
+
assets: ()=>{
|
|
237
|
+
const assets = this.provider?.createAssetsReadStream();
|
|
238
|
+
let batch = [];
|
|
239
|
+
const batchLength = ()=>{
|
|
240
|
+
return batch.reduce((acc, chunk)=>chunk.action === 'stream' ? acc + chunk.data.byteLength : acc, 0);
|
|
241
|
+
};
|
|
242
|
+
const BATCH_MAX_SIZE = 1024 * 1024; // 1MB
|
|
243
|
+
if (!assets) {
|
|
244
|
+
throw new Error('Assets read stream could not be created');
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Generates batches of 1MB of data from the assets stream to avoid
|
|
248
|
+
* sending too many small chunks
|
|
249
|
+
*
|
|
250
|
+
* @param stream Assets stream from the local source provider
|
|
251
|
+
*/ async function* generator(stream) {
|
|
252
|
+
let hasStarted = false;
|
|
253
|
+
let assetID = '';
|
|
254
|
+
for await (const chunk of stream){
|
|
255
|
+
const { stream: assetStream, ...assetData } = chunk;
|
|
256
|
+
if (!hasStarted) {
|
|
257
|
+
assetID = crypto.randomUUID();
|
|
258
|
+
// Start the transfer of a new asset
|
|
259
|
+
batch.push({
|
|
260
|
+
action: 'start',
|
|
261
|
+
assetID,
|
|
262
|
+
data: assetData
|
|
263
|
+
});
|
|
264
|
+
hasStarted = true;
|
|
265
|
+
}
|
|
266
|
+
for await (const assetChunk of assetStream){
|
|
267
|
+
// Add the asset data to the batch
|
|
268
|
+
batch.push({
|
|
269
|
+
action: 'stream',
|
|
270
|
+
assetID,
|
|
271
|
+
data: assetChunk
|
|
272
|
+
});
|
|
273
|
+
// if the batch size is bigger than BATCH_MAX_SIZE stream the batch
|
|
274
|
+
if (batchLength() >= BATCH_MAX_SIZE) {
|
|
275
|
+
yield batch;
|
|
276
|
+
batch = [];
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// All the asset data has been streamed and gets ready for the next one
|
|
280
|
+
hasStarted = false;
|
|
281
|
+
batch.push({
|
|
282
|
+
action: 'end',
|
|
283
|
+
assetID
|
|
284
|
+
});
|
|
285
|
+
yield batch;
|
|
286
|
+
batch = [];
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return stream.Readable.from(generator(assets));
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
if (!(step in mapper)) {
|
|
293
|
+
throw new Error('Invalid transfer step, impossible to create a stream');
|
|
294
|
+
}
|
|
295
|
+
if (!this.streams) {
|
|
296
|
+
throw new Error('Invalid transfer state');
|
|
297
|
+
}
|
|
298
|
+
this.streams[step] = await mapper[step]();
|
|
299
|
+
},
|
|
300
|
+
// Commands
|
|
301
|
+
async init () {
|
|
302
|
+
if (this.transferID || this.provider) {
|
|
303
|
+
throw new Error('Transfer already in progress');
|
|
304
|
+
}
|
|
305
|
+
await this.verifyAuth();
|
|
306
|
+
this.transferID = crypto.randomUUID();
|
|
307
|
+
this.startedAt = Date.now();
|
|
308
|
+
this.streams = {};
|
|
309
|
+
this.provider = index.createLocalStrapiSourceProvider({
|
|
310
|
+
autoDestroy: false,
|
|
311
|
+
getStrapi: ()=>strapi
|
|
312
|
+
});
|
|
313
|
+
return {
|
|
314
|
+
transferID: this.transferID
|
|
315
|
+
};
|
|
316
|
+
},
|
|
317
|
+
async end (params) {
|
|
318
|
+
await this.verifyAuth();
|
|
319
|
+
if (this.transferID !== params?.transferID) {
|
|
320
|
+
throw new providers.ProviderTransferError('Bad transfer ID provided');
|
|
321
|
+
}
|
|
322
|
+
this.cleanup();
|
|
323
|
+
return {
|
|
324
|
+
ok: true
|
|
325
|
+
};
|
|
326
|
+
},
|
|
327
|
+
async status () {
|
|
328
|
+
const isStarted = this.isTransferStarted();
|
|
329
|
+
if (!isStarted) {
|
|
330
|
+
const startedAt = this.startedAt;
|
|
331
|
+
return {
|
|
332
|
+
active: true,
|
|
333
|
+
kind: TRANSFER_KIND,
|
|
334
|
+
startedAt,
|
|
335
|
+
elapsed: Date.now() - startedAt
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
active: false,
|
|
340
|
+
kind: null,
|
|
341
|
+
elapsed: null,
|
|
342
|
+
startedAt: null
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}));
|
|
346
|
+
|
|
347
|
+
exports.createPullController = createPullController;
|
|
348
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","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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"}
|