@strapi/data-transfer 4.8.2 → 4.9.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/lib/engine/index.d.ts +1 -0
  2. package/lib/engine/index.js +30 -4
  3. package/lib/strapi/providers/index.d.ts +1 -0
  4. package/lib/strapi/providers/index.js +1 -0
  5. package/lib/strapi/providers/remote-destination/index.d.ts +1 -1
  6. package/lib/strapi/providers/remote-destination/index.js +3 -3
  7. package/lib/strapi/providers/remote-source/index.d.ts +36 -0
  8. package/lib/strapi/providers/remote-source/index.js +228 -0
  9. package/lib/strapi/providers/{remote-destination/utils.d.ts → utils.d.ts} +3 -3
  10. package/lib/strapi/providers/{remote-destination/utils.js → utils.js} +1 -1
  11. package/lib/strapi/remote/constants.d.ts +3 -1
  12. package/lib/strapi/remote/constants.js +1 -1
  13. package/lib/strapi/remote/flows/index.d.ts +4 -4
  14. package/lib/strapi/remote/handlers/abstract.d.ts +62 -0
  15. package/lib/strapi/remote/handlers/abstract.js +3 -0
  16. package/lib/strapi/remote/handlers/constants.d.ts +2 -0
  17. package/lib/strapi/remote/handlers/constants.js +5 -0
  18. package/lib/strapi/remote/handlers/index.d.ts +3 -0
  19. package/lib/strapi/remote/handlers/index.js +10 -0
  20. package/lib/strapi/remote/handlers/pull.d.ts +22 -0
  21. package/lib/strapi/remote/handlers/pull.js +186 -0
  22. package/lib/strapi/remote/handlers/push.d.ts +75 -0
  23. package/lib/strapi/remote/handlers/push.js +297 -0
  24. package/lib/strapi/remote/handlers/utils.d.ts +25 -0
  25. package/lib/strapi/remote/handlers/utils.js +181 -0
  26. package/lib/strapi/remote/index.d.ts +0 -1
  27. package/lib/strapi/remote/index.js +1 -2
  28. package/package.json +4 -4
  29. package/lib/strapi/remote/controllers/index.d.ts +0 -1
  30. package/lib/strapi/remote/controllers/index.js +0 -18
  31. package/lib/strapi/remote/controllers/push.d.ts +0 -26
  32. package/lib/strapi/remote/controllers/push.js +0 -116
  33. package/lib/strapi/remote/handlers.d.ts +0 -10
  34. package/lib/strapi/remote/handlers.js +0 -285
@@ -22,6 +22,7 @@ declare class TransferEngine<S extends ISourceProvider = ISourceProvider, D exte
22
22
  diagnostics: IDiagnosticReporter;
23
23
  constructor(sourceProvider: S, destinationProvider: D, options: ITransferEngineOptions);
24
24
  shouldSkipStage(stage: TransferStage): boolean;
25
+ abortTransfer(): Promise<void>;
25
26
  init(): Promise<void>;
