@strapi/data-transfer 4.6.0-alpha.0 → 4.6.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 (99) hide show
  1. package/jest.config.js +3 -1
  2. package/{dist → lib}/engine/index.d.ts +17 -10
  3. package/lib/engine/index.js +359 -0
  4. package/lib/engine/validation/index.d.ts +1 -0
  5. package/lib/engine/validation/index.js +28 -0
  6. package/lib/engine/validation/schemas/index.d.ts +7 -0
  7. package/lib/engine/validation/schemas/index.js +53 -0
  8. package/lib/file/index.d.ts +1 -0
  9. package/lib/file/index.js +28 -0
  10. package/{dist/providers/local-file-destination-provider.d.ts → lib/file/providers/destination/index.d.ts} +10 -6
  11. package/{dist/providers/local-file-destination-provider.js → lib/file/providers/destination/index.js} +59 -87
  12. package/lib/file/providers/destination/utils.d.ts +9 -0
  13. package/lib/file/providers/destination/utils.js +61 -0
  14. package/lib/file/providers/index.d.ts +2 -0
  15. package/{dist → lib/file}/providers/index.js +2 -6
  16. package/lib/file/providers/source/index.d.ts +40 -0
  17. package/{dist/providers/local-file-source-provider.js → lib/file/providers/source/index.js} +94 -51
  18. package/lib/index.d.ts +4 -0
  19. package/lib/index.js +31 -0
  20. package/lib/strapi/index.d.ts +4 -0
  21. package/lib/strapi/index.js +35 -0
  22. package/lib/strapi/providers/index.d.ts +3 -0
  23. package/lib/strapi/providers/index.js +22 -0
  24. package/lib/strapi/providers/local-destination/index.d.ts +32 -0
  25. package/lib/strapi/providers/local-destination/index.js +195 -0
  26. package/lib/strapi/providers/local-destination/strategies/index.d.ts +1 -0
  27. package/lib/strapi/providers/local-destination/strategies/index.js +28 -0
  28. package/lib/strapi/providers/local-destination/strategies/restore/configuration.d.ts +5 -0
  29. package/lib/strapi/providers/local-destination/strategies/restore/configuration.js +44 -0
  30. package/lib/strapi/providers/local-destination/strategies/restore/entities.d.ts +9 -0
  31. package/lib/strapi/providers/local-destination/strategies/restore/entities.js +100 -0
  32. package/lib/strapi/providers/local-destination/strategies/restore/index.d.ts +32 -0
  33. package/lib/strapi/providers/local-destination/strategies/restore/index.js +106 -0
  34. package/lib/strapi/providers/local-destination/strategies/restore/links.d.ts +3 -0
  35. package/lib/strapi/providers/local-destination/strategies/restore/links.js +29 -0
  36. package/lib/strapi/providers/local-source/assets.d.ts +5 -0
  37. package/lib/strapi/providers/local-source/assets.js +31 -0
  38. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/configuration.d.ts +0 -0
  39. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/configuration.js +13 -14
  40. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/entities.d.ts +0 -0
  41. package/lib/strapi/providers/local-source/entities.js +85 -0
  42. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/index.d.ts +9 -8
  43. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/index.js +36 -6
  44. package/{dist/providers/local-strapi-source-provider/links/index.d.ts → lib/strapi/providers/local-source/links.d.ts} +1 -1
  45. package/lib/strapi/providers/local-source/links.js +23 -0
  46. package/lib/strapi/providers/remote-destination/index.d.ts +40 -0
  47. package/lib/strapi/providers/remote-destination/index.js +171 -0
  48. package/lib/strapi/providers/remote-destination/utils.d.ts +31 -0
  49. package/lib/strapi/providers/remote-destination/utils.js +72 -0
  50. package/lib/strapi/queries/entity.d.ts +19 -0
  51. package/lib/strapi/queries/entity.js +130 -0
  52. package/lib/strapi/queries/index.d.ts +2 -0
  53. package/lib/strapi/queries/index.js +29 -0
  54. package/lib/strapi/queries/link.d.ts +6 -0
  55. package/lib/strapi/queries/link.js +201 -0
  56. package/lib/strapi/register.d.ts +7 -0
  57. package/lib/strapi/register.js +13 -0
  58. package/lib/strapi/remote/constants.d.ts +1 -0
  59. package/lib/strapi/remote/constants.js +5 -0
  60. package/lib/strapi/remote/controllers/index.d.ts +1 -0
  61. package/{dist → lib/strapi/remote/controllers}/index.js +1 -2
  62. package/lib/strapi/remote/controllers/push.d.ts +25 -0
  63. package/lib/strapi/remote/controllers/push.js +95 -0
  64. package/lib/strapi/remote/handlers.d.ts +3 -0
  65. package/lib/strapi/remote/handlers.js +177 -0
  66. package/lib/strapi/remote/index.d.ts +3 -0
  67. package/lib/strapi/remote/index.js +30 -0
  68. package/lib/strapi/remote/routes.d.ts +21 -0
  69. package/lib/strapi/remote/routes.js +22 -0
  70. package/lib/utils/encryption/decrypt.d.ts +11 -0
  71. package/{dist → lib/utils}/encryption/decrypt.js +12 -4
  72. package/lib/utils/encryption/encrypt.d.ts +11 -0
  73. package/{dist → lib/utils}/encryption/encrypt.js +12 -4
  74. package/{dist → lib/utils}/encryption/index.d.ts +0 -0
  75. package/{dist → lib/utils}/encryption/index.js +0 -0
  76. package/lib/utils/index.d.ts +4 -0
  77. package/lib/utils/index.js +31 -0
  78. package/lib/utils/json.d.ts +30 -0
  79. package/{dist/utils.js → lib/utils/json.js} +16 -38
  80. package/lib/utils/schema.d.ts +7 -0
  81. package/lib/utils/schema.js +29 -0
  82. package/lib/utils/stream.d.ts +27 -0
  83. package/lib/utils/stream.js +59 -0
  84. package/package.json +19 -12
  85. package/dist/encryption/decrypt.d.ts +0 -3
  86. package/dist/encryption/encrypt.d.ts +0 -3
  87. package/dist/engine/index.js +0 -324
  88. package/dist/index.d.ts +0 -2
  89. package/dist/providers/index.d.ts +0 -4
  90. package/dist/providers/local-file-source-provider.d.ts +0 -43
  91. package/dist/providers/local-strapi-destination-provider.d.ts +0 -22
  92. package/dist/providers/local-strapi-destination-provider.js +0 -78
  93. package/dist/providers/local-strapi-source-provider/entities.js +0 -58
  94. package/dist/providers/local-strapi-source-provider/links/index.js +0 -37
  95. package/dist/providers/local-strapi-source-provider/links/utils.d.ts +0 -27
  96. package/dist/providers/local-strapi-source-provider/links/utils.js +0 -155
  97. package/dist/strategies/index.d.ts +0 -7
  98. package/dist/strategies/index.js +0 -29
  99. package/dist/utils.d.ts +0 -10
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAssetsStream = void 0;
4
+ const path_1 = require("path");
5
+ const fs_extra_1 = require("fs-extra");
6
+ const stream_1 = require("stream");
7
+ const IGNORED_FILES = ['.gitkeep'];
8
+ /**
9
+ * Generate and consume assets streams in order to stream each file individually
10
+ */
11
+ const createAssetsStream = (strapi) => {
12
+ const assetsDirectory = (0, path_1.join)(strapi.dirs.static.public, 'uploads');
13
+ const generator = async function* () {
14
+ const files = await (0, fs_extra_1.readdir)(assetsDirectory);
15
+ const validFiles = files.filter((file) => !IGNORED_FILES.includes(file));
16
+ for (const filename of validFiles) {
17
+ const filepath = (0, path_1.join)(assetsDirectory, filename);
18
+ const stats = await (0, fs_extra_1.stat)(filepath);
19
+ const stream = (0, fs_extra_1.createReadStream)(filepath);
20
+ yield {
21
+ filename,
22
+ filepath,
23
+ stream,
24
+ stats: { size: stats.size },
25
+ };
26
+ }
27
+ };
28
+ return stream_1.Duplex.from(generator());
29
+ };
30
+ exports.createAssetsStream = createAssetsStream;
31
+ //# sourceMappingURL=assets.js.map
@@ -8,20 +8,19 @@ const fp_1 = require("lodash/fp");
8
8
  * Create a readable stream that export the Strapi app configuration
