@strapi/data-transfer 4.20.5 → 5.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/index.d.ts +0 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +170 -1104
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +171 -1100
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/strapi/providers/local-destination/strategies/restore/index.d.ts.map +1 -1
  8. package/dist/strapi/providers/local-source/assets.d.ts +1 -0
  9. package/dist/strapi/providers/local-source/assets.d.ts.map +1 -1
  10. package/dist/strapi/providers/local-source/configuration.d.ts +1 -0
  11. package/dist/strapi/providers/local-source/configuration.d.ts.map +1 -1
  12. package/dist/strapi/providers/local-source/entities.d.ts +1 -0
  13. package/dist/strapi/providers/local-source/entities.d.ts.map +1 -1
  14. package/dist/strapi/providers/local-source/links.d.ts +1 -0
  15. package/dist/strapi/providers/local-source/links.d.ts.map +1 -1
  16. package/dist/strapi/providers/remote-source/index.d.ts.map +1 -1
  17. package/dist/strapi/remote/handlers/utils.d.ts +1 -1
  18. package/dist/strapi/remote/handlers/utils.d.ts.map +1 -1
  19. package/dist/utils/components.d.ts +1 -4
  20. package/dist/utils/components.d.ts.map +1 -1
  21. package/dist/utils/encryption/decrypt.d.ts +1 -0
  22. package/dist/utils/encryption/decrypt.d.ts.map +1 -1
  23. package/dist/utils/encryption/encrypt.d.ts +1 -0
  24. package/dist/utils/encryption/encrypt.d.ts.map +1 -1
  25. package/package.json +12 -15
  26. package/dist/commands/commander.d.ts +0 -36
  27. package/dist/commands/commander.d.ts.map +0 -1
  28. package/dist/commands/data-transfer.d.ts +0 -63
  29. package/dist/commands/data-transfer.d.ts.map +0 -1
  30. package/dist/commands/export/action.d.ts +0 -21
  31. package/dist/commands/export/action.d.ts.map +0 -1
  32. package/dist/commands/export/command.d.ts +0 -9
  33. package/dist/commands/export/command.d.ts.map +0 -1
  34. package/dist/commands/helpers.d.ts +0 -31
  35. package/dist/commands/helpers.d.ts.map +0 -1
  36. package/dist/commands/import/action.d.ts +0 -20
  37. package/dist/commands/import/action.d.ts.map +0 -1
  38. package/dist/commands/import/command.d.ts +0 -9
  39. package/dist/commands/import/command.d.ts.map +0 -1
  40. package/dist/commands/index.d.ts +0 -4
  41. package/dist/commands/index.d.ts.map +0 -1
  42. package/dist/commands/transfer/action.d.ts +0 -19
  43. package/dist/commands/transfer/action.d.ts.map +0 -1
  44. package/dist/commands/transfer/command.d.ts +0 -9
  45. package/dist/commands/transfer/command.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -12,20 +12,13 @@ const fse = require("fs-extra");
12
12
  const _ = require("lodash");
13
13
  const utils = require("@strapi/utils");
14
14
  const chalk = require("chalk");
15
- const https = require("https");
16
- const http = require("http");
15
+ const webStream = require("stream/web");
17
16
  const ws = require("ws");
18
17
  const zip = require("zlib");
19
18
  const tar = require("tar");
20
19
  const Parser = require("stream-json/jsonl/Parser");
21
20
  const tar$1 = require("tar-stream");
22
21
  const Stringer = require("stream-json/jsonl/Stringer");
23
- const commander = require("commander");
24
- const Table = require("cli-table3");
25
- const logger = require("@strapi/logger");
26
- const strapiFactory = require("@strapi/strapi");
27
- const ora = require("ora");
28
- const inquirer = require("inquirer");
29
22
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
30
23
  function _interopNamespace(e) {
31
24
  if (e && e.__esModule)
@@ -49,15 +42,10 @@ const path__default = /* @__PURE__ */ _interopDefault(path);
49
42
  const fse__namespace = /* @__PURE__ */ _interopNamespace(fse);
50
43
  const ___default = /* @__PURE__ */ _interopDefault(_);
51
44
  const chalk__default = /* @__PURE__ */ _interopDefault(chalk);
52
- const https__default = /* @__PURE__ */ _interopDefault(https);
53
- const http__default = /* @__PURE__ */ _interopDefault(http);
45
+ const webStream__namespace = /* @__PURE__ */ _interopNamespace(webStream);
54
46
  const zip__default = /* @__PURE__ */ _interopDefault(zip);
55
47
  const tar__default = /* @__PURE__ */ _interopDefault(tar);
56
48
  const tar__default$1 = /* @__PURE__ */ _interopDefault(tar$1);
57
- const Table__default = /* @__PURE__ */ _interopDefault(Table);
58
- const strapiFactory__default = /* @__PURE__ */ _interopDefault(strapiFactory);
59
- const ora__default = /* @__PURE__ */ _interopDefault(ora);
60
- const inquirer__default = /* @__PURE__ */ _interopDefault(inquirer);
61
49
  const getEncryptionStrategy = (algorithm) => {
62
50
  const strategies2 = {
63
51
  "aes-128-ecb"(key) {
@@ -122,7 +110,7 @@ const getDecryptionStrategy = (algorithm) => {
122
110
  const createDecryptionCipher = (key, algorithm = "aes-128-ecb") => {
123
111
  return getDecryptionStrategy(algorithm)(key);
124
112
  };
125
- const index$7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
113
+ const index$9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
126
114
  __proto__: null,
127
115
  createDecryptionCipher,
128
116
  createEncryptionCipher
@@ -334,9 +322,9 @@ const middleware = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
334
322
  __proto__: null,
335
323
  runMiddleware
336
324
  }, Symbol.toStringTag, { value: "Module" }));
337
- const index$6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
325
+ const index$8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
338
326
  __proto__: null,
339
- encryption: index$7,
327
+ encryption: index$9,
340
328
  json,
341
329
  middleware,
342
330
  schema,
@@ -399,11 +387,11 @@ class TransferEngineError extends DataTransferError {
399
387
  super("engine", severity, message, details);
400
388
  }
401
389
  }
402
- let TransferEngineInitializationError$1 = class TransferEngineInitializationError extends TransferEngineError {
390
+ class TransferEngineInitializationError extends TransferEngineError {
403
391
  constructor(message) {
404
392
  super(SeverityKind.FATAL, message, { step: "initialization" });
405
393
  }
406
- };
394
+ }
407
395
  class TransferEngineValidationError extends TransferEngineError {
408
396
  constructor(message, details) {
409
397
  super(SeverityKind.FATAL, message, { step: "validation", details });
@@ -417,7 +405,7 @@ class TransferEngineTransferError extends TransferEngineError {
417
405
  const errors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
418
406
  __proto__: null,
419
407
  TransferEngineError,
420
- TransferEngineInitializationError: TransferEngineInitializationError$1,
408
+ TransferEngineInitializationError,
421
409
  TransferEngineTransferError,
422
410
  TransferEngineValidationError
423
411
  }, Symbol.toStringTag, { value: "Module" }));
@@ -529,8 +517,8 @@ const TransferGroupPresets = {
529
517
  configuration: true
530
518
  }
531
519
  };