26
27
  /**
27
28
  * Run the bootstrap method in both source and destination providers
@@ -27,7 +27,13 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
27
27
  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");
28
28
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
29
29
  };
30
- var _TransferEngine_instances, _TransferEngine_metadata, _TransferEngine_panic, _TransferEngine_reportError, _TransferEngine_reportWarning, _TransferEngine_reportInfo, _TransferEngine_createStageTransformStream, _TransferEngine_updateTransferProgress, _TransferEngine_progressTracker, _TransferEngine_emitTransferUpdate, _TransferEngine_emitStageUpdate, _TransferEngine_assertStrapiVersionIntegrity, _TransferEngine_assertSchemasMatching, _TransferEngine_transferStage, _TransferEngine_resolveProviderResource;
30
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
31
+ if (kind === "m") throw new TypeError("Private method is not writable");
32
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
33
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
34
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
35
+ };
36
+ var _TransferEngine_instances, _TransferEngine_metadata, _TransferEngine_currentStream, _TransferEngine_panic, _TransferEngine_reportError, _TransferEngine_reportWarning, _TransferEngine_reportInfo, _TransferEngine_createStageTransformStream, _TransferEngine_updateTransferProgress, _TransferEngine_progressTracker, _TransferEngine_emitTransferUpdate, _TransferEngine_emitStageUpdate, _TransferEngine_assertStrapiVersionIntegrity, _TransferEngine_assertSchemasMatching, _TransferEngine_transferStage, _TransferEngine_resolveProviderResource;
31
37
  Object.defineProperty(exports, "__esModule", { value: true });
32
38
  exports.errors = exports.createTransferEngine = exports.DEFAULT_SCHEMA_STRATEGY = exports.DEFAULT_VERSION_STRATEGY = exports.TransferGroupPresets = exports.TRANSFER_STAGES = void 0;
33
39
  const stream_1 = require("stream");
@@ -77,6 +83,8 @@ class TransferEngine {
77
83
  constructor(sourceProvider, destinationProvider, options) {
78
84
  _TransferEngine_instances.add(this);
79
85
  _TransferEngine_metadata.set(this, {});
86
+ // Save the currently open stream so that we can access it at any time
87
+ _TransferEngine_currentStream.set(this, void 0);
80
88
  this.diagnostics = (0, diagnostic_1.createDiagnosticReporter)();
81
89
  (0, validation_1.validateProvider)('source', sourceProvider);
82
90
  (0, validation_1.validateProvider)('destination', destinationProvider);
@@ -107,6 +115,10 @@ class TransferEngine {
107
115
  }
108
116
  return !included;
109
117
  }
118
+ // Cause an ongoing transfer to abort gracefully
119
+ async abortTransfer() {
120
+ __classPrivateFieldGet(this, _TransferEngine_currentStream, "f")?.destroy(new errors_1.TransferEngineError('fatal', 'Transfer aborted.'));
121
+ }
110
122
  async init() {
111
123
  // Resolve providers' resource and store
112
124
  // them in the engine's internal state
@@ -266,7 +278,7 @@ class TransferEngine {
266
278
  await __classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_transferStage).call(this, { stage, source, destination, transform, tracker });
267
279
  }
268
280
  }
269
- _TransferEngine_metadata = new WeakMap(), _TransferEngine_instances = new WeakSet(), _TransferEngine_panic = function _TransferEngine_panic(error) {
281
+ _TransferEngine_metadata = new WeakMap(), _TransferEngine_currentStream = new WeakMap(), _TransferEngine_instances = new WeakSet(), _TransferEngine_panic = function _TransferEngine_panic(error) {
270
282
  __classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_reportError).call(this, error, 'fatal');
271
283
  throw error;
272
284
  }, _TransferEngine_reportError = function _TransferEngine_reportError(error, severity) {
@@ -292,6 +304,7 @@ _TransferEngine_metadata = new WeakMap(), _TransferEngine_instances = new WeakSe
292
304
  });
293
305
  }, _TransferEngine_createStageTransformStream = function _TransferEngine_createStageTransformStream(key, options = {}) {
294
306
  const { includeGlobal = true } = options;
307
+ const { throttle } = this.options;
295
308
  const { global: globalTransforms, [key]: stageTransforms } = this.options?.transforms ?? {};
296
309
  let stream = new stream_1.PassThrough({ objectMode: true });
297
310
  const applyTransforms = (transforms = []) => {
@@ -307,6 +320,17 @@ _TransferEngine_metadata = new WeakMap(), _TransferEngine_instances = new WeakSe
307
320
  if (includeGlobal) {
308
321
  applyTransforms(globalTransforms);
309
322
  }
323
+ if ((0, fp_1.isNumber)(throttle) && throttle > 0) {
324
+ stream = stream.pipe(new stream_1.PassThrough({
325
+ objectMode: true,
326
+ async transform(data, _encoding, callback) {
327
+ await new Promise((resolve) => {
328
+ setTimeout(resolve, throttle);
329
+ });
330
+ callback(null, data);
331
+ },
332
+ }));
333
+ }
310
334
  applyTransforms(stageTransforms);
311
335
  return stream;
312
336
  }, _TransferEngine_updateTransferProgress = function _TransferEngine_updateTransferProgress(stage, data, aggregate) {
@@ -474,18 +498,20 @@ _TransferEngine_metadata = new WeakMap(), _TransferEngine_instances = new WeakSe
474
498
  if (tracker) {
475
499
  stream = stream.pipe(tracker);
476
500
  }
477
- stream
501
+ __classPrivateFieldSet(this, _TransferEngine_currentStream, stream
478
502
  .pipe(destination)
479
503
  .on('error', (e) => {
480
504
  updateEndTime();
505
+ __classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_emitStageUpdate).call(this, 'error', stage);
481
506
  __classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_reportError).call(this, e, 'error');
482
507
  destination.destroy(e);
483
508
  reject(e);
484
509
  })
485
510
  .on('close', () => {
511
+ __classPrivateFieldSet(this, _TransferEngine_currentStream, undefined, "f");
486
512
  updateEndTime();
487
513
  resolve();
488
- });
514
+ }), "f");
489
515
  });
490
516
  __classPrivateFieldGet(this, _TransferEngine_instances, "m", _TransferEngine_emitStageUpdate).call(this, 'finish', stage);
491
517
  }, _TransferEngine_resolveProviderResource = async function _TransferEngine_resolveProviderResource() {
@@ -1,3 +1,4 @@
1
1
  export * from './local-destination';
2
2
  export * from './local-source';
3
3
  export * from './remote-destination';
4
+ export * from './remote-source';
@@ -19,4 +19,5 @@ __exportStar(require("./local-destination"), exports);
19
19
  __exportStar(require("./local-source"), exports);
20
20
  // Remote
21
21
  __exportStar(require("./remote-destination"), exports);
22
+ __exportStar(require("./remote-source"), exports);
22
23
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { WebSocket } from 'ws';
3
3
  import { Writable } from 'stream';
4
- import { createDispatcher } from './utils';
4
+ import { createDispatcher } from '../utils';
5
5
  import type { IDestinationProvider, IMetadata, ProviderType } from '../../../../types';
6
6
  import type { ILocalStrapiDestinationProviderOptions } from '../local-destination';
7
7
  interface ITransferTokenAuth {
@@ -11,7 +11,7 @@ const ws_1 = require("ws");
11
11
  const uuid_1 = require("uuid");
12
12
  const stream_1 = require("stream");
13
13
  const fp_1 = require("lodash/fp");
14
- const utils_1 = require("./utils");
14
+ const utils_1 = require("../utils");
15
15
  const constants_1 = require("../../remote/constants");
16
16
  const providers_1 = require("../../../errors/providers");
17
17
  const jsonLength = (obj) => Buffer.byteLength(JSON.stringify(obj));
@@ -34,7 +34,7 @@ class RemoteStrapiDestinationProvider {
34
34
  try {
35
35
  const query = this.dispatcher?.dispatchCommand({
36
36
  command: 'init',
37
- params: { options: { strategy, restore }, transfer: 'push' },
37
+ params: { strategy, restore },
38
38
  });
39
39
  const res = (await query);
40
40
  if (!res?.transferID) {
@@ -65,7 +65,7 @@ class RemoteStrapiDestinationProvider {
65
65
  });
66
66
  }
67
67
  const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
68
- const wsUrl = `${wsProtocol}//${url.host}${url.pathname}${constants_1.TRANSFER_PATH}`;
68
+ const wsUrl = `${wsProtocol}//${url.host}${url.pathname}${constants_1.TRANSFER_PATH}/push`;
69
69
  // No auth defined, trying public access for transfer
70
70
  if (!auth) {
71
71
  ws = new ws_1.WebSocket(wsUrl);
@@ -0,0 +1,36 @@
1
+ /// <reference types="node" />
2
+ import { Readable } from 'stream';
3
+ import { WebSocket } from 'ws';
4
+ import type { IMetadata, ISourceProvider, ISourceProviderTransferResults, MaybePromise, ProviderType } from '../../../../types';
5
+ import { ILocalStrapiSourceProviderOptions } from '../local-source';
6
+ import { createDispatcher } from '../utils';
7
+ interface ITransferTokenAuth {
8
+ type: 'token';
9
+ token: string;
10
+ }
11
+ export interface IRemoteStrapiSourceProviderOptions extends ILocalStrapiSourceProviderOptions {
12
+ url: URL;
13
+ auth?: ITransferTokenAuth;
14
+ }
15
+ declare class RemoteStrapiSourceProvider implements ISourceProvider {
16
+ #private;
17
+ name: string;
18
+ type: ProviderType;
19
+ options: IRemoteStrapiSourceProviderOptions;
20
+ ws: WebSocket | null;
21
+ dispatcher: ReturnType<typeof createDispatcher> | null;
22
+ constructor(options: IRemoteStrapiSourceProviderOptions);
23
+ results?: ISourceProviderTransferResults | undefined;
24
+ createEntitiesReadStream(): MaybePromise<Readable>;
25
+ createLinksReadStream(): MaybePromise<Readable>;
26
+ createAssetsReadStream(): Promise<Readable>;
27
+ createConfigurationReadStream(): MaybePromise<Readable>;
28
+ getMetadata(): Promise<IMetadata | null>;
29
+ assertValidProtocol(url: URL): void;
30
+ initTransfer(): Promise<string>;
31
+ bootstrap(): Promise<void>;
32
+ close(): Promise<void>;
33
+ getSchemas(): Promise<Strapi.Schemas | null>;
34
+ }
35
+ export declare const createRemoteStrapiSourceProvider: (options: IRemoteStrapiSourceProviderOptions) => RemoteStrapiSourceProvider;
36
+ export {};
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _RemoteStrapiSourceProvider_instances, _RemoteStrapiSourceProvider_createStageReadStream, _RemoteStrapiSourceProvider_startStep, _RemoteStrapiSourceProvider_respond, _RemoteStrapiSourceProvider_endStep;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createRemoteStrapiSourceProvider = void 0;
10
+ const stream_1 = require("stream");
11
+ const ws_1 = require("ws");
12
+ const providers_1 = require("../../../errors/providers");
13
+ const constants_1 = require("../../remote/constants");
14
+ const utils_1 = require("../utils");
15
+ class RemoteStrapiSourceProvider {
16
+ constructor(options) {
17
+ _RemoteStrapiSourceProvider_instances.add(this);
18
+ this.name = 'source::remote-strapi';
19
+ this.type = 'source';
20
+ this.options = options;
21
+ this.ws = null;
22
+ this.dispatcher = null;
23
+ }
24
+ createEntitiesReadStream() {
25
+ return __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_createStageReadStream).call(this, 'entities');
26
+ }
27
+ createLinksReadStream() {
28
+ return __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_createStageReadStream).call(this, 'links');
29
+ }
30
+ async createAssetsReadStream() {
31
+ const assets = {};
32
+ const stream = await __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_createStageReadStream).call(this, 'assets');
33
+ const pass = new stream_1.PassThrough({ objectMode: true });
34
+ stream
35
+ .on('data', (asset) => {
36
+ const { chunk, ...rest } = asset;
37
+ if (!(asset.filename in assets)) {
38
+ const assetStream = new stream_1.PassThrough();
39
+ assets[asset.filename] = assetStream;
40
+ pass.push({ ...rest, stream: assetStream });
41
+ }
42
+ if (asset.filename in assets) {
43
+ // The buffer has gone through JSON operations and is now of shape { type: "Buffer"; data: UInt8Array }
44
+ // We need to transform it back into a Buffer instance
45
+ assets[asset.filename].push(Buffer.from(chunk.data));
46
+ }
47
+ })
48
+ .on('end', () => {
49
+ Object.values(assets).forEach((s) => {
50
+ s.push(null);
51
+ });
52
+ })
53
+ .on('close', () => {
54
+ pass.end();
55
+ });
56
+ return pass;
57
+ }
58
+ createConfigurationReadStream() {
59
+ return __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_createStageReadStream).call(this, 'configuration');
60
+ }
61
+ async getMetadata() {
62
+ const metadata = await this.dispatcher?.dispatchTransferAction('getMetadata');
63
+ return metadata ?? null;
64
+ }
65
+ assertValidProtocol(url) {
66
+ const validProtocols = ['https:', 'http:'];
67
+ if (!validProtocols.includes(url.protocol)) {
68
+ throw new providers_1.ProviderValidationError(`Invalid protocol "${url.protocol}"`, {
69
+ check: 'url',
70
+ details: {
71
+ protocol: url.protocol,
72
+ validProtocols,
73
+ },
74
+ });
75
+ }
76
+ }
77
+ async initTransfer() {
78
+ return new Promise((resolve, reject) => {
79
+ this.ws
80
+ ?.on('unexpected-response', (_req, res) => {
81
+ if (res.statusCode === 401) {
82
+ return reject(new providers_1.ProviderInitializationError('Failed to initialize the connexion: Authentication Error'));
83
+ }
84
+ if (res.statusCode === 403) {
85
+ return reject(new providers_1.ProviderInitializationError('Failed to initialize the connexion: Authorization Error'));
86
+ }
87
+ if (res.statusCode === 404) {
88
+ return reject(new providers_1.ProviderInitializationError('Failed to initialize the connexion: Data transfer is not enabled on the remote host'));
89
+ }
90
+ return reject(new providers_1.ProviderInitializationError(`Failed to initialize the connexion: Unexpected server response ${res.statusCode}`));
91
+ })
92
+ ?.once('open', async () => {
93
+ const query = this.dispatcher?.dispatchCommand({
94
+ command: 'init',
95
+ });
96
+ const res = (await query);
97
+ if (!res?.transferID) {
98
+ return reject(new providers_1.ProviderTransferError('Init failed, invalid response from the server'));
99
+ }
100
+ resolve(res.transferID);
101
+ })
102
+ .once('error', reject);
103
+ });
104
+ }
105
+ async bootstrap() {
106
+ const { url, auth } = this.options;
107
+ let ws;
108
+ this.assertValidProtocol(url);
109
+ const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
110
+ const wsUrl = `${wsProtocol}//${url.host}${url.pathname}${constants_1.TRANSFER_PATH}/pull`;
111
+ // No auth defined, trying public access for transfer
112
+ if (!auth) {
113
+ ws = new ws_1.WebSocket(wsUrl);
114
+ }
115
+ // Common token auth, this should be the main auth method
116
+ else if (auth.type === 'token') {
117
+ const headers = { Authorization: `Bearer ${auth.token}` };
118
+ ws = new ws_1.WebSocket(wsUrl, { headers });
119
+ }
120
+ // Invalid auth method provided
121
+ else {
122
+ throw new providers_1.ProviderValidationError('Auth method not available', {
123
+ check: 'auth.type',
124
+ details: {
125
+ auth: auth.type,
126
+ },
127
+ });
128
+ }
129
+ this.ws = ws;
130
+ this.dispatcher = (0, utils_1.createDispatcher)(this.ws);
131
+ const transferID = await this.initTransfer();
132
+ this.dispatcher.setTransferProperties({ id: transferID, kind: 'pull' });
133
+ await this.dispatcher.dispatchTransferAction('bootstrap');
134
+ }
135
+ async close() {
136
+ await this.dispatcher?.dispatchTransferAction('close');
137
+ await new Promise((resolve) => {
138
+ const { ws } = this;
139
+ if (!ws || ws.CLOSED) {
140
+ resolve();
141
+ return;
142
+ }
143
+ ws.on('close', () => resolve()).close();
144
+ });
145
+ }
146
+ async getSchemas() {
147
+ const schemas = (await this.dispatcher?.dispatchTransferAction('getSchemas')) ?? null;
148
+ return schemas;
149
+ }
150
+ }
151
+ _RemoteStrapiSourceProvider_instances = new WeakSet(), _RemoteStrapiSourceProvider_createStageReadStream = async function _RemoteStrapiSourceProvider_createStageReadStream(stage) {
152
+ const startResult = await __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_startStep).call(this, stage);
153
+ if (startResult instanceof Error) {
154
+ throw startResult;
155
+ }
156
+ const { id: processID } = startResult;
157
+ const stream = new stream_1.PassThrough({ objectMode: true });
158
+ const listener = async (raw) => {
159
+ const parsed = JSON.parse(raw.toString());
160
+ // If not a message related to our transfer process, ignore it
161
+ if (!parsed.uuid || parsed?.data?.type !== 'transfer' || parsed?.data?.id !== processID) {
162
+ this.ws?.once('message', listener);
163
+ return;
164
+ }
165
+ const { uuid, data: message } = parsed;
166
+ const { ended, error, data } = message;
167
+ if (ended) {
168
+ await __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_respond).call(this, uuid);
169
+ await __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_endStep).call(this, stage);
170
+ stream.end();
171
+ return;
172
+ }
173
+ if (error) {
174
+ await __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_respond).call(this, uuid);
175
+ await __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_endStep).call(this, stage);
176
+ stream.destroy(error);
177
+ return;
178
+ }
179
+ stream.push(data);
180
+ this.ws?.once('message', listener);
181
+ await __classPrivateFieldGet(this, _RemoteStrapiSourceProvider_instances, "m", _RemoteStrapiSourceProvider_respond).call(this, uuid);
182
+ };
183
+ this.ws?.once('message', listener);
184
+ return stream;
185
+ }, _RemoteStrapiSourceProvider_startStep = async function _RemoteStrapiSourceProvider_startStep(step) {
186
+ try {
187
+ return await this.dispatcher?.dispatchTransferStep({ action: 'start', step });
188
+ }
189
+ catch (e) {
190
+ if (e instanceof Error) {
191
+ return e;
192
+ }
193
+ if (typeof e === 'string') {
194
+ return new providers_1.ProviderTransferError(e);
195
+ }
196
+ return new providers_1.ProviderTransferError('Unexpected error');
197
+ }
198
+ }, _RemoteStrapiSourceProvider_respond = async function _RemoteStrapiSourceProvider_respond(uuid) {
199
+ return new Promise((resolve, reject) => {
200
+ this.ws?.send(JSON.stringify({ uuid }), (e) => {
201
+ if (e) {
202
+ reject(e);
203
+ }
204
+ else {
205
+ resolve(e);
206
+ }
207
+ });
208
+ });
209
+ }, _RemoteStrapiSourceProvider_endStep = async function _RemoteStrapiSourceProvider_endStep(step) {
210
+ try {
211
+ await this.dispatcher?.dispatchTransferStep({ action: 'end', step });
212
+ }
213
+ catch (e) {
214
+ if (e instanceof Error) {
215
+ return e;
216
+ }
217
+ if (typeof e === 'string') {
218
+ return new providers_1.ProviderTransferError(e);
219
+ }
220
+ return new providers_1.ProviderTransferError('Unexpected error');
221
+ }
222
+ return null;
223
+ };
224
+ const createRemoteStrapiSourceProvider = (options) => {
225
+ return new RemoteStrapiSourceProvider(options);
226
+ };
227
+ exports.createRemoteStrapiSourceProvider = createRemoteStrapiSourceProvider;
228
+ //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { WebSocket } from 'ws';
2
- import type { client } from '../../../../types/remote/protocol';
2
+ import type { client } from '../../../types/remote/protocol';
3
3
  interface IDispatcherState {
4
4
  transfer?: {
5
5
  kind: client.TransferKind;
@@ -12,13 +12,13 @@ interface IDispatchOptions {
12
12
  declare type Dispatch<T> = Omit<T, 'transferID' | 'uuid'>;
13
13
  declare const createDispatcher: (ws: WebSocket) => {
14
14
  readonly transferID: string | undefined;
15
- readonly transferKind: "push" | "pull" | undefined;
15
+ readonly transferKind: any;
16
16
  setTransferProperties: (properties: Exclude<IDispatcherState['transfer'], undefined>) => void;
17
17
  dispatch: <U = null>(message: Dispatch<client.Message>, options?: IDispatchOptions) => Promise<U | null>;
18
18
  dispatchCommand: <U_1 extends "end" | "init" | "status">(payload: {
19
19
  command: U_1;
20
20
  } & ([client.GetCommandParams<U_1>] extends [never] ? unknown : {
21
- params: client.GetCommandParams<U_1>;
21
+ params?: client.GetCommandParams<U_1> | undefined;
22
22
  })) => Promise<null>;
23
23
  dispatchTransferAction: <T>(action: client.Action['action']) => Promise<T | null>;
24
24
  dispatchTransferStep: <T_1, A extends "stream" | "end" | "start" = "stream" | "end" | "start", S extends "entities" | "links" | "configuration" | "assets" = "entities" | "links" | "configuration" | "assets">(payload: {
@@ -2,7 +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
+ const providers_1 = require("../../errors/providers");
6
6
  const createDispatcher = (ws) => {
7
7
  const state = {};
8
8
  const dispatch = async (message, options = {}) => {
@@ -1,2 +1,4 @@
1
- export declare const TRANSFER_PATH: "/transfer/runner/connect";
1
+ export declare const TRANSFER_PATH: "/transfer/runner";
2
2
  export declare const TRANSFER_METHODS: readonly ["push", "pull"];
3
+ export declare type TransferPath = typeof TRANSFER_PATH;
4
+ export declare type TransferMethod = (typeof TRANSFER_METHODS)[number];
@@ -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/runner/connect';
4
+ exports.TRANSFER_PATH = '/transfer/runner';
5
5
  exports.TRANSFER_METHODS = ['push', 'pull'];
6
6
  //# sourceMappingURL=constants.js.map
@@ -8,11 +8,11 @@ export declare type Step = {
8
8
  locked?: boolean;
9
9
  };
10
10
  export { default as DEFAULT_TRANSFER_FLOW } from './default';
11
- export declare const createFlow: (flow: readonly Step[]) => {
11
+ export interface TransferFlow {
12
12
  has(step: Step): boolean;
13
13
  can(step: Step): boolean;
14
14
  cannot(step: Step): boolean;
15
- set(step: Step): any;
15
+ set(step: Step): this;
16
16
  get(): Step | null;
17
- };
18
- export declare type TransferFlow = ReturnType<typeof createFlow>;
17
+ }
18
+ export declare const createFlow: (flow: readonly Step[]) => TransferFlow;
@@ -0,0 +1,62 @@
1
+ /// <reference types="node" />
2
+ import type { WebSocket, RawData } from 'ws';
3
+ import type { ValidTransferCommand } from './constants';
4
+ import type { TransferMethod } from '../constants';
5
+ declare type BufferLike = Parameters<WebSocket['send']>[0];
6
+ export interface TransferState {
7
+ id?: string;
8
+ startedAt?: number;
9
+ }
10
+ export interface Handler {
11
+ get transferID(): TransferState['id'];
12
+ set transferID(id: TransferState['id']);
13
+ get startedAt(): TransferState['startedAt'];
14
+ set startedAt(id: TransferState['startedAt']);
15
+ /**
16
+ * Returns whether a transfer is currently in progress or not
17
+ */
18
+ isTransferStarted(): boolean;
19
+ /**
20
+ * Make sure the current transfer is started and initialized
21
+ */
22
+ assertValidTransfer(): void;
23
+ /**
24
+ * Checks that the given string is a valid transfer command
25
+ */
26
+ assertValidTransferCommand(command: string): asserts command is ValidTransferCommand;
27
+ /**
28
+ * Respond to a specific message
29
+ */
30
+ respond<T = unknown>(uuid?: string, e?: Error | null, data?: T): Promise<void>;
31
+ /**
32
+ * It sends a message to the client
33
+ */
34
+ send<T extends BufferLike>(message: T, cb?: (err?: Error) => void): void;
35
+ /**
36
+ * It sends a message to the client and waits for a confirmation
37
+ */
38
+ confirm<T = unknown>(message: T): Promise<void>;
39
+ /**
40
+ * Check the current auth has the permission for the given scope
41
+ */
42
+ verifyAuth(scope?: TransferMethod): Promise<void>;
43
+ /**
44
+ * Invoke a function and return its result to the client
45
+ */
46
+ executeAndRespond<T = unknown>(uuid: string, fn: () => T): Promise<void>;
47
+ /**
48
+ * Lifecycle called on error or when the ws connection is closed
49
+ */
50
+ teardown(): Promise<void> | void;
51
+ /**
52
+ * Lifecycle called to cleanup the transfer state
53
+ */
54
+ cleanup(): Promise<void> | void;
55
+ init(...args: unknown[]): unknown;
56
+ end(...args: unknown[]): unknown;
57
+ status(...args: unknown[]): unknown;
58
+ onMessage(message: RawData, isBinary: boolean): Promise<void> | void;
59
+ onClose(code: number, reason: Buffer): Promise<void> | void;
60
+ onError(err: Error): Promise<void> | void;
61
+ }
62
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=abstract.js.map
@@ -0,0 +1,2 @@
1
+ export declare const VALID_TRANSFER_COMMANDS: readonly ["init", "end", "status"];
2
+ export declare type ValidTransferCommand = (typeof VALID_TRANSFER_COMMANDS)[number];
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VALID_TRANSFER_COMMANDS = void 0;
4
+ exports.VALID_TRANSFER_COMMANDS = ['init', 'end', 'status'];
5
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,3 @@
1
+ export { createPushController, PushHandler } from './push';
2
+ export { createPullController, PullHandler } from './pull';
3
+ export { handlerControllerFactory, HandlerOptions } from './utils';
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handlerControllerFactory = exports.createPullController = exports.createPushController = void 0;
4
+ var push_1 = require("./push");
5
+ Object.defineProperty(exports, "createPushController", { enumerable: true, get: function () { return push_1.createPushController; } });
6
+ var pull_1 = require("./pull");
7
+ Object.defineProperty(exports, "createPullController", { enumerable: true, get: function () { return pull_1.createPullController; } });
8
+ var utils_1 = require("./utils");
9
+ Object.defineProperty(exports, "handlerControllerFactory", { enumerable: true, get: function () { return utils_1.handlerControllerFactory; } });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,22 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="koa" />
3
+ import { Readable } from 'stream';
4
+ import { Handler } from './abstract';
5
+ import { ILocalStrapiSourceProvider } from '../../providers';
6
+ import type { TransferStage, Protocol } from '../../../../types';
7
+ declare const VALID_TRANSFER_ACTIONS: readonly ["bootstrap", "close", "getMetadata", "getSchemas"];
8
+ declare type PullTransferAction = (typeof VALID_TRANSFER_ACTIONS)[number];
9
+ export interface PullHandler extends Handler {
10
+ provider?: ILocalStrapiSourceProvider;
11
+ streams?: {
12
+ [stage in TransferStage]?: Readable;
13
+ };
14
+ assertValidTransferAction(action: string): asserts action is PullTransferAction;
15
+ onTransferMessage(msg: Protocol.client.TransferMessage): Promise<unknown> | unknown;
16
+ onTransferAction(msg: Protocol.client.Action): Promise<unknown> | unknown;
17
+ onTransferStep(msg: Protocol.client.TransferPullMessage): Promise<unknown> | unknown;
18
+ createReadableStreamForStep(step: TransferStage): Promise<void>;
19
+ flush(stage: TransferStage, id: string): Promise<void> | void;
20
+ }
21
+ export declare const createPullController: (options: import("./utils").HandlerOptions) => (ctx: import("koa").Context) => Promise<void>;
22
+ export {};