9
9
  */
10
10
  const createConfigurationStream = (strapi) => {
11
- // Core Store
12
- const coreStoreStream = (0, stream_chain_1.chain)([
13
- strapi.db.queryBuilder('strapi::core-store').stream(),
14
- (data) => (0, fp_1.set)('value', JSON.parse(data.value), data),
15
- wrapConfigurationItem('core-store'),
16
- ]);
17
- // Webhook
18
- const webhooksStream = (0, stream_chain_1.chain)([
19
- strapi.db.queryBuilder('webhook').stream(),
20
- wrapConfigurationItem('webhook'),
21
- ]);
22
- const streams = [coreStoreStream, webhooksStream];
23
- // Readable configuration stream
24
- return stream_1.Readable.from((async function* () {
11
+ return stream_1.Readable.from((async function* configurationGenerator() {
12
+ // Core Store
13
+ const coreStoreStream = (0, stream_chain_1.chain)([
14
+ strapi.db.queryBuilder('strapi::core-store').stream(),
15
+ (data) => (0, fp_1.set)('value', JSON.parse(data.value), data),
16
+ wrapConfigurationItem('core-store'),
17
+ ]);
18
+ // Webhook
19
+ const webhooksStream = (0, stream_chain_1.chain)([
20
+ strapi.db.queryBuilder('webhook').stream(),
21
+ wrapConfigurationItem('webhook'),
22
+ ]);
23
+ const streams = [coreStoreStream, webhooksStream];
25
24
  for (const stream of streams) {
26
25
  for await (const item of stream) {
27
26
  yield item;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.createEntitiesTransformStream = exports.createEntitiesStream = void 0;
27
+ const stream_1 = require("stream");
28
+ const shared = __importStar(require("../../queries"));
29
+ /**
30
+ * Generate and consume content-types streams in order to stream each entity individually
31
+ */
32
+ const createEntitiesStream = (strapi) => {
33
+ const contentTypes = Object.values(strapi.contentTypes);
34
+ async function* contentTypeStreamGenerator() {
35
+ for (const contentType of contentTypes) {
36
+ const query = shared.entity.createEntityQuery(strapi).call(null, contentType.uid);
37
+ const stream = strapi.db
38
+ // Create a query builder instance (default type is 'select')
39
+ .queryBuilder(contentType.uid)
40
+ // Fetch all columns
41
+ .select('*')
42
+ // Apply the populate
43
+ .populate(query.deepPopulateComponentLikeQuery)
44
+ // Get a readable stream
45
+ .stream();
46
+ yield { contentType, stream };
47
+ }
48
+ }
49
+ return stream_1.Readable.from((async function* entitiesGenerator() {
50
+ for await (const { stream, contentType } of contentTypeStreamGenerator()) {
51
+ try {
52
+ for await (const entity of stream) {
53
+ yield { entity, contentType };
54
+ }
55
+ }
56
+ catch {
57
+ // ignore
58
+ }
59
+ finally {
60
+ stream.destroy();
61
+ }
62
+ }
63
+ })());
64
+ };
65
+ exports.createEntitiesStream = createEntitiesStream;
66
+ /**
67
+ * Create an entity transform stream which convert the output of
68
+ * the multi-content-types stream to the transfer entity format
69
+ */
70
+ const createEntitiesTransformStream = () => {
71
+ return new stream_1.PassThrough({
72
+ objectMode: true,
73
+ transform(data, _encoding, callback) {
74
+ const { entity, contentType } = data;
75
+ const { id, ...attributes } = entity;
76
+ callback(null, {
77
+ type: contentType.uid,
78
+ id,
79
+ data: attributes,
80
+ });
81
+ },
82
+ });
83
+ };
84
+ exports.createEntitiesTransformStream = createEntitiesTransformStream;
85
+ //# sourceMappingURL=entities.js.map
@@ -1,5 +1,7 @@
1
1
  /// <reference types="node" />
2
- import type { IMetadata, ISourceProvider, ProviderType } from '../../../types';
2
+ /// <reference types="lodash" />
3
+ import { Readable } from 'stream';
4
+ import type { IMetadata, ISourceProvider, ProviderType } from '../../../../types';
3
5
  export interface ILocalStrapiSourceProviderOptions {
4
6
  getStrapi(): Strapi.Strapi | Promise<Strapi.Strapi>;
5
7
  autoDestroy?: boolean;
@@ -14,13 +16,12 @@ declare class LocalStrapiSourceProvider implements ISourceProvider {
14
16
  bootstrap(): Promise<void>;
15
17
  close(): Promise<void>;
16
18
  getMetadata(): IMetadata;
17
- streamEntities(): Promise<NodeJS.ReadableStream>;
18
- streamLinks(): NodeJS.ReadableStream;
19
- streamConfiguration(): NodeJS.ReadableStream;
20
- getSchemas(): {
21
- [x: string]: Partial<any>;
22
- };
23
- streamSchemas(): NodeJS.ReadableStream;
19
+ createEntitiesReadStream(): Promise<Readable>;
20
+ createLinksReadStream(): Readable;
21
+ createConfigurationReadStream(): Readable;
22
+ getSchemas(): import("lodash").Dictionary<Partial<import("@strapi/strapi").Schema>>;
23
+ createSchemasReadStream(): Readable;
24
+ createAssetsReadStream(): Readable;
24
25
  }
25
26
  export declare type ILocalStrapiSourceProvider = InstanceType<typeof LocalStrapiSourceProvider>;
26
27
  export {};
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.createLocalStrapiSourceProvider = void 0;
4
27
  const stream_chain_1 = require("stream-chain");
@@ -6,7 +29,8 @@ const stream_1 = require("stream");
6
29
  const entities_1 = require("./entities");
7
30
  const links_1 = require("./links");
8
31
  const configuration_1 = require("./configuration");
9
- const utils_1 = require("../../utils");
32
+ const assets_1 = require("./assets");
33
+ const utils = __importStar(require("../../../utils"));
10
34
  const createLocalStrapiSourceProvider = (options) => {
11
35
  return new LocalStrapiSourceProvider(options);
12
36
  };
@@ -43,7 +67,7 @@ class LocalStrapiSourceProvider {
43
67
  },
44
68
  };
45
69
  }
46
- async streamEntities() {
70
+ async createEntitiesReadStream() {
47
71
  if (!this.strapi) {
48
72
  throw new Error('Not able to stream entities. Strapi instance not found');
49
73
  }
@@ -54,13 +78,13 @@ class LocalStrapiSourceProvider {
54
78
  (0, entities_1.createEntitiesTransformStream)(),
55
79
  ]);
56
80
  }
57
- streamLinks() {
81
+ createLinksReadStream() {
58
82
  if (!this.strapi) {
59
83
  throw new Error('Not able to stream links. Strapi instance not found');
60
84
  }
61
85
  return (0, links_1.createLinksStream)(this.strapi);
62
86
  }
63
- streamConfiguration() {
87
+ createConfigurationReadStream() {
64
88
  if (!this.strapi) {
65
89
  throw new Error('Not able to stream configuration. Strapi instance not found');
66
90
  }
@@ -74,10 +98,16 @@ class LocalStrapiSourceProvider {
74
98
  ...this.strapi.contentTypes,
75
99
  ...this.strapi.components,
76
100
  };
77
- return (0, utils_1.mapSchemasValues)(schemas);
101
+ return utils.schema.mapSchemasValues(schemas);
78
102
  }
79
- streamSchemas() {
103
+ createSchemasReadStream() {
80
104
  return stream_1.Readable.from(Object.values(this.getSchemas()));
81
105
  }
106
+ createAssetsReadStream() {
107
+ if (!this.strapi) {
108
+ throw new Error('Not able to stream assets. Strapi instance not found');
109
+ }
110
+ return (0, assets_1.createAssetsStream)(this.strapi);
111
+ }
82
112
  }
83
113
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { Readable } from 'stream';
2
2
  /**
3
- * Create a Duplex instance which will stream all the links from a Strapi instance
3
+ * Create a Readable which will stream all the links from a Strapi instance
4
4
  */
5
5
  export declare const createLinksStream: (strapi: Strapi.Strapi) => Readable;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLinksStream = void 0;
4
+ const stream_1 = require("stream");
5
+ const link_1 = require("../../queries/link");
6
+ /**
7
+ * Create a Readable which will stream all the links from a Strapi instance
8
+ */
9
+ const createLinksStream = (strapi) => {
10
+ const uids = [...Object.keys(strapi.contentTypes), ...Object.keys(strapi.components)];
11
+ // Async generator stream that returns every link from a Strapi instance
12
+ return stream_1.Readable.from((async function* linkGenerator() {
13
+ const query = (0, link_1.createLinkQuery)(strapi);
14
+ for (const uid of uids) {
15
+ const generator = query().generateAll(uid);
16
+ for await (const link of generator) {
17
+ yield link;
18
+ }
19
+ }
20
+ })());
21
+ };
22
+ exports.createLinksStream = createLinksStream;
23
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1,40 @@
1
+ /// <reference types="node" />
2
+ import { WebSocket } from 'ws';
3
+ import { Writable } from 'stream';
4
+ import { createDispatcher } from './utils';
5
+ import type { IDestinationProvider, IMetadata, ProviderType } from '../../../../types';
6
+ import type { ILocalStrapiDestinationProviderOptions } from '../local-destination';
7
+ interface ITokenAuth {
8
+ type: 'token';
9
+ token: string;
10
+ }
11
+ interface ICredentialsAuth {
12
+ type: 'credentials';
13
+ email: string;
14
+ password: string;
15
+ }
16
+ export interface IRemoteStrapiDestinationProviderOptions extends Pick<ILocalStrapiDestinationProviderOptions, 'restore' | 'strategy'> {
17
+ url: URL;
18
+ auth?: ITokenAuth | ICredentialsAuth;
19
+ }
20
+ declare class RemoteStrapiDestinationProvider implements IDestinationProvider {
21
+ #private;
22
+ name: string;
23
+ type: ProviderType;
24
+ options: IRemoteStrapiDestinationProviderOptions;
25
+ ws: WebSocket | null;
26
+ dispatcher: ReturnType<typeof createDispatcher> | null;
27
+ constructor(options: IRemoteStrapiDestinationProviderOptions);
28
+ initTransfer(): Promise<string>;
29
+ bootstrap(): Promise<void>;
30
+ close(): Promise<void>;
31
+ getMetadata(): Promise<IMetadata | null> | null;
32
+ beforeTransfer(): Promise<void>;
33
+ getSchemas(): Promise<Strapi.Schemas | null>;
34
+ createEntitiesWriteStream(): Writable;
35
+ createLinksWriteStream(): Writable;
36
+ createConfigurationWriteStream(): Writable;
37
+ createAssetsWriteStream(): Writable | Promise<Writable>;
38
+ }
39
+ export declare const createRemoteStrapiDestinationProvider: (options: IRemoteStrapiDestinationProviderOptions) => RemoteStrapiDestinationProvider;
40
+ export {};
@@ -0,0 +1,171 @@
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 _RemoteStrapiDestinationProvider_instances, _RemoteStrapiDestinationProvider_streamStep;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createRemoteStrapiDestinationProvider = void 0;
10
+ const ws_1 = require("ws");
11
+ const uuid_1 = require("uuid");
12
+ const stream_1 = require("stream");
13
+ const utils_1 = require("./utils");
14
+ const constants_1 = require("../../remote/constants");
15
+ class RemoteStrapiDestinationProvider {
16
+ constructor(options) {
17
+ _RemoteStrapiDestinationProvider_instances.add(this);
18
+ this.name = 'destination::remote-strapi';
19
+ this.type = 'destination';
20
+ this.options = options;
21
+ this.ws = null;
22
+ this.dispatcher = null;
23
+ }
24
+ async initTransfer() {
25
+ const { strategy, restore } = this.options;
26
+ // Wait for the connection to be made to the server, then init the transfer
27
+ return new Promise((resolve, reject) => {
28
+ this.ws
29
+ ?.once('open', async () => {
30
+ const query = this.dispatcher?.dispatchCommand({
31
+ command: 'init',
32
+ params: { options: { strategy, restore }, transfer: 'push' },
33
+ });
34
+ const res = (await query);
35
+ if (!res?.transferID) {
36
+ return reject(new Error('Init failed, invalid response from the server'));
37
+ }
38
+ resolve(res.transferID);
39
+ })
40
+ .once('error', reject);
41
+ });
42
+ }
43
+ async bootstrap() {
44
+ const { url, auth } = this.options;
45
+ let ws;
46
+ if (!['https:', 'http:'].includes(url.protocol)) {
47
+ throw new Error(`Invalid protocol "${url.protocol}"`);
48
+ }
49
+ const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
50
+ const wsUrl = `${wsProtocol}//${url.host}${url.pathname}${constants_1.TRANSFER_PATH}`;
51
+ // No auth defined, trying public access for transfer
52
+ if (!auth) {
53
+ ws = new ws_1.WebSocket(wsUrl);
54
+ }
55
+ // Common token auth, this should be the main auth method
56
+ else if (auth.type === 'token') {
57
+ const headers = { Authorization: `Bearer ${auth.token}` };
58
+ ws = new ws_1.WebSocket(wsUrl, { headers });
59
+ }
60
+ // Invalid auth method provided
61
+ else {
62
+ throw new Error('Auth method not implemented');
63
+ }
64
+ this.ws = ws;
65
+ this.dispatcher = (0, utils_1.createDispatcher)(this.ws);
66
+ const transferID = await this.initTransfer();
67
+ this.dispatcher.setTransferProperties({ id: transferID, kind: 'push' });
68
+ await this.dispatcher.dispatchTransferAction('bootstrap');
69
+ }
70
+ async close() {
71
+ await this.dispatcher?.dispatchTransferAction('close');
72
+ await new Promise((resolve) => {
73
+ const { ws } = this;
74
+ if (!ws || ws.CLOSED) {
75
+ resolve();
76
+ return;
77
+ }
78
+ ws.on('close', () => resolve()).close();
79
+ });
80
+ }
81
+ getMetadata() {
82
+ return this.dispatcher?.dispatchTransferAction('getMetadata') ?? null;
83
+ }
84
+ async beforeTransfer() {
85
+ await this.dispatcher?.dispatchTransferAction('beforeTransfer');
86
+ }
87
+ getSchemas() {
88
+ if (!this.dispatcher) {
89
+ return Promise.resolve(null);
90
+ }
91
+ return this.dispatcher.dispatchTransferAction('getSchemas');
92
+ }
93
+ createEntitiesWriteStream() {
94
+ return new stream_1.Writable({
95
+ objectMode: true,
96
+ write: async (entity, _encoding, callback) => {
97
+ const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'entities', entity);
98
+ callback(e);
99
+ },
100
+ });
101
+ }
102
+ createLinksWriteStream() {
103
+ return new stream_1.Writable({
104
+ objectMode: true,
105
+ write: async (link, _encoding, callback) => {
106
+ const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'links', link);
107
+ callback(e);
108
+ },
109
+ });
110
+ }
111
+ createConfigurationWriteStream() {
112
+ return new stream_1.Writable({
113
+ objectMode: true,
114
+ write: async (configuration, _encoding, callback) => {
115
+ const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'configuration', configuration);
116
+ callback(e);
117
+ },
118
+ });
119
+ }
120
+ createAssetsWriteStream() {
121
+ return new stream_1.Writable({
122
+ objectMode: true,
123
+ final: async (callback) => {
124
+ // TODO: replace this stream call by an end call
125
+ const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', null);
126
+ callback(e);
127
+ },
128
+ write: async (asset, _encoding, callback) => {
129
+ const { filename, filepath, stats, stream } = asset;
130
+ const assetID = (0, uuid_1.v4)();
131
+ await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', {
132
+ action: 'start',
133
+ assetID,
134
+ data: { filename, filepath, stats },
135
+ });
136
+ for await (const chunk of stream) {
137
+ await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', {
138
+ action: 'stream',
139
+ assetID,
140
+ data: chunk,
141
+ });
142
+ }
143
+ await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', {
144
+ action: 'end',
145
+ assetID,
146
+ });
147
+ callback();
148
+ },
149
+ });
150
+ }
151
+ }
152
+ _RemoteStrapiDestinationProvider_instances = new WeakSet(), _RemoteStrapiDestinationProvider_streamStep = async function _RemoteStrapiDestinationProvider_streamStep(step, data) {
153
+ try {
154
+ await this.dispatcher?.dispatchTransferStep({ action: 'stream', step, data });
155
+ }
156
+ catch (e) {
157
+ if (e instanceof Error) {
158
+ return e;
159
+ }
160
+ if (typeof e === 'string') {
161
+ return new Error(e);
162
+ }
163
+ return new Error('Unexpected error');
164
+ }
165
+ return null;
166
+ };
167
+ const createRemoteStrapiDestinationProvider = (options) => {
168
+ return new RemoteStrapiDestinationProvider(options);
169
+ };
170
+ exports.createRemoteStrapiDestinationProvider = createRemoteStrapiDestinationProvider;
171
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,31 @@
1
+ import { WebSocket } from 'ws';
2
+ import type { client } from '../../../../types/remote/protocol';
3
+ interface IDispatcherState {
4
+ transfer?: {
5
+ kind: client.TransferKind;
6
+ id: string;
7
+ };
8
+ }
9
+ interface IDispatchOptions {
10
+ attachTransfer?: boolean;
11
+ }
12
+ declare type Dispatch<T> = Omit<T, 'transferID' | 'uuid'>;
13
+ declare const createDispatcher: (ws: WebSocket) => {
14
+ readonly transferID: string | undefined;
15
+ readonly transferKind: "push" | "pull" | undefined;
16
+ setTransferProperties: (properties: Exclude<IDispatcherState['transfer'], undefined>) => void;
17
+ dispatch: <U = null>(message: Dispatch<client.Message>, options?: IDispatchOptions) => Promise<U | null>;
18
+ dispatchCommand: <U_1 extends "end" | "init" | "status">(payload: {
19
+ command: U_1;
20
+ } & ([client.GetCommandParams<U_1>] extends [never] ? unknown : {
21
+ params: client.GetCommandParams<U_1>;
22
+ })) => Promise<null>;
23
+ dispatchTransferAction: <T>(action: client.Action['action']) => Promise<T | null>;
24
+ dispatchTransferStep: <T_1, A extends "stream" | "end" | "start" = "stream" | "end" | "start", S extends "entities" | "links" | "configuration" | "assets" = "entities" | "links" | "configuration" | "assets">(payload: {
25
+ step: S;
26
+ action: A;
27
+ } & (A extends "stream" ? {
28
+ data: client.GetTransferPushStreamData<S>;
29
+ } : unknown)) => Promise<T_1 | null>;
30
+ };
31
+ export { createDispatcher };
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDispatcher = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const createDispatcher = (ws) => {
6
+ const state = {};
7
+ const dispatch = async (message, options = {}) => {
8
+ if (!ws) {
9
+ throw new Error('No websocket connection found');
10
+ }
11
+ return new Promise((resolve, reject) => {
12
+ const uuid = (0, uuid_1.v4)();
13
+ const payload = { ...message, uuid };
14
+ if (options.attachTransfer) {
15
+ Object.assign(payload, { transferID: state.transfer?.id });
16
+ }
17
+ const stringifiedPayload = JSON.stringify(payload);
18
+ ws.send(stringifiedPayload, (error) => {
19
+ if (error) {
20
+ reject(error);
21
+ }
22
+ });
23
+ const onResponse = (raw) => {
24
+ const response = JSON.parse(raw.toString());
25
+ if (response.uuid === uuid) {
26
+ if (response.error) {
27
+ return reject(new Error(response.error.message));
28
+ }
29
+ resolve(response.data ?? null);
30
+ }
31
+ else {
32
+ ws.once('message', onResponse);
33
+ }
34
+ };
35
+ // TODO: What happens if the server sends another message (not a response to this message)
36
+ ws.once('message', onResponse);
37
+ });
38
+ };
39
+ const dispatchCommand = (payload) => {
40
+ return dispatch({ type: 'command', ...payload });
41
+ };
42
+ const dispatchTransferAction = async (action) => {
43
+ const payload = { type: 'transfer', kind: 'action', action };
44
+ return dispatch(payload, { attachTransfer: true }) ?? Promise.resolve(null);
45
+ };
46
+ const dispatchTransferStep = async (payload) => {
47
+ const message = {
48
+ type: 'transfer',
49
+ kind: 'step',
50
+ ...payload,
51
+ };
52
+ return dispatch(message, { attachTransfer: true }) ?? Promise.resolve(null);
53
+ };
54
+ const setTransferProperties = (properties) => {
55
+ state.transfer = { ...properties };
56
+ };
57
+ return {
58
+ get transferID() {
59
+ return state.transfer?.id;
60
+ },
61
+ get transferKind() {
62
+ return state.transfer?.kind;
63
+ },
64
+ setTransferProperties,
65
+ dispatch,
66
+ dispatchCommand,
67
+ dispatchTransferAction,
68
+ dispatchTransferStep,
69
+ };
70
+ };
71
+ exports.createDispatcher = createDispatcher;
72
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,19 @@
1
+ import type { ContentTypeSchema } from '@strapi/strapi';
2
+ declare const createEntityQuery: (strapi: Strapi.Strapi) => (uid: string) => {
3
+ create: <T extends {
4
+ data: U;
5
+ }, U extends object>(params: T) => Promise<any>;
6
+ createMany: <T_1 extends {
7
+ data: U_1[];
8
+ }, U_1 extends object>(params: T_1) => Promise<{
9
+ count: number;
10
+ }>;
11
+ deleteMany: <T_2 extends object>(params?: T_2 | undefined) => Promise<{
12
+ count: number;
13
+ } | null>;
14
+ getDeepPopulateComponentLikeQuery: (contentType: ContentTypeSchema, params?: {
15
+ select: string;
16
+ }) => any;
17
+ readonly deepPopulateComponentLikeQuery: any;
18
+ };
19
+ export { createEntityQuery };