@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
@@ -43,7 +43,9 @@ const stream_1 = require("stream");
43
43
  const path_1 = __importDefault(require("path"));
44
44
  const fse = __importStar(require("fs-extra"));
45
45
  const strategies_1 = require("./strategies");
46
- const utils = __importStar(require("../../utils"));
46
+ const utils = __importStar(require("../../../utils"));
47
+ const providers_1 = require("../../../errors/providers");
48
+ const providers_2 = require("../../../utils/providers");
47
49
  exports.VALID_CONFLICT_STRATEGIES = ['restore', 'merge'];
48
50
  exports.DEFAULT_CONFLICT_STRATEGY = 'restore';
49
51
  class LocalStrapiDestinationProvider {
@@ -51,6 +53,9 @@ class LocalStrapiDestinationProvider {
51
53
  _LocalStrapiDestinationProvider_instances.add(this);
52
54
  this.name = 'destination::local-strapi';
53
55
  this.type = 'destination';
56
+ /**
57
+ * The entities mapper is used to map old entities to their new IDs
58
+ */
54
59
  _LocalStrapiDestinationProvider_entitiesMapper.set(this, void 0);
55
60
  this.options = options;
56
61
  __classPrivateFieldSet(this, _LocalStrapiDestinationProvider_entitiesMapper, {}, "f");
@@ -58,45 +63,54 @@ class LocalStrapiDestinationProvider {
58
63
  async bootstrap() {
59
64
  __classPrivateFieldGet(this, _LocalStrapiDestinationProvider_instances, "m", _LocalStrapiDestinationProvider_validateOptions).call(this);
60
65
  this.strapi = await this.options.getStrapi();
66
+ this.transaction = utils.transaction.createTransaction(this.strapi);
61
67
  }
62
68
  async close() {
63
- await this.strapi?.destroy?.();
69
+ const { autoDestroy } = this.options;
70
+ this.transaction?.end();
71
+ // Basically `!== false` but more deterministic
72
+ if (autoDestroy === undefined || autoDestroy === true) {
73
+ await this.strapi?.destroy();
74
+ }
75
+ }
76
+ rollback() {
77
+ this.transaction?.rollback();
64
78
  }
65
79
  async beforeTransfer() {
66
- if (this.options.strategy === 'restore') {
67
- await __classPrivateFieldGet(this, _LocalStrapiDestinationProvider_instances, "m", _LocalStrapiDestinationProvider_deleteAll).call(this);
80
+ if (!this.strapi) {
81
+ throw new Error('Strapi instance not found');
68
82
  }
83
+ await this.transaction?.attach(async () => {
84
+ try {
85
+ if (this.options.strategy === 'restore') {
86
+ await __classPrivateFieldGet(this, _LocalStrapiDestinationProvider_instances, "m", _LocalStrapiDestinationProvider_deleteAll).call(this);
87
+ }
88
+ }
89
+ catch (error) {
90
+ throw new Error(`restore failed ${error}`);
91
+ }
92
+ });
69
93
  }
70
94
  getMetadata() {
71
95
  const strapiVersion = strapi.config.get('info.strapi');
72
96
  const createdAt = new Date().toISOString();
73
- const plugins = Object.keys(strapi.plugins);
74
97
  return {
75
98
  createdAt,
76
99
  strapi: {
77
100
  version: strapiVersion,
78
- plugins: plugins.map((name) => ({
79
- name,
80
- // TODO: Get the plugin actual version when it'll be available
81
- version: strapiVersion,
82
- })),
83
101
  },
84
102
  };
85
103
  }
86
104
  getSchemas() {
87
- if (!this.strapi) {
88
- throw new Error('Not able to get Schemas. Strapi instance not found');
89
- }
105
+ (0, providers_2.assertValidStrapi)(this.strapi, 'Not able to get Schemas');
90
106
  const schemas = {
91
107
  ...this.strapi.contentTypes,
92
108
  ...this.strapi.components,
93
109
  };
94
110
  return utils.schema.mapSchemasValues(schemas);
95
111
  }
96
- getEntitiesStream() {
97
- if (!this.strapi) {
98
- throw new Error('Not able to import entities. Strapi instance not found');
99
- }
112
+ createEntitiesWriteStream() {
113
+ (0, providers_2.assertValidStrapi)(this.strapi, 'Not able to import entities');
100
114
  const { strategy } = this.options;
101
115
  const updateMappingTable = (type, oldID, newID) => {
102
116
  if (!__classPrivateFieldGet(this, _LocalStrapiDestinationProvider_entitiesMapper, "f")[type]) {
@@ -108,18 +122,24 @@ class LocalStrapiDestinationProvider {
108
122
  return strategies_1.restore.createEntitiesWriteStream({
109
123
  strapi: this.strapi,
110
124
  updateMappingTable,
125
+ transaction: this.transaction,
111
126
  });
112
127
  }
113
- throw new Error(`Invalid strategy supplied: "${strategy}"`);
128
+ throw new providers_1.ProviderValidationError(`Invalid strategy ${this.options.strategy}`, {
129
+ check: 'strategy',
130
+ strategy: this.options.strategy,
131
+ validStrategies: exports.VALID_CONFLICT_STRATEGIES,
132
+ });
114
133
  }
115
- async getAssetsStream() {
116
- if (!this.strapi) {
117
- throw new Error('Not able to stream Assets. Strapi instance not found');
118
- }
134
+ // TODO: Move this logic to the restore strategy
135
+ async createAssetsWriteStream() {
136
+ (0, providers_2.assertValidStrapi)(this.strapi, 'Not able to stream Assets');
119
137
  const assetsDirectory = path_1.default.join(this.strapi.dirs.static.public, 'uploads');
120
138
  const backupDirectory = path_1.default.join(this.strapi.dirs.static.public, `uploads_backup_${Date.now()}`);
121
139
  await fse.rename(assetsDirectory, backupDirectory);
122
140
  await fse.mkdir(assetsDirectory);
141
+ // Create a .gitkeep file to ensure the directory is not empty
142
+ await fse.outputFile(path_1.default.join(assetsDirectory, '.gitkeep'), '');
123
143
  return new stream_1.Writable({
124
144
  objectMode: true,
125
145
  async final(next) {
@@ -136,10 +156,10 @@ class LocalStrapiDestinationProvider {
136
156
  try {
137
157
  await fse.rm(assetsDirectory, { recursive: true, force: true });
138
158
  await fse.rename(backupDirectory, assetsDirectory);
139
- this.destroy(new Error(`There was an error during the transfer process. The original files have been restored to ${assetsDirectory}`));
159
+ this.destroy(new providers_1.ProviderTransferError(`There was an error during the transfer process. The original files have been restored to ${assetsDirectory}`));
140
160
  }
141
161
  catch (err) {
142
- throw new Error(`There was an error doing the rollback process. The original files are in ${backupDirectory}, but we failed to restore them to ${assetsDirectory}`);
162
+ throw new providers_1.ProviderTransferError(`There was an error doing the rollback process. The original files are in ${backupDirectory}, but we failed to restore them to ${assetsDirectory}`);
143
163
  }
144
164
  finally {
145
165
  callback(error);
@@ -148,36 +168,44 @@ class LocalStrapiDestinationProvider {
148
168
  },
149
169
  });
150
170
  }
151
- async getConfigurationStream() {
152
- if (!this.strapi) {
153
- throw new Error('Not able to stream Configurations. Strapi instance not found');
154
- }
171
+ async createConfigurationWriteStream() {
172
+ (0, providers_2.assertValidStrapi)(this.strapi, 'Not able to stream Configurations');
155
173
  const { strategy } = this.options;
156
174
  if (strategy === 'restore') {
157
- return strategies_1.restore.createConfigurationWriteStream(this.strapi);
175
+ return strategies_1.restore.createConfigurationWriteStream(this.strapi, this.transaction);
158
176
  }
159
- throw new Error(`Invalid strategy supplied: "${strategy}"`);
177
+ throw new providers_1.ProviderValidationError(`Invalid strategy ${strategy}`, {
178
+ check: 'strategy',
179
+ strategy,
180
+ validStrategies: exports.VALID_CONFLICT_STRATEGIES,
181
+ });
160
182
  }
161
- async getLinksStream() {
183
+ async createLinksWriteStream() {
162
184
  if (!this.strapi) {
163
185
  throw new Error('Not able to stream links. Strapi instance not found');
164
186
  }
165
187
  const { strategy } = this.options;
166
188
  const mapID = (uid, id) => __classPrivateFieldGet(this, _LocalStrapiDestinationProvider_entitiesMapper, "f")[uid]?.[id];
167
189
  if (strategy === 'restore') {
168
- return strategies_1.restore.createLinksWriteStream(mapID, this.strapi);
190
+ return strategies_1.restore.createLinksWriteStream(mapID, this.strapi, this.transaction);
169
191
  }
170
- throw new Error(`Invalid strategy supplied: "${strategy}"`);
192
+ throw new providers_1.ProviderValidationError(`Invalid strategy ${strategy}`, {
193
+ check: 'strategy',
194
+ strategy,
195
+ validStrategies: exports.VALID_CONFLICT_STRATEGIES,
196
+ });
171
197
  }
172
198
  }
173
199
  _LocalStrapiDestinationProvider_entitiesMapper = new WeakMap(), _LocalStrapiDestinationProvider_instances = new WeakSet(), _LocalStrapiDestinationProvider_validateOptions = function _LocalStrapiDestinationProvider_validateOptions() {
174
200
  if (!exports.VALID_CONFLICT_STRATEGIES.includes(this.options.strategy)) {
175
- throw new Error(`Invalid stategy ${this.options.strategy}`);
201
+ throw new providers_1.ProviderValidationError(`Invalid strategy ${this.options.strategy}`, {
202
+ check: 'strategy',
203
+ strategy: this.options.strategy,
204
+ validStrategies: exports.VALID_CONFLICT_STRATEGIES,
205
+ });
176
206
  }
177
207
  }, _LocalStrapiDestinationProvider_deleteAll = async function _LocalStrapiDestinationProvider_deleteAll() {
178
- if (!this.strapi) {
179
- throw new Error('Strapi instance not found');
180
- }
208
+ (0, providers_2.assertValidStrapi)(this.strapi);
181
209
  return strategies_1.restore.deleteRecords(this.strapi, this.options.restore);
182
210
  };
183
211
  const createLocalStrapiDestinationProvider = (options) => {
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  import { Writable } from 'stream';
3
- import { IConfiguration } from '../../../../../types';
3
+ import { IConfiguration, Transaction } from '../../../../../../types';
4
4
  export declare const restoreConfigs: (strapi: Strapi.Strapi, config: IConfiguration) => Promise<any>;
5
- export declare const createConfigurationWriteStream: (strapi: Strapi.Strapi) => Promise<Writable>;
5
+ export declare const createConfigurationWriteStream: (strapi: Strapi.Strapi, transaction?: Transaction | undefined) => Promise<Writable>;
@@ -4,9 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createConfigurationWriteStream = exports.restoreConfigs = void 0;
7
+ const fp_1 = require("lodash/fp");
7
8
  const stream_1 = require("stream");
8
9
  const chalk_1 = __importDefault(require("chalk"));
9
- const restoreCoreStore = async (strapi, data) => {
10
+ const providers_1 = require("../../../../../errors/providers");
11
+ const omitInvalidCreationAttributes = (0, fp_1.omit)(['id']);
12
+ const restoreCoreStore = async (strapi, values) => {
13
+ const data = omitInvalidCreationAttributes(values);
10
14
  return strapi.db.query('strapi::core-store').create({
11
15
  data: {
12
16
  ...data,
@@ -14,7 +18,8 @@ const restoreCoreStore = async (strapi, data) => {
14
18
  },
15
19
  });
16
20
  };
17
- const restoreWebhooks = async (strapi, data) => {
21
+ const restoreWebhooks = async (strapi, values) => {
22
+ const data = omitInvalidCreationAttributes(values);
18
23
  return strapi.db.query('webhook').create({ data });
19
24
  };
20
25
  const restoreConfigs = async (strapi, config) => {
@@ -26,17 +31,19 @@ const restoreConfigs = async (strapi, config) => {
26
31
  }
27
32
  };
28
33
  exports.restoreConfigs = restoreConfigs;
29
- const createConfigurationWriteStream = async (strapi) => {
34
+ const createConfigurationWriteStream = async (strapi, transaction) => {
30
35
  return new stream_1.Writable({
31
36
  objectMode: true,
32
37
  async write(config, _encoding, callback) {
33
- try {
34
- await (0, exports.restoreConfigs)(strapi, config);
35
- }
36
- catch (error) {
37
- return callback(new Error(`Failed to import ${chalk_1.default.yellowBright(config.type)} (${chalk_1.default.greenBright(config.value.id)}`));
38
- }
39
- callback();
38
+ await transaction?.attach(async () => {
39
+ try {
40
+ await (0, exports.restoreConfigs)(strapi, config);
41
+ }
42
+ catch (error) {
43
+ return callback(new providers_1.ProviderTransferError(`Failed to import ${chalk_1.default.yellowBright(config.type)} (${chalk_1.default.greenBright(config.value.id)}`));
44
+ }
45
+ callback();
46
+ });
40
47
  },
41
48
  });
42
49
  };
@@ -1,9 +1,11 @@
1
1
  /// <reference types="node" />
2
2
  import type { SchemaUID } from '@strapi/strapi/lib/types/utils';
3
3
  import { Writable } from 'stream';
4
+ import type { Transaction } from '../../../../../../types';
4
5
  interface IEntitiesRestoreStreamOptions {
5
6
  strapi: Strapi.Strapi;
6
7
  updateMappingTable<T extends SchemaUID | string>(type: T, oldID: number, newID: number): void;
8
+ transaction?: Transaction;
7
9
  }
8
10
  declare const createEntitiesWriteStream: (options: IEntitiesRestoreStreamOptions) => Writable;
9
11
  export { createEntitiesWriteStream };
@@ -0,0 +1,103 @@
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.createEntitiesWriteStream = void 0;
27
+ const fp_1 = require("lodash/fp");
28
+ const stream_1 = require("stream");
29
+ const providers_1 = require("../../../../../errors/providers");
30
+ const utils_1 = require("../../../../../utils");
31
+ const queries = __importStar(require("../../../../queries"));
32
+ const createEntitiesWriteStream = (options) => {
33
+ const { strapi, updateMappingTable, transaction } = options;
34
+ const query = queries.entity.createEntityQuery(strapi);
35
+ return new stream_1.Writable({
36
+ objectMode: true,
37
+ async write(entity, _encoding, callback) {
38
+ await transaction?.attach(async () => {
39
+ const { type, id, data } = entity;
40
+ const { create, getDeepPopulateComponentLikeQuery } = query(type);
41
+ const contentType = strapi.getModel(type);
42
+ /**
43
+ * Resolve the component UID of an entity's attribute based
44
+ * on a given path (components & dynamic zones only)
45
+ */
46
+ const resolveType = (paths) => {
47
+ let cType = contentType;
48
+ let value = data;
49
+ for (const path of paths) {
50
+ value = (0, fp_1.get)(path, value);
51
+ // Needed when the value of cType should be computed
52
+ // based on the next value (eg: dynamic zones)
53
+ if (typeof cType === 'function') {
54
+ cType = cType(value);
55
+ }
56
+ if (path in cType.attributes) {
57
+ const attribute = cType.attributes[path];
58
+ if (attribute.type === 'component') {
59
+ cType = strapi.getModel(attribute.component);
60
+ }
61
+ if (attribute.type === 'dynamiczone') {
62
+ cType = ({ __component }) => strapi.getModel(__component);
63
+ }
64
+ }
65
+ }
66
+ return cType?.uid;
67
+ };
68
+ try {
69
+ const created = await create({
70
+ data,
71
+ populate: getDeepPopulateComponentLikeQuery(contentType, { select: 'id' }),
72
+ select: 'id',
73
+ });
74
+ // Compute differences between original & new entities
75
+ const diffs = utils_1.json.diff(data, created);
76
+ updateMappingTable(type, id, created.id);
77
+ // For each difference found on an ID attribute,
78
+ // update the mapping the table accordingly
79
+ diffs.forEach((diff) => {
80
+ if (diff.kind === 'modified' && (0, fp_1.last)(diff.path) === 'id') {
81
+ const target = resolveType(diff.path);
82
+ // If no type is found for the given path, then ignore the diff
83
+ if (!target) {
84
+ return;
85
+ }
86
+ const [oldID, newID] = diff.values;
87
+ updateMappingTable(target, oldID, newID);
88
+ }
89
+ });
90
+ }
91
+ catch (e) {
92
+ if (e instanceof Error) {
93
+ return callback(e);
94
+ }
95
+ return callback(new providers_1.ProviderTransferError(`Failed to create "${type}" (${id})`));
96
+ }
97
+ return callback(null);
98
+ });
99
+ },
100
+ });
101
+ };
102
+ exports.createEntitiesWriteStream = createEntitiesWriteStream;
103
+ //# sourceMappingURL=entities.js.map
@@ -27,7 +27,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.deleteRecords = void 0;
30
- const shared = __importStar(require("../../../shared"));
30
+ const providers_1 = require("../../../../../errors/providers");
31
+ const queries = __importStar(require("../../../../queries"));
31
32
  const deleteRecords = async (strapi, options) => {
32
33
  const entities = await deleteEntitiesRecord(strapi, options);
33
34
  const configuration = await deleteConfigurationRecords(strapi, options);
@@ -40,7 +41,7 @@ const deleteRecords = async (strapi, options) => {
40
41
  exports.deleteRecords = deleteRecords;
41
42
  const deleteEntitiesRecord = async (strapi, options = {}) => {
42
43
  const { entities } = options;
43
- const query = shared.strapi.entity.createEntityQuery(strapi);
44
+ const query = queries.entity.createEntityQuery(strapi);
44
45
  const contentTypes = Object.values(strapi.contentTypes);
45
46
  const contentTypesToClear = contentTypes.filter((contentType) => {
46
47
  let keep = true;
@@ -92,7 +93,7 @@ const useResults = (keys) => {
92
93
  const update = (count, key) => {
93
94
  if (key) {
94
95
  if (!(key in results.aggregate)) {
95
- throw new Error(`Unknown key "${key}" provided in results update`);
96
+ throw new providers_1.ProviderTransferError(`Unknown key "${key}" provided in results update`);
96
97
  }
97
98
  results.aggregate[key].count += count;
98
99
  }
@@ -0,0 +1,4 @@
1
+ /// <reference types="node" />
2
+ import { Writable } from 'stream';
3
+ import { Transaction } from '../../../../../../types';
4
+ export declare const createLinksWriteStream: (mapID: (uid: string, id: number) => number | undefined, strapi: Strapi.Strapi, transaction?: Transaction | undefined) => Writable;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLinksWriteStream = void 0;
4
+ const stream_1 = require("stream");
5
+ const providers_1 = require("../../../../../errors/providers");
6
+ const link_1 = require("../../../../queries/link");
7
+ const createLinksWriteStream = (mapID, strapi, transaction) => {
8
+ return new stream_1.Writable({
9
+ objectMode: true,
10
+ async write(link, _encoding, callback) {
11
+ await transaction?.attach(async (trx) => {
12
+ const { left, right } = link;
13
+ const query = (0, link_1.createLinkQuery)(strapi, trx);
14
+ // Map IDs if needed
15
+ left.ref = mapID(left.type, left.ref) ?? left.ref;
16
+ right.ref = mapID(right.type, right.ref) ?? right.ref;
17
+ try {
18
+ await query().insert(link);
19
+ }
20
+ catch (e) {
21
+ if (e instanceof Error) {
22
+ return callback(e);
23
+ }
24
+ return callback(new providers_1.ProviderTransferError(`An error happened while trying to import a ${left.type} link.`));
25
+ }
26
+ callback(null);
27
+ });
28
+ },
29
+ });
30
+ };
31
+ exports.createLinksWriteStream = createLinksWriteStream;
32
+ //# sourceMappingURL=links.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
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;
@@ -25,7 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.createEntitiesTransformStream = exports.createEntitiesStream = void 0;
27
27
  const stream_1 = require("stream");
28
- const shared = __importStar(require("../shared/strapi"));
28
+ const shared = __importStar(require("../../queries"));
29
29
  /**
30
30
  * Generate and consume content-types streams in order to stream each entity individually
31
31
  */
@@ -48,10 +48,17 @@ const createEntitiesStream = (strapi) => {
48
48
  }
49
49
  return stream_1.Readable.from((async function* entitiesGenerator() {
50
50
  for await (const { stream, contentType } of contentTypeStreamGenerator()) {
51
- for await (const entity of stream) {
52
- yield { entity, contentType };
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();
53
61
  }
54
- stream.destroy();
55
62
  }
56
63
  })());
57
64
  };
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="lodash" />
3
3
  import { Readable } from 'stream';
4
- import type { IMetadata, ISourceProvider, ProviderType } from '../../../types';
4
+ import type { IMetadata, ISourceProvider, ProviderType } from '../../../../types';
5
5
  export interface ILocalStrapiSourceProviderOptions {
6
6
  getStrapi(): Strapi.Strapi | Promise<Strapi.Strapi>;
7
7
  autoDestroy?: boolean;
@@ -16,12 +16,12 @@ declare class LocalStrapiSourceProvider implements ISourceProvider {
16
16
  bootstrap(): Promise<void>;
17
17
  close(): Promise<void>;
18
18
  getMetadata(): IMetadata;
19
- streamEntities(): Promise<Readable>;
20
- streamLinks(): Readable;
21
- streamConfiguration(): Readable;
19
+ createEntitiesReadStream(): Promise<Readable>;
20
+ createLinksReadStream(): Readable;
21
+ createConfigurationReadStream(): Readable;
22
22
  getSchemas(): import("lodash").Dictionary<Partial<import("@strapi/strapi").Schema>>;
23
- streamSchemas(): Readable;
24
- streamAssets(): Readable;
23
+ createSchemasReadStream(): Readable;
24
+ createAssetsReadStream(): Readable;
25
25
  }
26
26
  export declare type ILocalStrapiSourceProvider = InstanceType<typeof LocalStrapiSourceProvider>;
27
27
  export {};
@@ -30,7 +30,8 @@ const entities_1 = require("./entities");
30
30
  const links_1 = require("./links");
31
31
  const configuration_1 = require("./configuration");
32
32
  const assets_1 = require("./assets");
33
- const utils = __importStar(require("../../utils"));
33
+ const utils = __importStar(require("../../../utils"));
34
+ const providers_1 = require("../../../utils/providers");
34
35
  const createLocalStrapiSourceProvider = (options) => {
35
36
  return new LocalStrapiSourceProvider(options);
36
37
  };
@@ -54,23 +55,15 @@ class LocalStrapiSourceProvider {
54
55
  getMetadata() {
55
56
  const strapiVersion = strapi.config.get('info.strapi');
56
57
  const createdAt = new Date().toISOString();
57
- const plugins = Object.keys(strapi.plugins);
58
58
  return {
59
59
  createdAt,
60
60
  strapi: {
61
61
  version: strapiVersion,
62
- plugins: plugins.map((name) => ({
63
- name,
64
- // TODO: Get the plugin actual version when it'll be available
65
- version: strapiVersion,
66
- })),
67
62
  },
68
63
  };
69
64
  }
70
- async streamEntities() {
71
- if (!this.strapi) {
72
- throw new Error('Not able to stream entities. Strapi instance not found');
73
- }
65
+ async createEntitiesReadStream() {
66
+ (0, providers_1.assertValidStrapi)(this.strapi, 'Not able to stream entities');
74
67
  return (0, stream_chain_1.chain)([
75
68
  // Entities stream
76
69
  (0, entities_1.createEntitiesStream)(this.strapi),
@@ -78,35 +71,27 @@ class LocalStrapiSourceProvider {
78
71
  (0, entities_1.createEntitiesTransformStream)(),
79
72
  ]);
80
73
  }
81
- streamLinks() {
82
- if (!this.strapi) {
83
- throw new Error('Not able to stream links. Strapi instance not found');
84
- }
74
+ createLinksReadStream() {
75
+ (0, providers_1.assertValidStrapi)(this.strapi, 'Not able to stream links');
85
76
  return (0, links_1.createLinksStream)(this.strapi);
86
77
  }
87
- streamConfiguration() {
88
- if (!this.strapi) {
89
- throw new Error('Not able to stream configuration. Strapi instance not found');
90
- }
78
+ createConfigurationReadStream() {
79
+ (0, providers_1.assertValidStrapi)(this.strapi, 'Not able to stream configuration');
91
80
  return (0, configuration_1.createConfigurationStream)(strapi);
92
81
  }
93
82
  getSchemas() {
94
- if (!this.strapi) {
95
- throw new Error('Not able to get Schemas. Strapi instance not found');
96
- }
83
+ (0, providers_1.assertValidStrapi)(this.strapi, 'Not able to get Schemas');
97
84
  const schemas = {
98
85
  ...this.strapi.contentTypes,
99
86
  ...this.strapi.components,
100
87
  };
101
88
  return utils.schema.mapSchemasValues(schemas);
102
89
  }
103
- streamSchemas() {
90
+ createSchemasReadStream() {
104
91
  return stream_1.Readable.from(Object.values(this.getSchemas()));
105
92
  }
106
- streamAssets() {
107
- if (!this.strapi) {
108
- throw new Error('Not able to stream assets. Strapi instance not found');
109
- }
93
+ createAssetsReadStream() {
94
+ (0, providers_1.assertValidStrapi)(this.strapi, 'Not able to stream assets');
110
95
  return (0, assets_1.createAssetsStream)(this.strapi);
111
96
  }
112
97
  }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createLinksStream = void 0;
4
4
  const stream_1 = require("stream");
5
- const link_1 = require("../shared/strapi/link");
5
+ const link_1 = require("../../queries/link");
6
6
  /**
7
7
  * Create a Readable which will stream all the links from a Strapi instance
8
8
  */