@strapi/data-transfer 4.6.0-beta.1 → 4.6.0

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 (113) hide show
  1. package/lib/engine/diagnostic.d.ts +40 -0
  2. package/lib/engine/diagnostic.js +50 -0
  3. package/lib/engine/errors.d.ts +28 -0
  4. package/lib/engine/errors.js +29 -0
  5. package/{dist → lib}/engine/index.d.ts +18 -4
  6. package/{dist → lib}/engine/index.js +211 -45
  7. package/lib/engine/validation/index.d.ts +2 -0
  8. package/{dist → lib/engine/validation}/index.js +2 -2
  9. package/lib/engine/validation/provider.d.ts +3 -0
  10. package/lib/engine/validation/provider.js +18 -0
  11. package/{dist/strategies → lib/engine/validation/schemas}/index.d.ts +2 -2
  12. package/{dist/strategies → lib/engine/validation/schemas}/index.js +3 -2
  13. package/lib/errors/base.d.ts +8 -0
  14. package/lib/errors/base.js +13 -0
  15. package/lib/errors/constants.d.ts +3 -0
  16. package/lib/errors/constants.js +9 -0
  17. package/lib/errors/index.d.ts +2 -0
  18. package/{dist/providers → lib/errors}/index.js +2 -6
  19. package/lib/errors/providers.d.ts +21 -0
  20. package/lib/errors/providers.js +32 -0
  21. package/lib/file/index.d.ts +1 -0
  22. package/{dist/providers/shared → lib/file}/index.js +2 -2
  23. package/{dist/providers/local-file-destination-provider → lib/file/providers/destination}/index.d.ts +6 -6
  24. package/{dist/providers/local-file-destination-provider → lib/file/providers/destination}/index.js +7 -7
  25. package/{dist/providers/local-file-destination-provider → lib/file/providers/destination}/utils.d.ts +0 -0
  26. package/{dist/providers/local-file-destination-provider → lib/file/providers/destination}/utils.js +0 -0
  27. package/lib/file/providers/index.d.ts +2 -0
  28. package/lib/file/providers/index.js +19 -0
  29. package/{dist/providers/local-file-source-provider → lib/file/providers/source}/index.d.ts +9 -8
  30. package/{dist/providers/local-file-source-provider → lib/file/providers/source}/index.js +42 -56
  31. package/lib/index.d.ts +4 -0
  32. package/lib/index.js +31 -0
  33. package/lib/strapi/index.d.ts +4 -0
  34. package/lib/strapi/index.js +35 -0
  35. package/lib/strapi/providers/index.d.ts +3 -0
  36. package/lib/strapi/providers/index.js +22 -0
  37. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/index.d.ts +10 -7
  38. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/index.js +65 -37
  39. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/strategies/index.d.ts +0 -0
  40. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/strategies/index.js +0 -0
  41. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/strategies/restore/configuration.d.ts +2 -2
  42. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/strategies/restore/configuration.js +17 -10
  43. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/strategies/restore/entities.d.ts +2 -0
  44. package/lib/strapi/providers/local-destination/strategies/restore/entities.js +103 -0
  45. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/strategies/restore/index.d.ts +0 -0
  46. package/{dist/providers/local-strapi-destination-provider → lib/strapi/providers/local-destination}/strategies/restore/index.js +4 -3
  47. package/lib/strapi/providers/local-destination/strategies/restore/links.d.ts +4 -0
  48. package/lib/strapi/providers/local-destination/strategies/restore/links.js +32 -0
  49. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/assets.d.ts +0 -0
  50. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/assets.js +0 -0
  51. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/configuration.d.ts +0 -0
  52. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/configuration.js +12 -13
  53. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/entities.d.ts +0 -0
  54. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/entities.js +11 -4
  55. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/index.d.ts +6 -6
  56. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/index.js +12 -27
  57. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/links.d.ts +0 -0
  58. package/{dist/providers/local-strapi-source-provider → lib/strapi/providers/local-source}/links.js +1 -1
  59. package/lib/strapi/providers/remote-destination/index.d.ts +40 -0
  60. package/lib/strapi/providers/remote-destination/index.js +186 -0
  61. package/lib/strapi/providers/remote-destination/utils.d.ts +31 -0
  62. package/lib/strapi/providers/remote-destination/utils.js +72 -0
  63. package/{dist/providers/shared/strapi → lib/strapi/queries}/entity.d.ts +0 -0
  64. package/{dist/providers/shared/strapi → lib/strapi/queries}/entity.js +0 -0
  65. package/{dist/providers/shared/strapi → lib/strapi/queries}/index.d.ts +0 -0
  66. package/{dist/providers/shared/strapi → lib/strapi/queries}/index.js +0 -0
  67. package/{dist/providers/shared/strapi → lib/strapi/queries}/link.d.ts +2 -2
  68. package/{dist/providers/shared/strapi → lib/strapi/queries}/link.js +17 -3
  69. package/lib/strapi/register.d.ts +7 -0
  70. package/lib/strapi/register.js +13 -0
  71. package/lib/strapi/remote/constants.d.ts +2 -0
  72. package/lib/strapi/remote/constants.js +6 -0
  73. package/lib/strapi/remote/controllers/index.d.ts +1 -0
  74. package/lib/strapi/remote/controllers/index.js +18 -0
  75. package/lib/strapi/remote/controllers/push.d.ts +25 -0
  76. package/lib/strapi/remote/controllers/push.js +95 -0
  77. package/lib/strapi/remote/handlers.d.ts +3 -0
  78. package/lib/strapi/remote/handlers.js +193 -0
  79. package/lib/strapi/remote/index.d.ts +3 -0
  80. package/lib/strapi/remote/index.js +30 -0
  81. package/lib/strapi/remote/routes.d.ts +21 -0
  82. package/lib/strapi/remote/routes.js +22 -0
  83. package/lib/utils/encryption/decrypt.d.ts +11 -0
  84. package/{dist → lib/utils}/encryption/decrypt.js +8 -0
  85. package/lib/utils/encryption/encrypt.d.ts +11 -0
  86. package/{dist → lib/utils}/encryption/encrypt.js +8 -0
  87. package/{dist → lib/utils}/encryption/index.d.ts +0 -0
  88. package/{dist → lib/utils}/encryption/index.js +0 -0
  89. package/{dist → lib}/utils/index.d.ts +2 -0
  90. package/{dist → lib}/utils/index.js +3 -1
  91. package/{dist → lib}/utils/json.d.ts +7 -0
  92. package/{dist → lib}/utils/json.js +8 -1
  93. package/lib/utils/providers.d.ts +2 -0
  94. package/lib/utils/providers.js +11 -0
  95. package/{dist → lib}/utils/schema.d.ts +4 -0
  96. package/{dist → lib}/utils/schema.js +9 -2
  97. package/lib/utils/stream.d.ts +27 -0
  98. package/lib/utils/stream.js +59 -0
  99. package/lib/utils/transaction.d.ts +3 -0
  100. package/lib/utils/transaction.js +70 -0
  101. package/package.json +20 -12
  102. package/dist/encryption/decrypt.d.ts +0 -3
  103. package/dist/encryption/encrypt.d.ts +0 -3
  104. package/dist/index.d.ts +0 -2
  105. package/dist/providers/index.d.ts +0 -4
  106. package/dist/providers/local-strapi-destination-provider/strategies/restore/entities.js +0 -88
  107. package/dist/providers/local-strapi-destination-provider/strategies/restore/links.d.ts +0 -3
  108. package/dist/providers/local-strapi-destination-provider/strategies/restore/links.js +0 -29
  109. package/dist/providers/shared/index.d.ts +0 -1
  110. package/dist/providers/test-utils/index.d.ts +0 -111
  111. package/dist/providers/test-utils/index.js +0 -64
  112. package/dist/utils/stream.d.ts +0 -10
  113. package/dist/utils/stream.js +0 -39
