@strapi/data-transfer 4.9.0-alpha.0 → 4.9.0-beta.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 (48) hide show
  1. package/lib/engine/index.d.ts +2 -1
  2. package/lib/engine/index.js +67 -7
  3. package/lib/errors/constants.d.ts +1 -1
  4. package/lib/file/providers/destination/index.js +7 -0
  5. package/lib/strapi/index.d.ts +0 -1
  6. package/lib/strapi/index.js +1 -6
  7. package/lib/strapi/providers/index.d.ts +1 -0
  8. package/lib/strapi/providers/index.js +1 -0
  9. package/lib/strapi/providers/local-destination/index.d.ts +1 -1
  10. package/lib/strapi/providers/local-destination/index.js +9 -4
  11. package/lib/strapi/providers/remote-destination/index.d.ts +5 -8
  12. package/lib/strapi/providers/remote-destination/index.js +157 -59
  13. package/lib/strapi/providers/remote-source/index.d.ts +36 -0
  14. package/lib/strapi/providers/remote-source/index.js +228 -0
  15. package/lib/strapi/providers/{remote-destination/utils.d.ts → utils.d.ts} +3 -3
  16. package/lib/strapi/providers/{remote-destination/utils.js → utils.js} +2 -2
  17. package/lib/strapi/remote/constants.d.ts +4 -2
  18. package/lib/strapi/remote/constants.js +1 -1
  19. package/lib/strapi/remote/flows/default.d.ts +3 -0
  20. package/lib/strapi/remote/flows/default.js +41 -0
  21. package/lib/strapi/remote/flows/index.d.ts +18 -0
  22. package/lib/strapi/remote/flows/index.js +59 -0
  23. package/lib/strapi/remote/handlers/abstract.d.ts +62 -0
  24. package/lib/strapi/remote/handlers/abstract.js +3 -0
  25. package/lib/strapi/remote/handlers/constants.d.ts +2 -0
  26. package/lib/strapi/remote/handlers/constants.js +5 -0
  27. package/lib/strapi/remote/handlers/index.d.ts +3 -0
  28. package/lib/strapi/remote/handlers/index.js +10 -0
  29. package/lib/strapi/remote/handlers/pull.d.ts +22 -0
  30. package/lib/strapi/remote/handlers/pull.js +186 -0
  31. package/lib/strapi/remote/handlers/push.d.ts +75 -0
  32. package/lib/strapi/remote/handlers/push.js +297 -0
  33. package/lib/strapi/remote/handlers/utils.d.ts +25 -0
  34. package/lib/strapi/remote/handlers/utils.js +181 -0
  35. package/lib/strapi/remote/index.d.ts +1 -2
  36. package/lib/strapi/remote/index.js +2 -3
  37. package/lib/utils/transaction.js +21 -3
  38. package/package.json +8 -7
  39. package/lib/strapi/register.d.ts +0 -7
  40. package/lib/strapi/register.js +0 -13
  41. package/lib/strapi/remote/controllers/index.d.ts +0 -1
  42. package/lib/strapi/remote/controllers/index.js +0 -18
  43. package/lib/strapi/remote/controllers/push.d.ts +0 -25
  44. package/lib/strapi/remote/controllers/push.js +0 -95
  45. package/lib/strapi/remote/handlers.d.ts +0 -3
  46. package/lib/strapi/remote/handlers.js +0 -193
  47. package/lib/strapi/remote/routes.d.ts +0 -21
  48. package/lib/strapi/remote/routes.js +0 -22
