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