@@ -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,186 @@
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
+ const providers_1 = require("../../../errors/providers");
16
+ class RemoteStrapiDestinationProvider {
17
+ constructor(options) {
18
+ _RemoteStrapiDestinationProvider_instances.add(this);
19
+ this.name = 'destination::remote-strapi';
20
+ this.type = 'destination';
21
+ this.options = options;
22
+ this.ws = null;
23
+ this.dispatcher = null;
24
+ }
25
+ async initTransfer() {
26
+ const { strategy, restore } = this.options;
27
+ // Wait for the connection to be made to the server, then init the transfer
28
+ return new Promise((resolve, reject) => {
29
+ this.ws
30
+ ?.once('open', async () => {
31
+ const query = this.dispatcher?.dispatchCommand({
32
+ command: 'init',
33
+ params: { options: { strategy, restore }, transfer: 'push' },
34
+ });
35
+ const res = (await query);
36
+ if (!res?.transferID) {
37
+ return reject(new providers_1.ProviderTransferError('Init failed, invalid response from the server'));
38
+ }
39
+ resolve(res.transferID);
40
+ })
41
+ .once('error', reject);
42
+ });
43
+ }
44
+ async bootstrap() {
45
+ const { url, auth } = this.options;
46
+ const validProtocols = ['https:', 'http:'];
47
+ let ws;
48
+ if (!validProtocols.includes(url.protocol)) {
49
+ throw new providers_1.ProviderValidationError(`Invalid protocol "${url.protocol}"`, {
50
+ check: 'url',
51
+ details: {
52
+ protocol: url.protocol,
53
+ validProtocols,
54
+ },
55
+ });
56
+ }
57
+ const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
58
+ const wsUrl = `${wsProtocol}//${url.host}${url.pathname}${constants_1.TRANSFER_PATH}`;
59
+ const validAuthMethods = ['token'];
60
+ // No auth defined, trying public access for transfer
61
+ if (!auth) {
62
+ ws = new ws_1.WebSocket(wsUrl);
63
+ }
64
+ // Common token auth, this should be the main auth method
65
+ else if (auth.type === 'token') {
66
+ const headers = { Authorization: `Bearer ${auth.token}` };
67
+ ws = new ws_1.WebSocket(wsUrl, { headers });
68
+ }
69
+ // Invalid auth method provided
70
+ else {
71
+ throw new providers_1.ProviderValidationError('Auth method not implemented', {
72
+ check: 'auth.type',
73
+ details: {
74
+ auth: auth.type,
75
+ validAuthMethods,
76
+ },
77
+ });
78
+ }
79
+ this.ws = ws;
80
+ this.dispatcher = (0, utils_1.createDispatcher)(this.ws);
81
+ const transferID = await this.initTransfer();
82
+ this.dispatcher.setTransferProperties({ id: transferID, kind: 'push' });
83
+ await this.dispatcher.dispatchTransferAction('bootstrap');
84
+ }
85
+ async close() {
86
+ await this.dispatcher?.dispatchTransferAction('close');
87
+ await new Promise((resolve) => {
88
+ const { ws } = this;
89
+ if (!ws || ws.CLOSED) {
90
+ resolve();
91
+ return;
92
+ }
93
+ ws.on('close', () => resolve()).close();
94
+ });
95
+ }
96
+ getMetadata() {
97
+ return this.dispatcher?.dispatchTransferAction('getMetadata') ?? null;
98
+ }
99
+ async beforeTransfer() {
100
+ await this.dispatcher?.dispatchTransferAction('beforeTransfer');
101
+ }
102
+ getSchemas() {
103
+ if (!this.dispatcher) {
104
+ return Promise.resolve(null);
105
+ }
106
+ return this.dispatcher.dispatchTransferAction('getSchemas');
107
+ }
108
+ createEntitiesWriteStream() {
109
+ return new stream_1.Writable({
110
+ objectMode: true,
111
+ write: async (entity, _encoding, callback) => {
112
+ const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'entities', entity);
113
+ callback(e);
114
+ },
115
+ });
116
+ }
117
+ createLinksWriteStream() {
118
+ return new stream_1.Writable({
119
+ objectMode: true,
120
+ write: async (link, _encoding, callback) => {
121
+ const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'links', link);
122
+ callback(e);
123
+ },
124
+ });
125
+ }
126
+ createConfigurationWriteStream() {
127
+ return new stream_1.Writable({
128
+ objectMode: true,
129
+ write: async (configuration, _encoding, callback) => {
130
+ const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'configuration', configuration);
131
+ callback(e);
132
+ },
133
+ });
134
+ }
135
+ createAssetsWriteStream() {
136
+ return new stream_1.Writable({
137
+ objectMode: true,
138
+ final: async (callback) => {
139
+ // TODO: replace this stream call by an end call
140
+ const e = await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', null);
141
+ callback(e);
142
+ },
143
+ write: async (asset, _encoding, callback) => {
144
+ const { filename, filepath, stats, stream } = asset;
145
+ const assetID = (0, uuid_1.v4)();
146
+ await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', {
147
+ action: 'start',
148
+ assetID,
149
+ data: { filename, filepath, stats },
150
+ });
151
+ for await (const chunk of stream) {
152
+ await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', {
153
+ action: 'stream',
154
+ assetID,
155
+ data: chunk,
156
+ });
157
+ }
158
+ await __classPrivateFieldGet(this, _RemoteStrapiDestinationProvider_instances, "m", _RemoteStrapiDestinationProvider_streamStep).call(this, 'assets', {
159
+ action: 'end',
160
+ assetID,
161
+ });
162
+ callback();
163
+ },
164
+ });
165
+ }
166
+ }
167
+ _RemoteStrapiDestinationProvider_instances = new WeakSet(), _RemoteStrapiDestinationProvider_streamStep = async function _RemoteStrapiDestinationProvider_streamStep(step, data) {
168
+ try {
169
+ await this.dispatcher?.dispatchTransferStep({ action: 'stream', step, data });
170
+ }
171
+ catch (e) {
172
+ if (e instanceof Error) {
173
+ return e;
174
+ }
175
+ if (typeof e === 'string') {
176
+ return new providers_1.ProviderTransferError(e);
177
+ }
178
+ return new providers_1.ProviderTransferError('Unexpected error');
179
+ }
180
+ return null;
181
+ };
182
+ const createRemoteStrapiDestinationProvider = (options) => {
183
+ return new RemoteStrapiDestinationProvider(options);
184
+ };
185
+ exports.createRemoteStrapiDestinationProvider = createRemoteStrapiDestinationProvider;
186
+ //# 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
@@ -1,5 +1,5 @@
1
- import { ILink } from '../../../../types';
2
- export declare const createLinkQuery: (strapi: Strapi.Strapi) => () => {
1
+ import { ILink } from '../../../types';
2
+ export declare const createLinkQuery: (strapi: Strapi.Strapi, trx?: any) => () => {
3
3
  generateAll: (uid: string) => AsyncGenerator<ILink>;
4
4
  generateAllForAttribute: (uid: string, fieldName: string) => AsyncGenerator<ILink>;
5
5
  insert: (link: ILink) => Promise<void>;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createLinkQuery = void 0;
4
4
  const fp_1 = require("lodash/fp");
5
5
  // TODO: Remove any types when we'll have types for DB metadata
6
- const createLinkQuery = (strapi) => {
6
+ const createLinkQuery = (strapi, trx) => {
7
7
  const query = () => {
8
8
  const { connection } = strapi.db;
9
9
  async function* generateAllForAttribute(uid, fieldName) {
@@ -23,6 +23,9 @@ const createLinkQuery = (strapi) => {
23
23
  if (attribute.joinColumn) {
24
24
  const joinColumnName = attribute.joinColumn.name;
25
25
  const qb = connection.queryBuilder().select('id', joinColumnName).from(metadata.tableName);
26
+ if (trx) {
27
+ qb.transacting(trx);
28
+ }
26
29
  // TODO: stream the query to improve performances
27
30
  const entries = await qb;
28
31
  for (const entry of entries) {
@@ -77,6 +80,9 @@ const createLinkQuery = (strapi) => {
77
80
  columns.right.order,
78
81
  ].filter((column) => !(0, fp_1.isNil)(column));
79
82
  qb.select(validColumns);
83
+ if (trx) {
84
+ qb.transacting(trx);
85
+ }
80
86
  // TODO: stream the query to improve performances
81
87
  const entries = await qb;
82
88
  for (const entry of entries) {
@@ -127,9 +133,13 @@ const createLinkQuery = (strapi) => {
127
133
  const payload = {};
128
134
  if (attribute.joinColumn) {
129
135
  const joinColumnName = attribute.joinColumn.name;
130
- await connection(metadata.tableName)
136
+ const qb = connection(metadata.tableName)
131
137
  .where('id', left.ref)
132
138
  .update({ [joinColumnName]: right.ref });
139
+ if (trx) {
140
+ qb.transacting(trx);
141
+ }
142
+ await qb;
133
143
  }
134
144
  if (attribute.joinTable) {
135
145
  const { name, joinColumn, inverseJoinColumn, orderColumnName, inverseOrderColumnName, morphColumn, } = attribute.joinTable;
@@ -168,7 +178,11 @@ const createLinkQuery = (strapi) => {
168
178
  assignMorphColumns();
169
179
  }
170
180
  assignOrderColumns();
171
- await connection.insert(payload).into(name);
181
+ const qb = connection.insert(payload).into(name);
182
+ if (trx) {
183
+ qb.transacting(trx);
184
+ }
185
+ await qb;
172
186
  }
173
187
  };
174
188
  return { generateAll, generateAllForAttribute, insert };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * This is intended to be called on Strapi register phase.
3
+ *
4
+ * It registers a transfer route in the Strapi admin router.
5
+ */
6
+ declare const register: (strapi: Strapi.Strapi) => void;
7
+ export default register;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const remote_1 = require("./remote");
4
+ /**
5
+ * This is intended to be called on Strapi register phase.
6
+ *
7
+ * It registers a transfer route in the Strapi admin router.
8
+ */
9
+ const register = (strapi) => {
10
+ remote_1.routes.registerAdminTransferRoute(strapi);
11
+ };
12
+ exports.default = register;
13
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1,2 @@
1
+ export declare const TRANSFER_PATH = "/transfer";
2
+ export declare const TRANSFER_METHODS: string[];
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TRANSFER_METHODS = exports.TRANSFER_PATH = void 0;
4
+ exports.TRANSFER_PATH = '/transfer';
5
+ exports.TRANSFER_METHODS = ['push', 'pull'];
6
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ export * from './push';
@@ -0,0 +1,18 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./push"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,25 @@
1
+ /// <reference types="node" />
2
+ import { Writable } from 'stream-chain';
3
+ import type { IMetadata } from '../../../../types';
4
+ import type { TransferPushMessage, TransferPushStep } from '../../../../types/remote/protocol/client';
5
+ import { ILocalStrapiDestinationProviderOptions } from '../../providers';
6
+ export interface IPushController {
7
+ streams: {
8
+ [stage in TransferPushStep]?: Writable;
9
+ };
10
+ actions: {
11
+ getMetadata(): Promise<IMetadata>;
12
+ getSchemas(): Strapi.Schemas;
13
+ bootstrap(): Promise<void>;
14
+ close(): Promise<void>;
15
+ beforeTransfer(): Promise<void>;
16
+ };
17
+ transfer: {
18
+ [key in TransferPushStep]: <T extends TransferPushMessage>(value: T extends {
19
+ step: key;
20
+ data: infer U;
21
+ } ? U : never) => Promise<void>;
22
+ };
23
+ }
24
+ declare const createPushController: (options: ILocalStrapiDestinationProviderOptions) => IPushController;
25
+ export default createPushController;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const stream_chain_1 = require("stream-chain");
4
+ const providers_1 = require("../../providers");
5
+ const createPushController = (options) => {
6
+ const provider = (0, providers_1.createLocalStrapiDestinationProvider)(options);
7
+ const streams = {};
8
+ const assets = {};
9
+ const writeAsync = (stream, data) => {
10
+ return new Promise((resolve, reject) => {
11
+ stream.write(data, (error) => {
12
+ if (error) {
13
+ reject(error);
14
+ }
15
+ resolve();
16
+ });
17
+ });
18
+ };
19
+ return {
20
+ streams,
21
+ actions: {
22
+ async getSchemas() {
23
+ return provider.getSchemas();
24
+ },
25
+ async getMetadata() {
26
+ return provider.getMetadata();
27
+ },
28
+ async bootstrap() {
29
+ return provider.bootstrap();
30
+ },
31
+ async close() {
32
+ return provider.close();
33
+ },
34
+ async beforeTransfer() {
35
+ return provider.beforeTransfer();
36
+ },
37
+ },
38
+ transfer: {
39
+ async entities(entity) {
40
+ if (!streams.entities) {
41
+ streams.entities = provider.createEntitiesWriteStream();
42
+ }
43
+ await writeAsync(streams.entities, entity);
44
+ },
45
+ async links(link) {
46
+ if (!streams.links) {
47
+ streams.links = await provider.createLinksWriteStream();
48
+ }
49
+ await writeAsync(streams.links, link);
50
+ },
51
+ async configuration(config) {
52
+ if (!streams.configuration) {
53
+ streams.configuration = await provider.createConfigurationWriteStream();
54
+ }
55
+ await writeAsync(streams.configuration, config);
56
+ },
57
+ async assets(payload) {
58
+ // TODO: close the stream upong receiving an 'end' event instead
59
+ if (payload === null) {
60
+ streams.assets?.end();
61
+ return;
62
+ }
63
+ const { action, assetID } = payload;
64
+ if (!streams.assets) {
65
+ streams.assets = await provider.createAssetsWriteStream();
66
+ }
67
+ if (action === 'start') {
68
+ assets[assetID] = { ...payload.data, stream: new stream_chain_1.PassThrough() };
69
+ writeAsync(streams.assets, assets[assetID]);
70
+ }
71
+ if (action === 'stream') {
72
+ // The buffer has gone through JSON operations and is now of shape { type: "Buffer"; data: UInt8Array }
73
+ // We need to transform it back into a Buffer instance
74
+ const rawBuffer = payload.data;
75
+ const chunk = Buffer.from(rawBuffer.data);
76
+ await writeAsync(assets[assetID].stream, chunk);
77
+ }
78
+ if (action === 'end') {
79
+ await new Promise((resolve, reject) => {
80
+ const { stream } = assets[assetID];
81
+ stream
82
+ .on('close', () => {
83
+ delete assets[assetID];
84
+ resolve();
85
+ })
86
+ .on('error', reject)
87
+ .end();
88
+ });
89
+ }
90
+ },
91
+ },
92
+ };
93
+ };
94
+ exports.default = createPushController;
95
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1,3 @@
1
+ import type { Context } from 'koa';
2
+ import type { ServerOptions } from 'ws';
3
+ export declare const createTransferHandler: (options?: ServerOptions) => (ctx: Context) => Promise<void>;