532
- const DEFAULT_VERSION_STRATEGY$1 = "ignore";
533
- const DEFAULT_SCHEMA_STRATEGY$1 = "strict";
520
+ const DEFAULT_VERSION_STRATEGY = "ignore";
521
+ const DEFAULT_SCHEMA_STRATEGY = "strict";
534
522
  class TransferEngine {
535
523
  sourceProvider;
536
524
  destinationProvider;
@@ -723,7 +711,7 @@ class TransferEngine {
723
711
  * If there is a mismatch, throws a validation error.
724
712
  */
725
713
  #assertStrapiVersionIntegrity(sourceVersion, destinationVersion) {
726
- const strategy = this.options.versionStrategy || DEFAULT_VERSION_STRATEGY$1;
714
+ const strategy = this.options.versionStrategy || DEFAULT_VERSION_STRATEGY;
727
715
  const reject2 = () => {
728
716
  throw new TransferEngineValidationError(
729
717
  `The source and destination provide are targeting incompatible Strapi versions (using the "${strategy}" strategy). The source (${this.sourceProvider.name}) version is ${sourceVersion} and the destination (${this.destinationProvider.name}) version is ${destinationVersion}`,
@@ -766,7 +754,7 @@ class TransferEngine {
766
754
  * If there are differences and/or incompatibilities between source and destination schemas, then throw a validation error.
767
755
  */
768
756
  #assertSchemasMatching(sourceSchemas, destinationSchemas) {
769
- const strategy = this.options.schemaStrategy || DEFAULT_SCHEMA_STRATEGY$1;
757
+ const strategy = this.options.schemaStrategy || DEFAULT_SCHEMA_STRATEGY;
770
758
  if (strategy === "ignore") {
771
759
  return;
772
760
  }
@@ -1143,16 +1131,16 @@ ${formattedDiffs}`,
1143
1131
  await this.#transferStage({ stage, source, destination, transform, tracker });
1144
1132
  }
1145
1133
  }
1146
- const createTransferEngine$2 = (sourceProvider, destinationProvider, options) => {
1134
+ const createTransferEngine = (sourceProvider, destinationProvider, options) => {
1147
1135
  return new TransferEngine(sourceProvider, destinationProvider, options);
1148
1136
  };
1149
- const engineDatatransfer = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1137
+ const index$7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1150
1138
  __proto__: null,
1151
- DEFAULT_SCHEMA_STRATEGY: DEFAULT_SCHEMA_STRATEGY$1,
1152
- DEFAULT_VERSION_STRATEGY: DEFAULT_VERSION_STRATEGY$1,
1139
+ DEFAULT_SCHEMA_STRATEGY,
1140
+ DEFAULT_VERSION_STRATEGY,
1153
1141
  TRANSFER_STAGES,
1154
1142
  TransferGroupPresets,
1155
- createTransferEngine: createTransferEngine$2,
1143
+ createTransferEngine,
1156
1144
  errors
1157
1145
  }, Symbol.toStringTag, { value: "Module" }));
1158
1146
  const isDialectMySQL = () => strapi.db?.dialect.client === "mysql";
@@ -1182,7 +1170,7 @@ const createComponents = async (uid, data) => {
1182
1170
  if (!Array.isArray(componentValue)) {
1183
1171
  throw new Error("Expected an array to create repeatable component");
1184
1172
  }
1185
- const components = await utils.mapAsync(
1173
+ const components = await utils.async.map(
1186
1174
  componentValue,
1187
1175
  (value) => createComponent(componentUID, value),
1188
1176
  { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
@@ -1226,7 +1214,7 @@ const createComponents = async (uid, data) => {
1226
1214
  }
1227
1215
  };
1228
1216
  };
1229
- componentBody[attributeName] = await utils.mapAsync(
1217
+ componentBody[attributeName] = await utils.async.map(
1230
1218
  dynamiczoneValues,
1231
1219
  createDynamicZoneComponents,
1232
1220
  { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
@@ -1241,7 +1229,7 @@ const getComponents = async (uid, entity2) => {
1241
1229
  if (___default.default.isEmpty(componentAttributes)) {
1242
1230
  return {};
1243
1231
  }
1244
- return strapi.query(uid).load(entity2, componentAttributes);
1232
+ return strapi.db.query(uid).load(entity2, componentAttributes);
1245
1233
  };
1246
1234
  const deleteComponents = async (uid, entityToDelete, { loadComponents = true } = {}) => {
1247
1235
  const { attributes = {} } = strapi.getModel(uid);
@@ -1251,7 +1239,7 @@ const deleteComponents = async (uid, entityToDelete, { loadComponents = true } =
1251
1239
  if (attribute.type === "component" || attribute.type === "dynamiczone") {
1252
1240
  let value;
1253
1241
  if (loadComponents) {
1254
- value = await strapi.query(uid).load(entityToDelete, attributeName);
1242
+ value = await strapi.db.query(uid).load(entityToDelete, attributeName);
1255
1243
  } else {
1256
1244
  value = entityToDelete[attributeName];
1257
1245
  }
@@ -1260,7 +1248,7 @@ const deleteComponents = async (uid, entityToDelete, { loadComponents = true } =
1260
1248
  }
1261
1249
  if (attribute.type === "component") {
1262
1250
  const { component: componentUID } = attribute;
1263
- await utils.mapAsync(
1251
+ await utils.async.map(
1264
1252
  ___default.default.castArray(value),
1265
1253
  (subValue) => deleteComponent(componentUID, subValue),
1266
1254
  {
@@ -1268,7 +1256,7 @@ const deleteComponents = async (uid, entityToDelete, { loadComponents = true } =
1268
1256
  }
1269
1257
  );
1270
1258
  } else {
1271
- await utils.mapAsync(
1259
+ await utils.async.map(
1272
1260
  ___default.default.castArray(value),
1273
1261
  (subValue) => deleteComponent(subValue.__component, subValue),
1274
1262
  { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
@@ -1289,11 +1277,11 @@ const createComponent = async (uid, data) => {
1289
1277
  // ... and assign the newly created component instead
1290
1278
  fp.assign(componentData)
1291
1279
  );
1292
- return strapi.query(uid).create({ data: transform(data) });
1280
+ return strapi.db.query(uid).create({ data: transform(data) });
1293
1281
  };
1294
1282
  const deleteComponent = async (uid, componentToDelete) => {
1295
1283
  await deleteComponents(uid, componentToDelete);
1296
- await strapi.query(uid).delete({ where: { id: componentToDelete.id } });
1284
+ await strapi.db.query(uid).delete({ where: { id: componentToDelete.id } });
1297
1285
  };
1298
1286
  const sanitizeComponentLikeAttributes = (model, data) => {
1299
1287
  const { attributes } = model;
@@ -1645,7 +1633,7 @@ const link = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty
1645
1633
  __proto__: null,
1646
1634
  createLinkQuery
1647
1635
  }, Symbol.toStringTag, { value: "Module" }));
1648
- const index$5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1636
+ const index$6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1649
1637
  __proto__: null,
1650
1638
  entity,
1651
1639
  link
@@ -1724,7 +1712,7 @@ const restoreCoreStore = async (strapi2, values) => {
1724
1712
  };
1725
1713
  const restoreWebhooks = async (strapi2, values) => {
1726
1714
  const data = omitInvalidCreationAttributes(values);
1727
- return strapi2.db.query("webhook").create({ data });
1715
+ return strapi2.db.query("strapi::webhook").create({ data });
1728
1716
  };
1729
1717
  const restoreConfigs = async (strapi2, config) => {
1730
1718
  if (config.type === "core-store") {
@@ -1812,10 +1800,8 @@ const deleteRecords = async (strapi2, options) => {
1812
1800
  };
1813
1801
  const deleteEntitiesRecords = async (strapi2, options = {}) => {
1814
1802
  const { entities } = options;
1815
- const query = createEntityQuery(strapi2);
1816
- const contentTypes = Object.values(
1817
- strapi2.contentTypes
1818
- );
1803
+ const models = strapi2.get("models").get();
1804
+ const contentTypes = Object.values(strapi2.contentTypes);
1819
1805
  const contentTypesToClear = contentTypes.filter((contentType) => {
1820
1806
  let removeThisContentType = true;
1821
1807
  if (entities?.include) {
@@ -1828,17 +1814,35 @@ const deleteEntitiesRecords = async (strapi2, options = {}) => {
1828
1814
  removeThisContentType = entities.filters.every((filter2) => filter2(contentType));
1829
1815
  }
1830
1816
  return removeThisContentType;
1817
+ }).map((contentType) => contentType.uid);
1818
+ const modelsToClear = models.filter((model) => {
1819
+ if (contentTypesToClear.includes(model.uid)) {
1820
+ return false;
1821
+ }
1822
+ let removeThisModel = true;
1823
+ if (entities?.include) {
1824
+ removeThisModel = entities.include.includes(model.uid);
1825
+ }
1826
+ if (entities?.exclude && entities.exclude.includes(model.uid)) {
1827
+ removeThisModel = false;
1828
+ }
1829
+ return removeThisModel;
1830
+ }).map((model) => model.uid);
1831
+ const [results, updateResults] = useResults([...contentTypesToClear, ...modelsToClear]);
1832
+ const contentTypeQuery = createEntityQuery(strapi2);
1833
+ const contentTypePromises = contentTypesToClear.map(async (uid) => {
1834
+ const result = await contentTypeQuery(uid).deleteMany(entities?.params);
1835
+ if (result) {
1836
+ updateResults(result.count || 0, uid);
1837
+ }
1831
1838
  });
1832
- const [results, updateResults] = useResults(
1833
- contentTypesToClear.map((contentType) => contentType.uid)
1834
- );
1835
- const deletePromises = contentTypesToClear.map(async (contentType) => {
1836
- const result = await query(contentType.uid).deleteMany(entities?.params);
1839
+ const modelsPromises = modelsToClear.map(async (uid) => {
1840
+ const result = await strapi2.db.query(uid).deleteMany({});
1837
1841
  if (result) {
1838
- updateResults(result.count || 0, contentType.uid);
1842
+ updateResults(result.count || 0, uid);
1839
1843
  }
1840
1844
  });
1841
- await Promise.all(deletePromises);
1845
+ await Promise.all([...contentTypePromises, ...modelsPromises]);
1842
1846
  return results;
1843
1847
  };
1844
1848
  const deleteConfigurationRecords = async (strapi2, options = {}) => {
@@ -1848,7 +1852,7 @@ const deleteConfigurationRecords = async (strapi2, options = {}) => {
1848
1852
  models.push("strapi::core-store");
1849
1853
  }
1850
1854
  if (webhook) {
1851
- models.push("webhook");
1855
+ models.push("strapi::webhook");
1852
1856
  }
1853
1857
  const [results, updateResults] = useResults(models);
1854
1858
  const deletePromises = models.map(async (uid) => {
@@ -1882,7 +1886,7 @@ const assertValidStrapi = (strapi2, msg = "") => {
1882
1886
  }
1883
1887
  };
1884
1888
  const VALID_CONFLICT_STRATEGIES = ["restore"];
1885
- const DEFAULT_CONFLICT_STRATEGY$1 = "restore";
1889
+ const DEFAULT_CONFLICT_STRATEGY = "restore";
1886
1890
  class LocalStrapiDestinationProvider {
1887
1891
  name = "destination::local-strapi";
1888
1892
  type = "destination";
@@ -1949,10 +1953,10 @@ class LocalStrapiDestinationProvider {
1949
1953
  return;
1950
1954
  }
1951
1955
  const stream2 = this.strapi.db.queryBuilder("plugin::upload.file").select("*").transacting(trx).stream();
1952
- for await (const file2 of stream2) {
1953
- await this.strapi.plugin("upload").provider.delete(file2);
1954
- if (file2.formats) {
1955
- for (const fileFormat of Object.values(file2.formats)) {
1956
+ for await (const file of stream2) {
1957
+ await this.strapi.plugin("upload").provider.delete(file);
1958
+ if (file.formats) {
1959
+ for (const fileFormat of Object.values(file.formats)) {
1956
1960
  await this.strapi.plugin("upload").provider.delete(fileFormat);
1957
1961
  }
1958
1962
  }
@@ -2023,7 +2027,7 @@ class LocalStrapiDestinationProvider {
2023
2027
  if (!this.#areAssetsIncluded()) {
2024
2028
  return;
2025
2029
  }
2026
- if (this.strapi.config.get("plugin.upload").provider === "local") {
2030
+ if (this.strapi.config.get("plugin::upload").provider === "local") {
2027
2031
  const assetsDirectory = path__default.default.join(this.strapi.dirs.static.public, "uploads");
2028
2032
  const backupDirectory = path__default.default.join(
2029
2033
  this.strapi.dirs.static.public,
@@ -2055,7 +2059,7 @@ class LocalStrapiDestinationProvider {
2055
2059
  if (!this.#areAssetsIncluded()) {
2056
2060
  return;
2057
2061
  }
2058
- if (this.strapi.config.get("plugin.upload").provider === "local") {
2062
+ if (this.strapi.config.get("plugin::upload").provider === "local") {
2059
2063
  assertValidStrapi(this.strapi);
2060
2064
  const backupDirectory = path__default.default.join(
2061
2065
  this.strapi.dirs.static.public,
@@ -2116,7 +2120,7 @@ class LocalStrapiDestinationProvider {
2116
2120
  stream: stream$1.Readable.from(chunk.stream),
2117
2121
  buffer: chunk?.buffer
2118
2122
  };
2119
- const provider = strapi2.config.get("plugin.upload").provider;
2123
+ const provider = strapi2.config.get("plugin::upload").provider;
2120
2124
  try {
2121
2125
  await strapi2.plugin("upload").provider.uploadStream(uploadData);
2122
2126
  if (!restoreMediaEntitiesContent) {
@@ -2187,7 +2191,7 @@ class LocalStrapiDestinationProvider {
2187
2191
  });
2188
2192
  }
2189
2193
  }
2190
- const createLocalStrapiDestinationProvider$2 = (options) => {
2194
+ const createLocalStrapiDestinationProvider = (options) => {
2191
2195
  return new LocalStrapiDestinationProvider(options);
2192
2196
  };
2193
2197
  const createEntitiesStream = (strapi2) => {
@@ -2251,7 +2255,7 @@ const createConfigurationStream = (strapi2) => {
2251
2255
  wrapConfigurationItem("core-store")
2252
2256
  ]);
2253
2257
  const webhooksStream = streamChain.chain([
2254
- strapi2.db.queryBuilder("webhook").stream(),
2258
+ strapi2.db.queryBuilder("strapi::webhook").stream(),
2255
2259
  wrapConfigurationItem("webhook")
2256
2260
  ]);
2257
2261
  const streams = [coreStoreStream, webhooksStream];
@@ -2267,44 +2271,42 @@ const wrapConfigurationItem = (type) => (value) => ({
2267
2271
  type,
2268
2272
  value
2269
2273
  });
2270
- const protocolForPath = (filepath) => {
2271
- return filepath?.startsWith("https") ? https__default.default : http__default.default;
2272
- };
2273
- function getFileStream(filepath, isLocal = false) {
2274
+ function getFileStream(filepath, strapi2, isLocal = false) {
2274
2275
  if (isLocal) {
2275
2276
  return fse.createReadStream(filepath);
2276
2277
  }
2277
2278
  const readableStream = new stream$1.PassThrough();
2278
- protocolForPath(filepath).get(filepath, (res) => {
2279
- if (res.statusCode !== 200) {
2280
- readableStream.emit(
2281
- "error",
2282
- new Error(`Request failed with status code ${res.statusCode}`)
2283
- );
2279
+ strapi2.fetch(filepath).then((res) => {
2280
+ if (res.status !== 200) {
2281
+ readableStream.emit("error", new Error(`Request failed with status code ${res.status}`));
2284
2282
  return;
2285
2283
  }
2286
- res.pipe(readableStream);
2287
- }).on("error", (error) => {
2284
+ if (res.body) {
2285
+ stream$1.Readable.fromWeb(new webStream__namespace.ReadableStream(res.body)).pipe(readableStream);
2286
+ } else {
2287
+ readableStream.emit("error", new Error("Empty data found for file"));
2288
+ }
2289
+ }).catch((error) => {
2288
2290
  readableStream.emit("error", error);
2289
2291
  });
2290
2292
  return readableStream;
2291
2293
  }
2292
- function getFileStats(filepath, isLocal = false) {
2294
+ function getFileStats(filepath, strapi2, isLocal = false) {
2293
2295
  if (isLocal) {
2294
2296
  return fse.stat(filepath);
2295
2297
  }
2296
2298
  return new Promise((resolve, reject2) => {
2297
- protocolForPath(filepath).get(filepath, (res) => {
2298
- if (res.statusCode !== 200) {
2299
- reject2(new Error(`Request failed with status code ${res.statusCode}`));
2299
+ strapi2.fetch(filepath).then((res) => {
2300
+ if (res.status !== 200) {
2301
+ reject2(new Error(`Request failed with status code ${res.status}`));
2300
2302
  return;
2301
2303
  }
2302
- const contentLength = res.headers["content-length"];
2304
+ const contentLength = res.headers.get("content-length");
2303
2305
  const stats = {
2304
2306
  size: contentLength ? parseInt(contentLength, 10) : 0
2305
2307
  };
2306
2308
  resolve(stats);
2307
- }).on("error", (error) => {
2309
+ }).catch((error) => {
2308
2310
  reject2(error);
2309
2311
  });
2310
2312
  });
@@ -2312,25 +2314,25 @@ function getFileStats(filepath, isLocal = false) {
2312
2314
  const createAssetsStream = (strapi2) => {
2313
2315
  const generator = async function* () {
2314
2316
  const stream2 = strapi2.db.queryBuilder("plugin::upload.file").select("*").stream();
2315
- for await (const file2 of stream2) {
2316
- const isLocalProvider = file2.provider === "local";
2317
- const filepath = isLocalProvider ? path.join(strapi2.dirs.static.public, file2.url) : file2.url;
2318
- const stats = await getFileStats(filepath, isLocalProvider);
2319
- const stream22 = getFileStream(filepath, isLocalProvider);
2317
+ for await (const file of stream2) {
2318
+ const isLocalProvider = file.provider === "local";
2319
+ const filepath = isLocalProvider ? path.join(strapi2.dirs.static.public, file.url) : file.url;
2320
+ const stats = await getFileStats(filepath, strapi2, isLocalProvider);
2321
+ const stream22 = getFileStream(filepath, strapi2, isLocalProvider);
2320
2322
  yield {
2321
- metadata: file2,
2323
+ metadata: file,
2322
2324
  filepath,
2323
- filename: file2.hash + file2.ext,
2325
+ filename: file.hash + file.ext,
2324
2326
  stream: stream22,
2325
2327
  stats: { size: stats.size }
2326
2328
  };
2327
- if (file2.formats) {
2328
- for (const format of Object.keys(file2.formats)) {
2329
- const fileFormat = file2.formats[format];
2329
+ if (file.formats) {
2330
+ for (const format of Object.keys(file.formats)) {
2331
+ const fileFormat = file.formats[format];
2330
2332
  const fileFormatFilepath = isLocalProvider ? path.join(strapi2.dirs.static.public, fileFormat.url) : fileFormat.url;
2331
- const fileFormatStats = await getFileStats(fileFormatFilepath, isLocalProvider);
2332
- const fileFormatStream = getFileStream(fileFormatFilepath, isLocalProvider);
2333
- const metadata = { ...fileFormat, type: format, id: file2.id, mainHash: file2.hash };
2333
+ const fileFormatStats = await getFileStats(fileFormatFilepath, strapi2, isLocalProvider);
2334
+ const fileFormatStream = getFileStream(fileFormatFilepath, strapi2, isLocalProvider);
2335
+ const metadata = { ...fileFormat, type: format, id: file.id, mainHash: file.hash };
2334
2336
  yield {
2335
2337
  metadata,
2336
2338
  filepath: fileFormatFilepath,
@@ -2344,7 +2346,7 @@ const createAssetsStream = (strapi2) => {
2344
2346
  };
2345
2347
  return stream$1.Duplex.from(generator());
2346
2348
  };
2347
- const createLocalStrapiSourceProvider$2 = (options) => {
2349
+ const createLocalStrapiSourceProvider = (options) => {
2348
2350
  return new LocalStrapiSourceProvider(options);
2349
2351
  };
2350
2352
  class LocalStrapiSourceProvider {
@@ -2472,8 +2474,8 @@ const createDispatcher = (ws2, retryMessageOptions = {
2472
2474
  const dispatchCommand = (payload) => {
2473
2475
  return dispatch({ type: "command", ...payload });
2474
2476
  };
2475
- const dispatchTransferAction = async (action2) => {
2476
- const payload = { type: "transfer", kind: "action", action: action2 };
2477
+ const dispatchTransferAction = async (action) => {
2478
+ const payload = { type: "transfer", kind: "action", action };
2477
2479
  return dispatch(payload, { attachTransfer: true }) ?? Promise.resolve(null);
2478
2480
  };
2479
2481
  const dispatchTransferStep = async (payload) => {
@@ -2807,7 +2809,7 @@ class RemoteStrapiDestinationProvider {
2807
2809
  });
2808
2810
  }
2809
2811
  }
2810
- const createRemoteStrapiDestinationProvider$1 = (options) => {
2812
+ const createRemoteStrapiDestinationProvider = (options) => {
2811
2813
  return new RemoteStrapiDestinationProvider(options);
2812
2814
  };
2813
2815
  class RemoteStrapiSourceProvider {
@@ -2879,15 +2881,15 @@ class RemoteStrapiSourceProvider {
2879
2881
  const pass = new stream$1.PassThrough({ objectMode: true });
2880
2882
  stream2.on("data", async (payload) => {
2881
2883
  for (const item of payload) {
2882
- const { action: action2 } = item;
2883
- if (action2 === "start") {
2884
+ const { action } = item;
2885
+ if (action === "start") {
2884
2886
  assets[item.assetID] = { ...item.data, stream: new stream$1.PassThrough() };
2885
2887
  await this.writeAsync(pass, assets[item.assetID]);
2886
- } else if (action2 === "stream") {
2888
+ } else if (action === "stream") {
2887
2889
  const rawBuffer = item.data;
2888
2890
  const chunk = Buffer.from(rawBuffer.data);
2889
2891
  await this.writeAsync(assets[item.assetID].stream, chunk);
2890
- } else if (action2 === "end") {
2892
+ } else if (action === "end") {
2891
2893
  await new Promise((resolve, reject2) => {
2892
2894
  const { stream: assetStream } = assets[item.assetID];
2893
2895
  assetStream.on("close", () => {
@@ -3015,17 +3017,17 @@ class RemoteStrapiSourceProvider {
3015
3017
  return null;
3016
3018
  }
3017
3019
  }
3018
- const createRemoteStrapiSourceProvider$1 = (options) => {
3020
+ const createRemoteStrapiSourceProvider = (options) => {
3019
3021
  return new RemoteStrapiSourceProvider(options);
3020
3022
  };
3021
- const index$4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3023
+ const index$5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3022
3024
  __proto__: null,
3023
- DEFAULT_CONFLICT_STRATEGY: DEFAULT_CONFLICT_STRATEGY$1,
3025
+ DEFAULT_CONFLICT_STRATEGY,
3024
3026
  VALID_CONFLICT_STRATEGIES,
3025
- createLocalStrapiDestinationProvider: createLocalStrapiDestinationProvider$2,
3026
- createLocalStrapiSourceProvider: createLocalStrapiSourceProvider$2,
3027
- createRemoteStrapiDestinationProvider: createRemoteStrapiDestinationProvider$1,
3028
- createRemoteStrapiSourceProvider: createRemoteStrapiSourceProvider$1
3027
+ createLocalStrapiDestinationProvider,
3028
+ createLocalStrapiSourceProvider,
3029
+ createRemoteStrapiDestinationProvider,
3030
+ createRemoteStrapiSourceProvider
3029
3031
  }, Symbol.toStringTag, { value: "Module" }));
3030
3032
  const DEFAULT_TRANSFER_FLOW = [
3031
3033
  {
@@ -3232,9 +3234,9 @@ const handlerControllerFactory = (implementation) => (options) => {
3232
3234
  throw new Error("Invalid Transfer Process");
3233
3235
  }
3234
3236
  },
3235
- assertValidTransferCommand(command2) {
3236
- const isDefined = typeof this[command2] === "function";
3237
- const isValidTransferCommand = VALID_TRANSFER_COMMANDS.includes(command2);
3237
+ assertValidTransferCommand(command) {
3238
+ const isDefined = typeof this[command] === "function";
3239
+ const isValidTransferCommand = VALID_TRANSFER_COMMANDS.includes(command);
3238
3240
  if (!isDefined || !isValidTransferCommand) {
3239
3241
  throw new Error("Invalid transfer command");
3240
3242
  }
@@ -3418,12 +3420,12 @@ const createPushController = handlerControllerFactory((proto) => ({
3418
3420
  throw new Error("Invalid Transfer Process");
3419
3421
  }
3420
3422
  },
3421
- assertValidTransferAction(action2) {
3422
- if (VALID_TRANSFER_ACTIONS$1.includes(action2)) {
3423
+ assertValidTransferAction(action) {
3424
+ if (VALID_TRANSFER_ACTIONS$1.includes(action)) {
3423
3425
  return;
3424
3426
  }
3425
- throw new ProviderTransferError(`Invalid action provided: "${action2}"`, {
3426
- action: action2,
3427
+ throw new ProviderTransferError(`Invalid action provided: "${action}"`, {
3428
+ action,
3427
3429
  validActions: Object.keys(VALID_TRANSFER_ACTIONS$1)
3428
3430
  });
3429
3431
  },
@@ -3474,13 +3476,13 @@ const createPushController = handlerControllerFactory((proto) => ({
3474
3476
  const { uuid, type } = msg;
3475
3477
  proto.addUUID(uuid);
3476
3478
  if (type === "command") {
3477
- const { command: command2 } = msg;
3479
+ const { command } = msg;
3478
3480
  await this.executeAndRespond(uuid, () => {
3479
- this.assertValidTransferCommand(command2);
3480
- if (command2 === "status") {
3481
+ this.assertValidTransferCommand(command);
3482
+ if (command === "status") {
3481
3483
  return this.status();
3482
3484
  }
3483
- return this[command2](msg.params);
3485
+ return this[command](msg.params);
3484
3486
  });
3485
3487
  } else if (type === "transfer") {
3486
3488
  await this.executeAndRespond(uuid, async () => {
@@ -3565,19 +3567,19 @@ const createPushController = handlerControllerFactory((proto) => ({
3565
3567
  }
3566
3568
  },
3567
3569
  async onTransferAction(msg) {
3568
- const { action: action2 } = msg;
3569
- this.assertValidTransferAction(action2);
3570
- const step = { kind: "action", action: action2 };
3570
+ const { action } = msg;
3571
+ this.assertValidTransferAction(action);
3572
+ const step = { kind: "action", action };
3571
3573
  const isStepRegistered = this.flow?.has(step);
3572
3574
  if (isStepRegistered) {
3573
3575
  if (this.flow?.cannot(step)) {
3574
- throw new ProviderTransferError(`Invalid action "${action2}" found for the current flow `, {
3575
- action: action2
3576
+ throw new ProviderTransferError(`Invalid action "${action}" found for the current flow `, {
3577
+ action
3576
3578
  });
3577
3579
  }
3578
3580
  this.flow?.set(step);
3579
3581
  }
3580
- return this.provider?.[action2]();
3582
+ return this.provider?.[action]();
3581
3583
  },
3582
3584
  async streamAsset(payload) {
3583
3585
  const assetsStream = this.streams?.assets;
@@ -3586,20 +3588,20 @@ const createPushController = handlerControllerFactory((proto) => ({
3586
3588
  return;
3587
3589
  }
3588
3590
  for (const item of payload) {
3589
- const { action: action2, assetID } = item;
3591
+ const { action, assetID } = item;
3590
3592
  if (!assetsStream) {
3591
3593
  throw new Error("Stream not defined");
3592
3594
  }
3593
- if (action2 === "start") {
3595
+ if (action === "start") {
3594
3596
  this.assets[assetID] = { ...item.data, stream: new stream$1.PassThrough() };
3595
3597
  writeAsync(assetsStream, this.assets[assetID]);
3596
3598
  }
3597
- if (action2 === "stream") {
3599
+ if (action === "stream") {
3598
3600
  const rawBuffer = item.data;
3599
3601
  const chunk = Buffer.from(rawBuffer.data);
3600
3602
  await writeAsync(this.assets[assetID].stream, chunk);
3601
3603
  }
3602
- if (action2 === "end") {
3604
+ if (action === "end") {
3603
3605
  await new Promise((resolve, reject2) => {
3604
3606
  const { stream: assetStream } = this.assets[assetID];
3605
3607
  assetStream.on("close", () => {
@@ -3628,7 +3630,7 @@ const createPushController = handlerControllerFactory((proto) => ({
3628
3630
  this.assets = {};
3629
3631
  this.streams = {};
3630
3632
  this.flow = createFlow(DEFAULT_TRANSFER_FLOW);
3631
- this.provider = createLocalStrapiDestinationProvider$2({
3633
+ this.provider = createLocalStrapiDestinationProvider({
3632
3634
  ...params.options,
3633
3635
  autoDestroy: false,
3634
3636
  getStrapi: () => strapi
@@ -3674,13 +3676,13 @@ const createPullController = handlerControllerFactory((proto) => ({
3674
3676
  this.streams = {};
3675
3677
  delete this.provider;
3676
3678
  },
3677
- assertValidTransferAction(action2) {
3679
+ assertValidTransferAction(action) {
3678
3680
  const validActions = VALID_TRANSFER_ACTIONS;
3679
- if (validActions.includes(action2)) {
3681
+ if (validActions.includes(action)) {
3680
3682
  return;
3681
3683
  }
3682
- throw new ProviderTransferError(`Invalid action provided: "${action2}"`, {
3683
- action: action2,
3684
+ throw new ProviderTransferError(`Invalid action provided: "${action}"`, {
3685
+ action,
3684
3686
  validActions: Object.keys(VALID_TRANSFER_ACTIONS)
3685
3687
  });
3686
3688
  },
@@ -3702,13 +3704,13 @@ const createPullController = handlerControllerFactory((proto) => ({
3702
3704
  const { uuid, type } = msg;
3703
3705
  proto.addUUID(uuid);
3704
3706
  if (type === "command") {
3705
- const { command: command2 } = msg;
3707
+ const { command } = msg;
3706
3708
  await this.executeAndRespond(uuid, () => {
3707
- this.assertValidTransferCommand(command2);
3708
- if (command2 === "status") {
3709
+ this.assertValidTransferCommand(command);
3710
+ if (command === "status") {
3709
3711
  return this.status();
3710
3712
  }
3711
- return this[command2](msg.params);
3713
+ return this[command](msg.params);
3712
3714
  });
3713
3715
  } else if (type === "transfer") {
3714
3716
  await this.executeAndRespond(uuid, async () => {
@@ -3730,9 +3732,9 @@ const createPullController = handlerControllerFactory((proto) => ({
3730
3732
  }
3731
3733
  },
3732
3734
  async onTransferAction(msg) {
3733
- const { action: action2 } = msg;
3734
- this.assertValidTransferAction(action2);
3735
- return this.provider?.[action2]();
3735
+ const { action } = msg;
3736
+ this.assertValidTransferAction(action);
3737
+ return this.provider?.[action]();
3736
3738
  },
3737
3739
  async flush(stage, id) {
3738
3740
  const batchSize = 1024 * 1024;
@@ -3779,8 +3781,8 @@ const createPullController = handlerControllerFactory((proto) => ({
3779
3781
  }
3780
3782
  },
3781
3783
  async onTransferStep(msg) {
3782
- const { step, action: action2 } = msg;
3783
- if (action2 === "start") {
3784
+ const { step, action } = msg;
3785
+ if (action === "start") {
3784
3786
  if (this.streams?.[step] instanceof stream$1.Readable) {
3785
3787
  throw new Error("Stream already created, something went wrong");
3786
3788
  }
@@ -3789,7 +3791,7 @@ const createPullController = handlerControllerFactory((proto) => ({
3789
3791
  this.flush(step, flushUUID);
3790
3792
  return { ok: true, id: flushUUID };
3791
3793
  }
3792
- if (action2 === "end") {
3794
+ if (action === "end") {
3793
3795
  const stream2 = this.streams?.[step];
3794
3796
  if (stream2?.readableEnded === false) {
3795
3797
  await new Promise((resolve) => {
@@ -3861,7 +3863,7 @@ const createPullController = handlerControllerFactory((proto) => ({
3861
3863
  this.transferID = crypto.randomUUID();
3862
3864
  this.startedAt = Date.now();
3863
3865
  this.streams = {};
3864
- this.provider = createLocalStrapiSourceProvider$2({
3866
+ this.provider = createLocalStrapiSourceProvider({
3865
3867
  autoDestroy: false,
3866
3868
  getStrapi: () => strapi
3867
3869
  });
@@ -3889,22 +3891,22 @@ const createPullController = handlerControllerFactory((proto) => ({
3889
3891
  return { active: false, kind: null, elapsed: null, startedAt: null };
3890
3892
  }
3891
3893
  }));
3892
- const index$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3894
+ const index$4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3893
3895
  __proto__: null,
3894
3896
  createPullController,
3895
3897
  createPushController,
3896
3898
  handlerControllerFactory
3897
3899
  }, Symbol.toStringTag, { value: "Module" }));
3898
- const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3900
+ const index$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3899
3901
  __proto__: null,
3900
3902
  constants,
3901
- handlers: index$3
3903
+ handlers: index$4
3902
3904
  }, Symbol.toStringTag, { value: "Module" }));
3903
- const strapiDatatransfer = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3905
+ const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3904
3906
  __proto__: null,
3905
- providers: index$4,
3906
- queries: index$5,
3907
- remote: index$2
3907
+ providers: index$5,
3908
+ queries: index$6,
3909
+ remote: index$3
3908
3910
  }, Symbol.toStringTag, { value: "Module" }));
3909
3911
  const isFilePathInDirname = (posixDirName, filePath) => {
3910
3912
  const normalizedDir = path__default.default.posix.dirname(unknownPathToPosix(filePath));
@@ -3922,7 +3924,7 @@ const unknownPathToPosix = (filePath) => {
3922
3924
  return path__default.default.normalize(filePath).split(path__default.default.win32.sep).join(path__default.default.posix.sep);
3923
3925
  };
3924
3926
  const METADATA_FILE_PATH = "metadata.json";
3925
- const createLocalFileSourceProvider$1 = (options) => {
3927
+ const createLocalFileSourceProvider = (options) => {
3926
3928
  return new LocalFileSourceProvider(options);
3927
3929
  };
3928
3930
  class LocalFileSourceProvider {
@@ -4007,18 +4009,18 @@ class LocalFileSourceProvider {
4007
4009
  async onentry(entry) {
4008
4010
  const { path: filePath, size = 0 } = entry;
4009
4011
  const normalizedPath = unknownPathToPosix(filePath);
4010
- const file2 = path__default.default.basename(normalizedPath);
4012
+ const file = path__default.default.basename(normalizedPath);
4011
4013
  let metadata;
4012
4014
  try {
4013
- metadata = await loadAssetMetadata(`assets/metadata/${file2}.json`);
4015
+ metadata = await loadAssetMetadata(`assets/metadata/${file}.json`);
4014
4016
  } catch (error) {
4015
4017
  console.warn(
4016
- ` Failed to read metadata for ${file2}, Strapi will try to fix this issue automatically`
4018
+ ` Failed to read metadata for ${file}, Strapi will try to fix this issue automatically`
4017
4019
  );
4018
4020
  }
4019
4021
  const asset = {
4020
4022
  metadata,
4021
- filename: file2,
4023
+ filename: file,
4022
4024
  filepath: normalizedPath,
4023
4025
  stats: { size },
4024
4026
  stream: entry
@@ -4032,10 +4034,10 @@ class LocalFileSourceProvider {
4032
4034
  return outStream;
4033
4035
  }
4034
4036
  #getBackupStream() {
4035
- const { file: file2, encryption, compression } = this.options;
4037
+ const { file, encryption, compression } = this.options;
4036
4038
  const streams = [];
4037
4039
  try {
4038
- streams.push(fse__namespace.default.createReadStream(file2.path));
4040
+ streams.push(fse__namespace.default.createReadStream(file.path));
4039
4041
  } catch (e) {
4040
4042
  throw new Error(`Could not read backup file path provided at "${this.options.file.path}"`);
4041
4043
  }
@@ -4183,7 +4185,7 @@ const createTarEntryStream = (archive, pathFactory, maxSize = 256e6) => {
4183
4185
  }
4184
4186
  });
4185
4187
  };
4186
- const createLocalFileDestinationProvider$1 = (options) => {
4188
+ const createLocalFileDestinationProvider = (options) => {
4187
4189
  return new LocalFileDestinationProvider(options);
4188
4190
  };
4189
4191
  class LocalFileDestinationProvider {
@@ -4197,8 +4199,8 @@ class LocalFileDestinationProvider {
4197
4199
  this.options = options;
4198
4200
  }
4199
4201
  get #archivePath() {
4200
- const { encryption, compression, file: file2 } = this.options;
4201
- let filePath = `${file2.path}.tar`;
4202
+ const { encryption, compression, file } = this.options;
4203
+ let filePath = `${file.path}.tar`;
4202
4204
  if (compression.enabled) {
4203
4205
  filePath += ".gz";
4204
4206
  }
@@ -4362,951 +4364,15 @@ class LocalFileDestinationProvider {
4362
4364
  }
4363
4365
  const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4364
4366
  __proto__: null,
4365
- createLocalFileDestinationProvider: createLocalFileDestinationProvider$1,
4366
- createLocalFileSourceProvider: createLocalFileSourceProvider$1
4367
- }, Symbol.toStringTag, { value: "Module" }));
4368
- const file = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4369
- __proto__: null,
4370
- providers: index$1
4367
+ createLocalFileDestinationProvider,
4368
+ createLocalFileSourceProvider
4371
4369
  }, Symbol.toStringTag, { value: "Module" }));
4372
- const bytesPerKb = 1024;
4373
- const sizes = ["B ", "KB", "MB", "GB", "TB", "PB"];
4374
- const readableBytes = (bytes, decimals = 1, padStart = 0) => {
4375
- if (!bytes) {
4376
- return "0";
4377
- }
4378
- const i = Math.floor(Math.log(bytes) / Math.log(bytesPerKb));
4379
- const result = `${parseFloat((bytes / bytesPerKb ** i).toFixed(decimals))} ${sizes[i].padStart(
4380
- 2
4381
- )}`;
4382
- return result.padStart(padStart);
4383
- };
4384
- const exitWith = (code, message, options = {}) => {
4385
- const { logger: logger2 = console, prc = process } = options;
4386
- const log = (message2) => {
4387
- if (code === 0) {
4388
- logger2.log(chalk__default.default.green(message2));
4389
- } else {
4390
- logger2.error(chalk__default.default.red(message2));
4391
- }
4392
- };
4393
- if (fp.isString(message)) {
4394
- log(message);
4395
- } else if (fp.isArray(message)) {
4396
- message.forEach((msg) => log(msg));
4397
- }
4398
- prc.exit(code);
4399
- };
4400
- const assertUrlHasProtocol = (url, protocol) => {
4401
- if (!url.protocol) {
4402
- exitWith(1, `${url.toString()} does not have a protocol`);
4403
- }
4404
- if (!protocol) {
4405
- return;
4406
- }
4407
- if (fp.isString(protocol)) {
4408
- if (protocol !== url.protocol) {
4409
- exitWith(1, `${url.toString()} must have the protocol ${protocol}`);
4410
- }
4411
- return;
4412
- }
4413
- if (!protocol.some((protocol2) => url.protocol === protocol2)) {
4414
- return exitWith(
4415
- 1,
4416
- `${url.toString()} must have one of the following protocols: ${protocol.join(",")}`
4417
- );
4418
- }
4419
- };
4420
- const ifOptions = (conditionCallback, isMetCallback = async () => {
4421
- }, isNotMetCallback = async () => {
4422
- }) => {
4423
- return async (command2) => {
4424
- const opts = command2.opts();
4425
- if (await conditionCallback(opts)) {
4426
- await isMetCallback(command2);
4427
- } else {
4428
- await isNotMetCallback(command2);
4429
- }
4430
- };
4431
- };
4432
- const parseList = (value) => {
4433
- try {
4434
- return value.split(",").map((item) => item.trim());
4435
- } catch (e) {
4436
- exitWith(1, `Unrecognized input: ${value}`);
4437
- }
4438
- return [];
4439
- };
4440
- const getParseListWithChoices = (choices, errorMessage = "Invalid options:") => {
4441
- return (value) => {
4442
- const list = parseList(value);
4443
- const invalid = list.filter((item) => {
4444
- return !choices.includes(item);
4445
- });
4446
- if (invalid.length > 0) {
4447
- exitWith(1, `${errorMessage}: ${invalid.join(",")}`);
4448
- }
4449
- return list;
4450
- };
4451
- };
4452
- const parseInteger = (value) => {
4453
- const parsedValue = parseInt(value, 10);
4454
- if (fp.isNaN(parsedValue)) {
4455
- throw new commander.InvalidOptionArgumentError(`Not an integer: ${value}`);
4456
- }
4457
- return parsedValue;
4458
- };
4459
- const parseURL = (value) => {
4460
- try {
4461
- const url = new URL(value);
4462
- if (!url.host) {
4463
- throw new commander.InvalidOptionArgumentError(`Could not parse url ${value}`);
4464
- }
4465
- return url;
4466
- } catch (e) {
4467
- throw new commander.InvalidOptionArgumentError(`Could not parse url ${value}`);
4468
- }
4469
- };
4470
- const promptEncryptionKey = async (thisCommand) => {
4471
- const opts = thisCommand.opts();
4472
- if (!opts.encrypt && opts.key) {
4473
- return exitWith(1, "Key may not be present unless encryption is used");
4474
- }
4475
- if (opts.encrypt && !(opts.key && opts.key.length > 0)) {
4476
- try {
4477
- const answers = await inquirer__default.default.prompt([
4478
- {
4479
- type: "password",
4480
- message: "Please enter an encryption key",
4481
- name: "key",
4482
- validate(key) {
4483
- if (key.length > 0)
4484
- return true;
4485
- return "Key must be present when using the encrypt option";
4486
- }
4487
- }
4488
- ]);
4489
- opts.key = answers.key;
4490
- } catch (e) {
4491
- return exitWith(1, "Failed to get encryption key");
4492
- }
4493
- if (!opts.key) {
4494
- return exitWith(1, "Failed to get encryption key");
4495
- }
4496
- }
4497
- };
4498
- const getCommanderConfirmMessage = (message, { failMessage } = {}) => {
4499
- return async (command2) => {
4500
- const confirmed = await confirmMessage(message, { force: command2.opts().force });
4501
- if (!confirmed) {
4502
- exitWith(1, failMessage);
4503
- }
4504
- };
4505
- };
4506
- const confirmMessage = async (message, { force } = {}) => {
4507
- if (force === true) {
4508
- console.log(`${chalk__default.default.green("?")} ${chalk__default.default.bold(message)} ${chalk__default.default.cyan("Yes")}`);
4509
- return true;
4510
- }
4511
- const answers = await inquirer__default.default.prompt([
4512
- {
4513
- type: "confirm",
4514
- message,
4515
- name: `confirm`,
4516
- default: false
4517
- }
4518
- ]);
4519
- return answers.confirm;
4520
- };
4521
- const forceOption = new commander.Option(
4522
- "--force",
4523
- `Automatically answer "yes" to all prompts, including potentially destructive requests, and run non-interactively.`
4524
- );
4525
- const {
4526
- errors: { TransferEngineInitializationError: TransferEngineInitializationError2 }
4527
- } = engineDatatransfer;
4528
- const exitMessageText = (process2, error = false) => {
4529
- const processCapitalized = process2[0].toUpperCase() + process2.slice(1);
4530
- if (!error) {
4531
- return chalk__default.default.bold(
4532
- chalk__default.default.green(`${processCapitalized} process has been completed successfully!`)
4533
- );
4534
- }
4535
- return chalk__default.default.bold(chalk__default.default.red(`${processCapitalized} process failed.`));
4536
- };
4537
- const pad = (n) => {
4538
- return (n < 10 ? "0" : "") + String(n);
4539
- };
4540
- const yyyymmddHHMMSS = () => {
4541
- const date = /* @__PURE__ */ new Date();
4542
- return date.getFullYear() + pad(date.getMonth() + 1) + pad(date.getDate()) + pad(date.getHours()) + pad(date.getMinutes()) + pad(date.getSeconds());
4543
- };
4544
- const getDefaultExportName = () => {
4545
- return `export_${yyyymmddHHMMSS()}`;
4546
- };
4547
- const buildTransferTable = (resultData) => {
4548
- if (!resultData) {
4549
- return;
4550
- }
4551
- const table = new Table__default.default({
4552
- head: ["Type", "Count", "Size"].map((text) => chalk__default.default.bold.blue(text))
4553
- });
4554
- let totalBytes = 0;
4555
- let totalItems = 0;
4556
- Object.keys(resultData).forEach((stage) => {
4557
- const item = resultData[stage];
4558
- if (!item) {
4559
- return;
4560
- }
4561
- table.push([
4562
- { hAlign: "left", content: chalk__default.default.bold(stage) },
4563
- { hAlign: "right", content: item.count },
4564
- { hAlign: "right", content: `${readableBytes(item.bytes, 1, 11)} ` }
4565
- ]);
4566
- totalBytes += item.bytes;
4567
- totalItems += item.count;
4568
- if (item.aggregates) {
4569
- Object.keys(item.aggregates).sort().forEach((subkey) => {
4570
- if (!item.aggregates) {
4571
- return;
4572
- }
4573
- const subitem = item.aggregates[subkey];
4574
- table.push([
4575
- { hAlign: "left", content: `-- ${chalk__default.default.bold.grey(subkey)}` },
4576
- { hAlign: "right", content: chalk__default.default.grey(subitem.count) },
4577
- { hAlign: "right", content: chalk__default.default.grey(`(${readableBytes(subitem.bytes, 1, 11)})`) }
4578
- ]);
4579
- });
4580
- }
4581
- });
4582
- table.push([
4583
- { hAlign: "left", content: chalk__default.default.bold.green("Total") },
4584
- { hAlign: "right", content: chalk__default.default.bold.green(totalItems) },
4585
- { hAlign: "right", content: `${chalk__default.default.bold.green(readableBytes(totalBytes, 1, 11))} ` }
4586
- ]);
4587
- return table;
4588
- };
4589
- const DEFAULT_IGNORED_CONTENT_TYPES = [
4590
- "admin::permission",
4591
- "admin::user",
4592
- "admin::role",
4593
- "admin::api-token",
4594
- "admin::api-token-permission",
4595
- "admin::transfer-token",
4596
- "admin::transfer-token-permission",
4597
- "admin::audit-log",
4598
- "plugin::content-releases.release",
4599
- "plugin::content-releases.release-action"
4600
- ];
4601
- const abortTransfer = async ({
4602
- engine,
4603
- strapi: strapi2
4604
- }) => {
4605
- try {
4606
- await engine.abortTransfer();
4607
- await strapi2.destroy();
4608
- } catch (e) {
4609
- return false;
4610
- }
4611
- return true;
4612
- };
4613
- const setSignalHandler = async (handler, signals = ["SIGINT", "SIGTERM", "SIGQUIT"]) => {
4614
- signals.forEach((signal) => {
4615
- process.removeAllListeners(signal);
4616
- process.on(signal, handler);
4617
- });
4618
- };
4619
- const createStrapiInstance = async (opts = {}) => {
4620
- try {
4621
- const appContext = await strapiFactory__default.default.compile();
4622
- const app = strapiFactory__default.default({ ...opts, ...appContext });
4623
- app.log.level = opts.logLevel || "error";
4624
- return await app.load();
4625
- } catch (error) {
4626
- if (error instanceof Error && "code" in error && error.code === "ECONNREFUSED") {
4627
- throw new Error("Process failed. Check the database connection with your Strapi project.");
4628
- }
4629
- throw error;
4630
- }
4631
- };
4632
- const transferDataTypes = Object.keys(TransferGroupPresets);
4633
- const throttleOption = new commander.Option(
4634
- "--throttle <delay after each entity>",
4635
- `Add a delay in milliseconds between each transferred entity`
4636
- ).argParser(parseInteger).hideHelp();
4637
- const excludeOption = new commander.Option(
4638
- "--exclude <comma-separated data types>",
4639
- `Exclude data using comma-separated types. Available types: ${transferDataTypes.join(",")}`
4640
- ).argParser(getParseListWithChoices(transferDataTypes, 'Invalid options for "exclude"'));
4641
- const onlyOption = new commander.Option(
4642
- "--only <command-separated data types>",
4643
- `Include only these types of data (plus schemas). Available types: ${transferDataTypes.join(",")}`
4644
- ).argParser(getParseListWithChoices(transferDataTypes, 'Invalid options for "only"'));
4645
- const validateExcludeOnly = (command2) => {
4646
- const { exclude, only } = command2.opts();
4647
- if (!only || !exclude) {
4648
- return;
4649
- }
4650
- const choicesInBoth = only.filter((n) => {
4651
- return exclude.indexOf(n) !== -1;
4652
- });
4653
- if (choicesInBoth.length > 0) {
4654
- exitWith(
4655
- 1,
4656
- `Data types may not be used in both "exclude" and "only" in the same command. Found in both: ${choicesInBoth.join(
4657
- ","
4658
- )}`
4659
- );
4660
- }
4661
- };
4662
- const errorColors = {
4663
- fatal: chalk__default.default.red,
4664
- error: chalk__default.default.red,
4665
- silly: chalk__default.default.yellow
4666
- };
4667
- const formatDiagnostic = (operation) => ({ details, kind }) => {
4668
- const logger$1 = logger.createLogger(
4669
- logger.configs.createOutputFileConfiguration(`${operation}_error_log_${Date.now()}.log`)
4670
- );
4671
- try {
4672
- if (kind === "error") {
4673
- const { message, severity = "fatal" } = details;
4674
- const colorizeError = errorColors[severity];
4675
- const errorMessage = colorizeError(`[${severity.toUpperCase()}] ${message}`);
4676
- logger$1.error(errorMessage);
4677
- }
4678
- if (kind === "info") {
4679
- const { message, params } = details;
4680
- const msg = `${message}
4681
- ${params ? JSON.stringify(params, null, 2) : ""}`;
4682
- logger$1.info(msg);
4683
- }
4684
- if (kind === "warning") {
4685
- const { origin: origin2, message } = details;
4686
- logger$1.warn(`(${origin2 ?? "transfer"}) ${message}`);
4687
- }
4688
- } catch (err) {
4689
- logger$1.error(err);
4690
- }
4691
- };
4692
- const loadersFactory = (defaultLoaders = {}) => {
4693
- const loaders = defaultLoaders;
4694
- const updateLoader = (stage, data) => {
4695
- if (!(stage in loaders)) {
4696
- createLoader(stage);
4697
- }
4698
- const stageData = data[stage];
4699
- const elapsedTime = stageData?.startTime ? (stageData?.endTime || Date.now()) - stageData.startTime : 0;
4700
- const size = `size: ${readableBytes(stageData?.bytes ?? 0)}`;
4701
- const elapsed = `elapsed: ${elapsedTime} ms`;
4702
- const speed = elapsedTime > 0 ? `(${readableBytes((stageData?.bytes ?? 0) * 1e3 / elapsedTime)}/s)` : "";
4703
- loaders[stage].text = `${stage}: ${stageData?.count ?? 0} transfered (${size}) (${elapsed}) ${!stageData?.endTime ? speed : ""}`;
4704
- return loaders[stage];
4705
- };
4706
- const createLoader = (stage) => {
4707
- Object.assign(loaders, { [stage]: ora__default.default() });
4708
- return loaders[stage];
4709
- };
4710
- const getLoader = (stage) => {
4711
- return loaders[stage];
4712
- };
4713
- return {
4714
- updateLoader,
4715
- createLoader,
4716
- getLoader
4717
- };
4718
- };
4719
- const getTransferTelemetryPayload = (engine) => {
4720
- return {
4721
- eventProperties: {
4722
- source: engine?.sourceProvider?.name,
4723
- destination: engine?.destinationProvider?.name
4724
- }
4725
- };
4726
- };
4727
- const getDiffHandler = (engine, {
4728
- force,
4729
- action: action2
4730
- }) => {
4731
- return async (context, next) => {
4732
- setSignalHandler(async () => {
4733
- await abortTransfer({ engine, strapi });
4734
- exitWith(1, exitMessageText(action2, true));
4735
- });
4736
- let workflowsStatus;
4737
- const source = "Schema Integrity";
4738
- Object.entries(context.diffs).forEach(([uid, diffs]) => {
4739
- for (const diff2 of diffs) {
4740
- const path2 = [uid].concat(diff2.path).join(".");
4741
- const endPath = diff2.path[diff2.path.length - 1];
4742
- if (uid === "admin::workflow" || uid === "admin::workflow-stage" || endPath?.startsWith("strapi_stage") || endPath?.startsWith("strapi_assignee")) {
4743
- workflowsStatus = diff2.kind;
4744
- } else if (diff2.kind === "added") {
4745
- engine.reportWarning(chalk__default.default.red(`${chalk__default.default.bold(path2)} does not exist on source`), source);
4746
- } else if (diff2.kind === "deleted") {
4747
- engine.reportWarning(
4748
- chalk__default.default.red(`${chalk__default.default.bold(path2)} does not exist on destination`),
4749
- source
4750
- );
4751
- } else if (diff2.kind === "modified") {
4752
- engine.reportWarning(chalk__default.default.red(`${chalk__default.default.bold(path2)} has a different data type`), source);
4753
- }
4754
- }
4755
- });
4756
- if (workflowsStatus === "added") {
4757
- engine.reportWarning(chalk__default.default.red(`Review workflows feature does not exist on source`), source);
4758
- } else if (workflowsStatus === "deleted") {
4759
- engine.reportWarning(
4760
- chalk__default.default.red(`Review workflows feature does not exist on destination`),
4761
- source
4762
- );
4763
- } else if (workflowsStatus === "modified") {
4764
- engine.panic(
4765
- new TransferEngineInitializationError2("Unresolved differences in schema [review workflows]")
4766
- );
4767
- }
4768
- const confirmed = await confirmMessage(
4769
- "There are differences in schema between the source and destination, and the data listed above will be lost. Are you sure you want to continue?",
4770
- {
4771
- force
4772
- }
4773
- );
4774
- setSignalHandler(() => abortTransfer({ engine, strapi }));
4775
- if (confirmed) {
4776
- context.ignoredDiffs = fp.merge(context.diffs, context.ignoredDiffs);
4777
- }
4778
- return next(context);
4779
- };
4780
- };
4781
- const getAssetsBackupHandler = (engine, {
4782
- force,
4783
- action: action2
4784
- }) => {
4785
- return async (context, next) => {
4786
- setSignalHandler(async () => {
4787
- await abortTransfer({ engine, strapi });
4788
- exitWith(1, exitMessageText(action2, true));
4789
- });
4790
- console.warn(
4791
- "The backup for the assets could not be created inside the public directory. Ensure Strapi has write permissions on the public directory."
4792
- );
4793
- const confirmed = await confirmMessage(
4794
- "Do you want to continue without backing up your public/uploads files?",
4795
- {
4796
- force
4797
- }
4798
- );
4799
- if (confirmed) {
4800
- context.ignore = true;
4801
- }
4802
- setSignalHandler(() => abortTransfer({ engine, strapi }));
4803
- return next(context);
4804
- };
4805
- };
4806
- const shouldSkipStage = (opts, dataKind) => {
4807
- if (opts.exclude?.includes(dataKind)) {
4808
- return true;
4809
- }
4810
- if (opts.only) {
4811
- return !opts.only.includes(dataKind);
4812
- }
4813
- return false;
4814
- };
4815
- const parseRestoreFromOptions = (opts) => {
4816
- const entitiesOptions = {
4817
- exclude: DEFAULT_IGNORED_CONTENT_TYPES,
4818
- include: void 0
4819
- };
4820
- if (opts.only && !opts.only.includes("content") || opts.exclude?.includes("content")) {
4821
- entitiesOptions.include = [];
4822
- }
4823
- const restoreConfig = {
4824
- entities: entitiesOptions,
4825
- assets: !shouldSkipStage(opts, "files"),
4826
- configuration: {
4827
- webhook: !shouldSkipStage(opts, "config"),
4828
- coreStore: !shouldSkipStage(opts, "config")
4829
- }
4830
- };
4831
- return restoreConfig;
4832
- };
4833
- const {
4834
- providers: { createLocalFileDestinationProvider }
4835
- } = file;
4836
- const {
4837
- providers: { createLocalStrapiSourceProvider: createLocalStrapiSourceProvider$1 }
4838
- } = strapiDatatransfer;
4839
- const BYTES_IN_MB = 1024 * 1024;
4840
- const action$2 = async (opts) => {
4841
- if (!fp.isObject(opts)) {
4842
- exitWith(1, "Could not parse command arguments");
4843
- }
4844
- const strapi2 = await createStrapiInstance();
4845
- const source = createSourceProvider(strapi2);
4846
- const destination = createDestinationProvider(opts);
4847
- const engine = createTransferEngine$2(source, destination, {
4848
- versionStrategy: "ignore",
4849
- // for an export to file, versionStrategy will always be skipped
4850
- schemaStrategy: "ignore",
4851
- // for an export to file, schemaStrategy will always be skipped
4852
- exclude: opts.exclude,
4853
- only: opts.only,
4854
- throttle: opts.throttle,
4855
- transforms: {
4856
- links: [
4857
- {
4858
- filter(link2) {
4859
- return !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.left.type) && !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.right.type);
4860
- }
4861
- }
4862
- ],
4863
- entities: [
4864
- {
4865
- filter(entity2) {
4866
- return !DEFAULT_IGNORED_CONTENT_TYPES.includes(entity2.type);
4867
- }
4868
- }
4869
- ]
4870
- }
4871
- });
4872
- engine.diagnostics.onDiagnostic(formatDiagnostic("export"));
4873
- const progress = engine.progress.stream;
4874
- const { updateLoader } = loadersFactory();
4875
- progress.on(`stage::start`, ({ stage, data }) => {
4876
- updateLoader(stage, data).start();
4877
- });
4878
- progress.on("stage::finish", ({ stage, data }) => {
4879
- updateLoader(stage, data).succeed();
4880
- });
4881
- progress.on("stage::progress", ({ stage, data }) => {
4882
- updateLoader(stage, data);
4883
- });
4884
- progress.on("transfer::start", async () => {
4885
- console.log(`Starting export...`);
4886
- await strapi2.telemetry.send("didDEITSProcessStart", getTransferTelemetryPayload(engine));
4887
- });
4888
- let results;
4889
- let outFile;
4890
- try {
4891
- setSignalHandler(() => abortTransfer({ engine, strapi: strapi2 }));
4892
- results = await engine.transfer();
4893
- outFile = results.destination?.file?.path ?? "";
4894
- const outFileExists = await fse__namespace.default.pathExists(outFile);
4895
- if (!outFileExists) {
4896
- throw new TransferEngineTransferError(`Export file not created "${outFile}"`);
4897
- }
4898
- await strapi2.telemetry.send("didDEITSProcessFinish", getTransferTelemetryPayload(engine));
4899
- try {
4900
- const table = buildTransferTable(results.engine);
4901
- console.log(table?.toString());
4902
- } catch (e) {
4903
- console.error("There was an error displaying the results of the transfer.");
4904
- }
4905
- console.log(`Export archive is in ${chalk__default.default.green(outFile)}`);
4906
- exitWith(0, exitMessageText("export"));
4907
- } catch {
4908
- await strapi2.telemetry.send("didDEITSProcessFail", getTransferTelemetryPayload(engine));
4909
- exitWith(1, exitMessageText("export", true));
4910
- }
4911
- };
4912
- const createSourceProvider = (strapi2) => {
4913
- return createLocalStrapiSourceProvider$1({
4914
- async getStrapi() {
4915
- return strapi2;
4916
- }
4917
- });
4918
- };
4919
- const createDestinationProvider = (opts) => {
4920
- const { file: file2, compress, encrypt, key, maxSizeJsonl } = opts;
4921
- const filepath = fp.isString(file2) && file2.length > 0 ? file2 : getDefaultExportName();
4922
- const maxSizeJsonlInMb = fp.isFinite(fp.toNumber(maxSizeJsonl)) ? fp.toNumber(maxSizeJsonl) * BYTES_IN_MB : void 0;
4923
- return createLocalFileDestinationProvider({
4924
- file: {
4925
- path: filepath,
4926
- maxSizeJsonl: maxSizeJsonlInMb
4927
- },
4928
- encryption: {
4929
- enabled: encrypt ?? false,
4930
- key: encrypt ? key : void 0
4931
- },
4932
- compression: {
4933
- enabled: compress ?? false
4934
- }
4935
- });
4936
- };
4937
- const command$2 = ({ command: command2 }) => {
4938
- command2.command("export").description("Export data from Strapi to file").allowExcessArguments(false).addOption(
4939
- new commander.Option("--no-encrypt", `Disables 'aes-128-ecb' encryption of the output file`).default(
4940
- true
4941
- )
4942
- ).addOption(
4943
- new commander.Option("--no-compress", "Disables gzip compression of output file").default(true)
4944
- ).addOption(
4945
- new commander.Option(
4946
- "-k, --key <string>",
4947
- "Provide encryption key in command instead of using the prompt"
4948
- )
4949
- ).addOption(
4950
- new commander.Option("-f, --file <file>", "name to use for exported file (without extensions)")
4951
- ).addOption(excludeOption).addOption(onlyOption).addOption(throttleOption).hook("preAction", validateExcludeOnly).hook("preAction", promptEncryptionKey).action(action$2);
4952
- };
4953
- const {
4954
- providers: { createLocalFileSourceProvider }
4955
- } = file;
4956
- const {
4957
- providers: { createLocalStrapiDestinationProvider: createLocalStrapiDestinationProvider$1, DEFAULT_CONFLICT_STRATEGY }
4958
- } = strapiDatatransfer;
4959
- const { createTransferEngine: createTransferEngine$1, DEFAULT_VERSION_STRATEGY, DEFAULT_SCHEMA_STRATEGY } = engineDatatransfer;
4960
- const action$1 = async (opts) => {
4961
- if (!fp.isObject(opts)) {
4962
- exitWith(1, "Could not parse arguments");
4963
- }
4964
- const sourceOptions = getLocalFileSourceOptions(opts);
4965
- const source = createLocalFileSourceProvider(sourceOptions);
4966
- const strapiInstance = await createStrapiInstance();
4967
- const engineOptions = {
4968
- versionStrategy: DEFAULT_VERSION_STRATEGY,
4969
- schemaStrategy: DEFAULT_SCHEMA_STRATEGY,
4970
- exclude: opts.exclude,
4971
- only: opts.only,
4972
- throttle: opts.throttle,
4973
- transforms: {
4974
- links: [
4975
- {
4976
- filter(link2) {
4977
- return !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.left.type) && !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.right.type);
4978
- }
4979
- }
4980
- ],
4981
- entities: [
4982
- {
4983
- filter: (entity2) => !DEFAULT_IGNORED_CONTENT_TYPES.includes(entity2.type)
4984
- }
4985
- ]
4986
- }
4987
- };
4988
- const destinationOptions = {
4989
- async getStrapi() {
4990
- return strapiInstance;
4991
- },
4992
- autoDestroy: false,
4993
- strategy: opts.conflictStrategy || DEFAULT_CONFLICT_STRATEGY,
4994
- restore: parseRestoreFromOptions(engineOptions)
4995
- };
4996
- const destination = createLocalStrapiDestinationProvider$1(destinationOptions);
4997
- destination.onWarning = (message) => console.warn(`
4998
- ${chalk__default.default.yellow("warn")}: ${message}`);
4999
- const engine2 = createTransferEngine$1(source, destination, engineOptions);
5000
- engine2.diagnostics.onDiagnostic(formatDiagnostic("import"));
5001
- const progress = engine2.progress.stream;
5002
- const { updateLoader } = loadersFactory();
5003
- engine2.onSchemaDiff(getDiffHandler(engine2, { force: opts.force, action: "import" }));
5004
- progress.on(`stage::start`, ({ stage, data }) => {
5005
- updateLoader(stage, data).start();
5006
- });
5007
- progress.on("stage::finish", ({ stage, data }) => {
5008
- updateLoader(stage, data).succeed();
5009
- });
5010
- progress.on("stage::progress", ({ stage, data }) => {
5011
- updateLoader(stage, data);
5012
- });
5013
- progress.on("transfer::start", async () => {
5014
- console.log("Starting import...");
5015
- await strapiInstance.telemetry.send(
5016
- "didDEITSProcessStart",
5017
- getTransferTelemetryPayload(engine2)
5018
- );
5019
- });
5020
- let results;
5021
- try {
5022
- setSignalHandler(() => abortTransfer({ engine: engine2, strapi }));
5023
- results = await engine2.transfer();
5024
- try {
5025
- const table = buildTransferTable(results.engine);
5026
- console.log(table?.toString());
5027
- } catch (e) {
5028
- console.error("There was an error displaying the results of the transfer.");
5029
- }
5030
- await strapiInstance.telemetry.send(
5031
- "didDEITSProcessFinish",
5032
- getTransferTelemetryPayload(engine2)
5033
- );
5034
- await strapiInstance.destroy();
5035
- exitWith(0, exitMessageText("import"));
5036
- } catch (e) {
5037
- await strapiInstance.telemetry.send("didDEITSProcessFail", getTransferTelemetryPayload(engine2));
5038
- exitWith(1, exitMessageText("import", true));
5039
- }
5040
- };
5041
- const getLocalFileSourceOptions = (opts) => {
5042
- const options = {
5043
- file: { path: opts.file ?? "" },
5044
- compression: { enabled: !!opts.decompress },
5045
- encryption: { enabled: !!opts.decrypt, key: opts.key }
5046
- };
5047
- return options;
5048
- };
5049
- const command$1 = ({ command: command2 }) => {
5050
- command2.command("import").description("Import data from file to Strapi").allowExcessArguments(false).requiredOption(
5051
- "-f, --file <file>",
5052
- "path and filename for the Strapi export file you want to import"
5053
- ).addOption(
5054
- new commander.Option(
5055
- "-k, --key <string>",
5056
- "Provide encryption key in command instead of using the prompt"
5057
- )
5058
- ).addOption(forceOption).addOption(excludeOption).addOption(onlyOption).addOption(throttleOption).hook("preAction", validateExcludeOnly).hook("preAction", async (thisCommand) => {
5059
- const opts = thisCommand.opts();
5060
- const ext = path__default.default.extname(String(opts.file));
5061
- if (ext === ".enc") {
5062
- if (!opts.key) {
5063
- const answers = await inquirer__default.default.prompt([
5064
- {
5065
- type: "password",
5066
- message: "Please enter your decryption key",
5067
- name: "key"
5068
- }
5069
- ]);
5070
- if (!answers.key?.length) {
5071
- exitWith(1, "No key entered, aborting import.");
5072
- }
5073
- opts.key = answers.key;
5074
- }
5075
- }
5076
- }).hook("preAction", (thisCommand) => {
5077
- const opts = thisCommand.opts();
5078
- const { extname, parse } = path__default.default;
5079
- let file2 = opts.file;
5080
- if (extname(file2) === ".enc") {
5081
- file2 = parse(file2).name;
5082
- thisCommand.opts().decrypt = true;
5083
- } else {
5084
- thisCommand.opts().decrypt = false;
5085
- }
5086
- if (extname(file2) === ".gz") {
5087
- file2 = parse(file2).name;
5088
- thisCommand.opts().decompress = true;
5089
- } else {
5090
- thisCommand.opts().decompress = false;
5091
- }
5092
- if (extname(file2) !== ".tar") {
5093
- exitWith(
5094
- 1,
5095
- `The file '${opts.file}' does not appear to be a valid Strapi data file. It must have an extension ending in .tar[.gz][.enc]`
5096
- );
5097
- }
5098
- }).hook(
5099
- "preAction",
5100
- getCommanderConfirmMessage(
5101
- "The import will delete your existing data! Are you sure you want to proceed?",
5102
- { failMessage: "Import process aborted" }
5103
- )
5104
- ).action(action$1);
5105
- };
5106
- const { createTransferEngine } = engineDatatransfer;
5107
- const {
5108
- providers: {
5109
- createRemoteStrapiDestinationProvider,
5110
- createLocalStrapiSourceProvider,
5111
- createLocalStrapiDestinationProvider,
5112
- createRemoteStrapiSourceProvider
5113
- }
5114
- } = strapiDatatransfer;
5115
- const action = async (opts) => {
5116
- if (!fp.isObject(opts)) {
5117
- exitWith(1, "Could not parse command arguments");
5118
- }
5119
- if (!(opts.from || opts.to) || opts.from && opts.to) {
5120
- exitWith(1, "Exactly one source (from) or destination (to) option must be provided");
5121
- }
5122
- const strapi2 = await createStrapiInstance();
5123
- let source;
5124
- let destination;
5125
- if (!opts.from) {
5126
- source = createLocalStrapiSourceProvider({
5127
- getStrapi: () => strapi2
5128
- });
5129
- } else {
5130
- if (!opts.fromToken) {
5131
- exitWith(1, "Missing token for remote destination");
5132
- }
5133
- source = createRemoteStrapiSourceProvider({
5134
- getStrapi: () => strapi2,
5135
- url: opts.from,
5136
- auth: {
5137
- type: "token",
5138
- token: opts.fromToken
5139
- }
5140
- });
5141
- }
5142
- if (!opts.to) {
5143
- destination = createLocalStrapiDestinationProvider({
5144
- getStrapi: () => strapi2,
5145
- strategy: "restore",
5146
- restore: parseRestoreFromOptions(opts)
5147
- });
5148
- } else {
5149
- if (!opts.toToken) {
5150
- exitWith(1, "Missing token for remote destination");
5151
- }
5152
- destination = createRemoteStrapiDestinationProvider({
5153
- url: opts.to,
5154
- auth: {
5155
- type: "token",
5156
- token: opts.toToken
5157
- },
5158
- strategy: "restore",
5159
- restore: parseRestoreFromOptions(opts)
5160
- });
5161
- }
5162
- if (!source || !destination) {
5163
- exitWith(1, "Could not create providers");
5164
- }
5165
- const engine = createTransferEngine(source, destination, {
5166
- versionStrategy: "exact",
5167
- schemaStrategy: "strict",
5168
- exclude: opts.exclude,
5169
- only: opts.only,
5170
- throttle: opts.throttle,
5171
- transforms: {
5172
- links: [
5173
- {
5174
- filter(link2) {
5175
- return !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.left.type) && !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.right.type);
5176
- }
5177
- }
5178
- ],
5179
- entities: [
5180
- {
5181
- filter(entity2) {
5182
- return !DEFAULT_IGNORED_CONTENT_TYPES.includes(entity2.type);
5183
- }
5184
- }
5185
- ]
5186
- }
5187
- });
5188
- engine.diagnostics.onDiagnostic(formatDiagnostic("transfer"));
5189
- const progress = engine.progress.stream;
5190
- const { updateLoader } = loadersFactory();
5191
- engine.onSchemaDiff(getDiffHandler(engine, { force: opts.force, action: "transfer" }));
5192
- engine.addErrorHandler(
5193
- "ASSETS_DIRECTORY_ERR",
5194
- getAssetsBackupHandler(engine, { force: opts.force, action: "transfer" })
5195
- );
5196
- progress.on(`stage::start`, ({ stage, data }) => {
5197
- updateLoader(stage, data).start();
5198
- });
5199
- progress.on("stage::finish", ({ stage, data }) => {
5200
- updateLoader(stage, data).succeed();
5201
- });
5202
- progress.on("stage::progress", ({ stage, data }) => {
5203
- updateLoader(stage, data);
5204
- });
5205
- progress.on("stage::error", ({ stage, data }) => {
5206
- updateLoader(stage, data).fail();
5207
- });
5208
- progress.on("transfer::start", async () => {
5209
- console.log(`Starting transfer...`);
5210
- await strapi2.telemetry.send("didDEITSProcessStart", getTransferTelemetryPayload(engine));
5211
- });
5212
- let results;
5213
- try {
5214
- setSignalHandler(() => abortTransfer({ engine, strapi: strapi2 }));
5215
- results = await engine.transfer();
5216
- await strapi2.telemetry.send("didDEITSProcessFinish", getTransferTelemetryPayload(engine));
5217
- try {
5218
- const table = buildTransferTable(results.engine);
5219
- console.log(table?.toString());
5220
- } catch (e) {
5221
- console.error("There was an error displaying the results of the transfer.");
5222
- }
5223
- exitWith(0, exitMessageText("transfer"));
5224
- } catch (e) {
5225
- await strapi2.telemetry.send("didDEITSProcessFail", getTransferTelemetryPayload(engine));
5226
- exitWith(1, exitMessageText("transfer", true));
5227
- }
5228
- };
5229
- const command = ({ command: command2 }) => {
5230
- command2.command("transfer").description("Transfer data from one source to another").allowExcessArguments(false).addOption(
5231
- new commander.Option(
5232
- "--from <sourceURL>",
5233
- `URL of the remote Strapi instance to get data from`
5234
- ).argParser(parseURL)
5235
- ).addOption(new commander.Option("--from-token <token>", `Transfer token for the remote Strapi source`)).addOption(
5236
- new commander.Option(
5237
- "--to <destinationURL>",
5238
- `URL of the remote Strapi instance to send data to`
5239
- ).argParser(parseURL)
5240
- ).addOption(new commander.Option("--to-token <token>", `Transfer token for the remote Strapi destination`)).addOption(forceOption).addOption(excludeOption).addOption(onlyOption).addOption(throttleOption).hook("preAction", validateExcludeOnly).hook(
5241
- "preAction",
5242
- ifOptions(
5243
- (opts) => !(opts.from || opts.to) || opts.from && opts.to,
5244
- async () => exitWith(
5245
- 1,
5246
- "Exactly one remote source (from) or destination (to) option must be provided"
5247
- )
5248
- )
5249
- ).hook(
5250
- "preAction",
5251
- ifOptions(
5252
- (opts) => opts.from,
5253
- async (thisCommand) => {
5254
- assertUrlHasProtocol(thisCommand.opts().from, ["https:", "http:"]);
5255
- if (!thisCommand.opts().fromToken) {
5256
- const answers = await inquirer__default.default.prompt([
5257
- {
5258
- type: "password",
5259
- message: "Please enter your transfer token for the remote Strapi source",
5260
- name: "fromToken"
5261
- }
5262
- ]);
5263
- if (!answers.fromToken?.length) {
5264
- exitWith(1, "No token provided for remote source, aborting transfer.");
5265
- }
5266
- thisCommand.opts().fromToken = answers.fromToken;
5267
- }
5268
- await getCommanderConfirmMessage(
5269
- "The transfer will delete all the local Strapi assets and its database. Are you sure you want to proceed?",
5270
- { failMessage: "Transfer process aborted" }
5271
- )(thisCommand);
5272
- }
5273
- )
5274
- ).hook(
5275
- "preAction",
5276
- ifOptions(
5277
- (opts) => opts.to,
5278
- async (thisCommand) => {
5279
- assertUrlHasProtocol(thisCommand.opts().to, ["https:", "http:"]);
5280
- if (!thisCommand.opts().toToken) {
5281
- const answers = await inquirer__default.default.prompt([
5282
- {
5283
- type: "password",
5284
- message: "Please enter your transfer token for the remote Strapi destination",
5285
- name: "toToken"
5286
- }
5287
- ]);
5288
- if (!answers.toToken?.length) {
5289
- exitWith(1, "No token provided for remote destination, aborting transfer.");
5290
- }
5291
- thisCommand.opts().toToken = answers.toToken;
5292
- }
5293
- await getCommanderConfirmMessage(
5294
- "The transfer will delete existing data from the remote Strapi! Are you sure you want to proceed?",
5295
- { failMessage: "Transfer process aborted" }
5296
- )(thisCommand);
5297
- }
5298
- )
5299
- ).action(action);
5300
- };
5301
4370
  const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
5302
4371
  __proto__: null,
5303
- export: command$2,
5304
- import: command$1,
5305
- transfer: command
4372
+ providers: index$1
5306
4373
  }, Symbol.toStringTag, { value: "Module" }));
5307
- exports.commands = index;
5308
- exports.engine = engineDatatransfer;
5309
- exports.file = file;
5310
- exports.strapi = strapiDatatransfer;
5311
- exports.utils = index$6;
4374
+ exports.engine = index$7;
4375
+ exports.file = index;
4376
+ exports.strapi = index$2;
4377
+ exports.utils = index$8;
5312
4378
  //# sourceMappingURL=index.js.map