@@ -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 connection: Authentication Error'));
83
+ }
84
+ if (res.statusCode === 403) {
85
+ return reject(new providers_1.ProviderInitializationError('Failed to initialize the connection: Authorization Error'));
86
+ }
87
+ if (res.statusCode === 404) {
88
+ return reject(new providers_1.ProviderInitializationError('Failed to initialize the connection: Data transfer is not enabled on the remote host'));
89
+ }
90
+ return reject(new providers_1.ProviderInitializationError(`Failed to initialize the connection: 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,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createDispatcher = void 0;
4
4
  const uuid_1 = require("uuid");
5
+ const providers_1 = require("../../errors/providers");
5
6
  const createDispatcher = (ws) => {
6
7
  const state = {};
7
8
  const dispatch = async (message, options = {}) => {
@@ -24,7 +25,7 @@ const createDispatcher = (ws) => {
24
25
  const response = JSON.parse(raw.toString());
25
26
  if (response.uuid === uuid) {
26
27
  if (response.error) {
27
- return reject(new Error(response.error.message));
28
+ return reject(new providers_1.ProviderError('error', response.error.message));
28
29
  }
29
30
  resolve(response.data ?? null);
30
31
  }
@@ -32,7 +33,6 @@ const createDispatcher = (ws) => {
32
33
  ws.once('message', onResponse);
33
34
  }
34
35
  };
35
- // TODO: What happens if the server sends another message (not a response to this message)
36
36
  ws.once('message', onResponse);
37
37
  });
38
38
  };
@@ -1,2 +1,4 @@
1
- export declare const TRANSFER_PATH = "/transfer";
2
- export declare const TRANSFER_METHODS: string[];
1
+ export declare const TRANSFER_PATH: "/transfer/runner";
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';
4
+ exports.TRANSFER_PATH = '/transfer/runner';
5
5
  exports.TRANSFER_METHODS = ['push', 'pull'];
6
6
  //# sourceMappingURL=constants.js.map
@@ -0,0 +1,3 @@
1
+ import type { Step } from '.';
2
+ declare const _default: readonly Step[];
3
+ export default _default;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = [
4
+ {
5
+ kind: 'action',
6
+ action: 'bootstrap',
7
+ },
8
+ {
9
+ kind: 'action',
10
+ action: 'init',
11
+ },
12
+ {
13
+ kind: 'action',
14
+ action: 'beforeTransfer',
15
+ },
16
+ {
17
+ kind: 'transfer',
18
+ stage: 'schemas',
19
+ },
20
+ {
21
+ kind: 'transfer',
22
+ stage: 'entities',
23
+ },
24
+ {
25
+ kind: 'transfer',
26
+ stage: 'assets',
27
+ },
28
+ {
29
+ kind: 'transfer',
30
+ stage: 'links',
31
+ },
32
+ {
33
+ kind: 'transfer',
34
+ stage: 'configuration',
35
+ },
36
+ {
37
+ kind: 'action',
38
+ action: 'close',
39
+ },
40
+ ];
41
+ //# sourceMappingURL=default.js.map
@@ -0,0 +1,18 @@
1
+ import type { TransferStage } from '../../../../types';
2
+ export declare type Step = {
3
+ kind: 'action';
4
+ action: string;
5
+ } | {
6
+ kind: 'transfer';
7
+ stage: TransferStage;
8
+ locked?: boolean;
9
+ };
10
+ export { default as DEFAULT_TRANSFER_FLOW } from './default';
11
+ export interface TransferFlow {
12
+ has(step: Step): boolean;
13
+ can(step: Step): boolean;
14
+ cannot(step: Step): boolean;
15
+ set(step: Step): this;
16
+ get(): Step | null;
17
+ }
18
+ export declare const createFlow: (flow: readonly Step[]) => TransferFlow;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createFlow = exports.DEFAULT_TRANSFER_FLOW = void 0;
7
+ var default_1 = require("./default");
8
+ Object.defineProperty(exports, "DEFAULT_TRANSFER_FLOW", { enumerable: true, get: function () { return __importDefault(default_1).default; } });
9
+ const createFlow = (flow) => {
10
+ const state = { step: null };
11
+ /**
12
+ * Equality check between two steps
13
+ */
14
+ const stepEqual = (stepA, stepB) => {
15
+ if (stepA.kind === 'action' && stepB.kind === 'action') {
16
+ return stepA.action === stepB.action;
17
+ }
18
+ if (stepA.kind === 'transfer' && stepB.kind === 'transfer') {
19
+ return stepA.stage === stepB.stage;
20
+ }
21
+ return false;
22
+ };
23
+ /**
24
+ * Find the index for a given step
25
+ */
26
+ const findStepIndex = (step) => flow.findIndex((flowStep) => stepEqual(step, flowStep));
27
+ return {
28
+ has(step) {
29
+ return findStepIndex(step) !== -1;
30
+ },
31
+ can(step) {
32
+ if (state.step === null) {
33
+ return true;
34
+ }
35
+ const indexesDifference = findStepIndex(step) - findStepIndex(state.step);
36
+ // It's possible to send multiple time the same transfer step in a row
37
+ if (indexesDifference === 0 && step.kind === 'transfer') {
38
+ return true;
39
+ }
40
+ return indexesDifference > 0;
41
+ },
42
+ cannot(step) {
43
+ return !this.can(step);
44
+ },
45
+ set(step) {
46
+ const canSwitch = this.can(step);
47
+ if (!canSwitch) {
48
+ throw new Error('Impossible to proceed to the given step');
49
+ }
50
+ state.step = step;
51
+ return this;
52
+ },
53
+ get() {
54
+ return state.step;
55
+ },
56
+ };
57
+ };
58
+ exports.createFlow = createFlow;
59
+ //# sourceMappingURL=index.js.map
@@ -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 {};