@strapi/data-transfer 4.20.5 → 5.0.0-alpha.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.
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +170 -1104
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +171 -1100
- package/dist/index.mjs.map +1 -1
- package/dist/strapi/providers/local-destination/strategies/restore/index.d.ts.map +1 -1
- package/dist/strapi/providers/local-source/assets.d.ts +1 -0
- package/dist/strapi/providers/local-source/assets.d.ts.map +1 -1
- package/dist/strapi/providers/local-source/configuration.d.ts +1 -0
- package/dist/strapi/providers/local-source/configuration.d.ts.map +1 -1
- package/dist/strapi/providers/local-source/entities.d.ts +1 -0
- package/dist/strapi/providers/local-source/entities.d.ts.map +1 -1
- package/dist/strapi/providers/local-source/links.d.ts +1 -0
- package/dist/strapi/providers/local-source/links.d.ts.map +1 -1
- package/dist/strapi/providers/remote-source/index.d.ts.map +1 -1
- package/dist/strapi/remote/handlers/utils.d.ts +1 -1
- package/dist/strapi/remote/handlers/utils.d.ts.map +1 -1
- package/dist/utils/components.d.ts +1 -4
- package/dist/utils/components.d.ts.map +1 -1
- package/dist/utils/encryption/decrypt.d.ts +1 -0
- package/dist/utils/encryption/decrypt.d.ts.map +1 -1
- package/dist/utils/encryption/encrypt.d.ts +1 -0
- package/dist/utils/encryption/encrypt.d.ts.map +1 -1
- package/package.json +12 -15
- package/dist/commands/commander.d.ts +0 -36
- package/dist/commands/commander.d.ts.map +0 -1
- package/dist/commands/data-transfer.d.ts +0 -63
- package/dist/commands/data-transfer.d.ts.map +0 -1
- package/dist/commands/export/action.d.ts +0 -21
- package/dist/commands/export/action.d.ts.map +0 -1
- package/dist/commands/export/command.d.ts +0 -9
- package/dist/commands/export/command.d.ts.map +0 -1
- package/dist/commands/helpers.d.ts +0 -31
- package/dist/commands/helpers.d.ts.map +0 -1
- package/dist/commands/import/action.d.ts +0 -20
- package/dist/commands/import/action.d.ts.map +0 -1
- package/dist/commands/import/command.d.ts +0 -9
- package/dist/commands/import/command.d.ts.map +0 -1
- package/dist/commands/index.d.ts +0 -4
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/transfer/action.d.ts +0 -19
- package/dist/commands/transfer/action.d.ts.map +0 -1
- package/dist/commands/transfer/command.d.ts +0 -9
- package/dist/commands/transfer/command.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -2,29 +2,22 @@ import { Transform, PassThrough, Writable, Readable, Duplex, pipeline } from "st
|
|
|
2
2
|
import path, { extname, join, posix } from "path";
|
|
3
3
|
import { EOL } from "os";
|
|
4
4
|
import { chain } from "stream-chain";
|
|
5
|
-
import { isArray, zip, isObject, uniq, isEqual, mapValues, pick, reject as reject$1, capitalize, isNumber, isEmpty, last, difference, set, omit, has, pipe, assign, map as map$1, size, isNil, clone, get, once, castArray, keyBy
|
|
5
|
+
import { isArray, zip, isObject, uniq, isEqual, mapValues, pick, reject as reject$1, capitalize, isNumber, isEmpty, last, difference, set, omit, has, pipe, assign, map as map$1, size, isNil, clone, get, once, castArray, keyBy } from "lodash/fp";
|
|
6
6
|
import { diff as diff$1 } from "semver";
|
|
7
7
|
import { scryptSync, createCipheriv, createDecipheriv, randomUUID } from "crypto";
|
|
8
8
|
import { EventEmitter } from "events";
|
|
9
9
|
import * as fse from "fs-extra";
|
|
10
10
|
import fse__default, { createReadStream, stat, createWriteStream, rm } from "fs-extra";
|
|
11
11
|
import _ from "lodash";
|
|
12
|
-
import { contentTypes,
|
|
12
|
+
import { contentTypes, async } from "@strapi/utils";
|
|
13
13
|
import chalk from "chalk";
|
|
14
|
-
import
|
|
15
|
-
import http from "http";
|
|
14
|
+
import * as webStream from "stream/web";
|
|
16
15
|
import { WebSocket } from "ws";
|
|
17
16
|
import zip$1 from "zlib";
|
|
18
17
|
import tar from "tar";
|
|
19
18
|
import { parser } from "stream-json/jsonl/Parser";
|
|
20
19
|
import tar$1 from "tar-stream";
|
|
21
20
|
import { stringer } from "stream-json/jsonl/Stringer";
|
|
22
|
-
import { Option, InvalidOptionArgumentError } from "commander";
|
|
23
|
-
import Table from "cli-table3";
|
|
24
|
-
import { createLogger, configs } from "@strapi/logger";
|
|
25
|
-
import strapiFactory from "@strapi/strapi";
|
|
26
|
-
import ora from "ora";
|
|
27
|
-
import inquirer from "inquirer";
|
|
28
21
|
const getEncryptionStrategy = (algorithm) => {
|
|
29
22
|
const strategies2 = {
|
|
30
23
|
"aes-128-ecb"(key) {
|
|
@@ -89,7 +82,7 @@ const getDecryptionStrategy = (algorithm) => {
|
|
|
89
82
|
const createDecryptionCipher = (key, algorithm = "aes-128-ecb") => {
|
|
90
83
|
return getDecryptionStrategy(algorithm)(key);
|
|
91
84
|
};
|
|
92
|
-
const index$
|
|
85
|
+
const index$9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
93
86
|
__proto__: null,
|
|
94
87
|
createDecryptionCipher,
|
|
95
88
|
createEncryptionCipher
|
|
@@ -301,9 +294,9 @@ const middleware = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
|
|
|
301
294
|
__proto__: null,
|
|
302
295
|
runMiddleware
|
|
303
296
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
304
|
-
const index$
|
|
297
|
+
const index$8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
305
298
|
__proto__: null,
|
|
306
|
-
encryption: index$
|
|
299
|
+
encryption: index$9,
|
|
307
300
|
json,
|
|
308
301
|
middleware,
|
|
309
302
|
schema,
|
|
@@ -366,11 +359,11 @@ class TransferEngineError extends DataTransferError {
|
|
|
366
359
|
super("engine", severity, message, details);
|
|
367
360
|
}
|
|
368
361
|
}
|
|
369
|
-
|
|
362
|
+
class TransferEngineInitializationError extends TransferEngineError {
|
|
370
363
|
constructor(message) {
|
|
371
364
|
super(SeverityKind.FATAL, message, { step: "initialization" });
|
|
372
365
|
}
|
|
373
|
-
}
|
|
366
|
+
}
|
|
374
367
|
class TransferEngineValidationError extends TransferEngineError {
|
|
375
368
|
constructor(message, details) {
|
|
376
369
|
super(SeverityKind.FATAL, message, { step: "validation", details });
|
|
@@ -384,7 +377,7 @@ class TransferEngineTransferError extends TransferEngineError {
|
|
|
384
377
|
const errors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
385
378
|
__proto__: null,
|
|
386
379
|
TransferEngineError,
|
|
387
|
-
TransferEngineInitializationError
|
|
380
|
+
TransferEngineInitializationError,
|
|
388
381
|
TransferEngineTransferError,
|
|
389
382
|
TransferEngineValidationError
|
|
390
383
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -496,8 +489,8 @@ const TransferGroupPresets = {
|
|
|
496
489
|
configuration: true
|
|
497
490
|
}
|
|
498
491
|
};
|
|
499
|
-
const DEFAULT_VERSION_STRATEGY
|
|
500
|
-
const DEFAULT_SCHEMA_STRATEGY
|
|
492
|
+
const DEFAULT_VERSION_STRATEGY = "ignore";
|
|
493
|
+
const DEFAULT_SCHEMA_STRATEGY = "strict";
|
|
501
494
|
class TransferEngine {
|
|
502
495
|
sourceProvider;
|
|
503
496
|
destinationProvider;
|
|
@@ -690,7 +683,7 @@ class TransferEngine {
|
|
|
690
683
|
* If there is a mismatch, throws a validation error.
|
|
691
684
|
*/
|
|
692
685
|
#assertStrapiVersionIntegrity(sourceVersion, destinationVersion) {
|
|
693
|
-
const strategy = this.options.versionStrategy || DEFAULT_VERSION_STRATEGY
|
|
686
|
+
const strategy = this.options.versionStrategy || DEFAULT_VERSION_STRATEGY;
|
|
694
687
|
const reject2 = () => {
|
|
695
688
|
throw new TransferEngineValidationError(
|
|
696
689
|
`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}`,
|
|
@@ -733,7 +726,7 @@ class TransferEngine {
|
|
|
733
726
|
* If there are differences and/or incompatibilities between source and destination schemas, then throw a validation error.
|
|
734
727
|
*/
|
|
735
728
|
#assertSchemasMatching(sourceSchemas, destinationSchemas) {
|
|
736
|
-
const strategy = this.options.schemaStrategy || DEFAULT_SCHEMA_STRATEGY
|
|
729
|
+
const strategy = this.options.schemaStrategy || DEFAULT_SCHEMA_STRATEGY;
|
|
737
730
|
if (strategy === "ignore") {
|
|
738
731
|
return;
|
|
739
732
|
}
|
|
@@ -1110,16 +1103,16 @@ ${formattedDiffs}`,
|
|
|
1110
1103
|
await this.#transferStage({ stage, source, destination, transform, tracker });
|
|
1111
1104
|
}
|
|
1112
1105
|
}
|
|
1113
|
-
const createTransferEngine
|
|
1106
|
+
const createTransferEngine = (sourceProvider, destinationProvider, options) => {
|
|
1114
1107
|
return new TransferEngine(sourceProvider, destinationProvider, options);
|
|
1115
1108
|
};
|
|
1116
|
-
const
|
|
1109
|
+
const index$7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1117
1110
|
__proto__: null,
|
|
1118
|
-
DEFAULT_SCHEMA_STRATEGY
|
|
1119
|
-
DEFAULT_VERSION_STRATEGY
|
|
1111
|
+
DEFAULT_SCHEMA_STRATEGY,
|
|
1112
|
+
DEFAULT_VERSION_STRATEGY,
|
|
1120
1113
|
TRANSFER_STAGES,
|
|
1121
1114
|
TransferGroupPresets,
|
|
1122
|
-
createTransferEngine
|
|
1115
|
+
createTransferEngine,
|
|
1123
1116
|
errors
|
|
1124
1117
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1125
1118
|
const isDialectMySQL = () => strapi.db?.dialect.client === "mysql";
|
|
@@ -1149,7 +1142,7 @@ const createComponents = async (uid, data) => {
|
|
|
1149
1142
|
if (!Array.isArray(componentValue)) {
|
|
1150
1143
|
throw new Error("Expected an array to create repeatable component");
|
|
1151
1144
|
}
|
|
1152
|
-
const components = await
|
|
1145
|
+
const components = await async.map(
|
|
1153
1146
|
componentValue,
|
|
1154
1147
|
(value) => createComponent(componentUID, value),
|
|
1155
1148
|
{ concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
|
|
@@ -1193,7 +1186,7 @@ const createComponents = async (uid, data) => {
|
|
|
1193
1186
|
}
|
|
1194
1187
|
};
|
|
1195
1188
|
};
|
|
1196
|
-
componentBody[attributeName] = await
|
|
1189
|
+
componentBody[attributeName] = await async.map(
|
|
1197
1190
|
dynamiczoneValues,
|
|
1198
1191
|
createDynamicZoneComponents,
|
|
1199
1192
|
{ concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
|
|
@@ -1208,7 +1201,7 @@ const getComponents = async (uid, entity2) => {
|
|
|
1208
1201
|
if (_.isEmpty(componentAttributes)) {
|
|
1209
1202
|
return {};
|
|
1210
1203
|
}
|
|
1211
|
-
return strapi.query(uid).load(entity2, componentAttributes);
|
|
1204
|
+
return strapi.db.query(uid).load(entity2, componentAttributes);
|
|
1212
1205
|
};
|
|
1213
1206
|
const deleteComponents = async (uid, entityToDelete, { loadComponents = true } = {}) => {
|
|
1214
1207
|
const { attributes = {} } = strapi.getModel(uid);
|
|
@@ -1218,7 +1211,7 @@ const deleteComponents = async (uid, entityToDelete, { loadComponents = true } =
|
|
|
1218
1211
|
if (attribute.type === "component" || attribute.type === "dynamiczone") {
|
|
1219
1212
|
let value;
|
|
1220
1213
|
if (loadComponents) {
|
|
1221
|
-
value = await strapi.query(uid).load(entityToDelete, attributeName);
|
|
1214
|
+
value = await strapi.db.query(uid).load(entityToDelete, attributeName);
|
|
1222
1215
|
} else {
|
|
1223
1216
|
value = entityToDelete[attributeName];
|
|
1224
1217
|
}
|
|
@@ -1227,7 +1220,7 @@ const deleteComponents = async (uid, entityToDelete, { loadComponents = true } =
|
|
|
1227
1220
|
}
|
|
1228
1221
|
if (attribute.type === "component") {
|
|
1229
1222
|
const { component: componentUID } = attribute;
|
|
1230
|
-
await
|
|
1223
|
+
await async.map(
|
|
1231
1224
|
_.castArray(value),
|
|
1232
1225
|
(subValue) => deleteComponent(componentUID, subValue),
|
|
1233
1226
|
{
|
|
@@ -1235,7 +1228,7 @@ const deleteComponents = async (uid, entityToDelete, { loadComponents = true } =
|
|
|
1235
1228
|
}
|
|
1236
1229
|
);
|
|
1237
1230
|
} else {
|
|
1238
|
-
await
|
|
1231
|
+
await async.map(
|
|
1239
1232
|
_.castArray(value),
|
|
1240
1233
|
(subValue) => deleteComponent(subValue.__component, subValue),
|
|
1241
1234
|
{ concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
|
|
@@ -1256,11 +1249,11 @@ const createComponent = async (uid, data) => {
|
|
|
1256
1249
|
// ... and assign the newly created component instead
|
|
1257
1250
|
assign(componentData)
|
|
1258
1251
|
);
|
|
1259
|
-
return strapi.query(uid).create({ data: transform(data) });
|
|
1252
|
+
return strapi.db.query(uid).create({ data: transform(data) });
|
|
1260
1253
|
};
|
|
1261
1254
|
const deleteComponent = async (uid, componentToDelete) => {
|
|
1262
1255
|
await deleteComponents(uid, componentToDelete);
|
|
1263
|
-
await strapi.query(uid).delete({ where: { id: componentToDelete.id } });
|
|
1256
|
+
await strapi.db.query(uid).delete({ where: { id: componentToDelete.id } });
|
|
1264
1257
|
};
|
|
1265
1258
|
const sanitizeComponentLikeAttributes = (model, data) => {
|
|
1266
1259
|
const { attributes } = model;
|
|
@@ -1612,7 +1605,7 @@ const link = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty
|
|
|
1612
1605
|
__proto__: null,
|
|
1613
1606
|
createLinkQuery
|
|
1614
1607
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1615
|
-
const index$
|
|
1608
|
+
const index$6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1616
1609
|
__proto__: null,
|
|
1617
1610
|
entity,
|
|
1618
1611
|
link
|
|
@@ -1691,7 +1684,7 @@ const restoreCoreStore = async (strapi2, values) => {
|
|
|
1691
1684
|
};
|
|
1692
1685
|
const restoreWebhooks = async (strapi2, values) => {
|
|
1693
1686
|
const data = omitInvalidCreationAttributes(values);
|
|
1694
|
-
return strapi2.db.query("webhook").create({ data });
|
|
1687
|
+
return strapi2.db.query("strapi::webhook").create({ data });
|
|
1695
1688
|
};
|
|
1696
1689
|
const restoreConfigs = async (strapi2, config) => {
|
|
1697
1690
|
if (config.type === "core-store") {
|
|
@@ -1779,10 +1772,8 @@ const deleteRecords = async (strapi2, options) => {
|
|
|
1779
1772
|
};
|
|
1780
1773
|
const deleteEntitiesRecords = async (strapi2, options = {}) => {
|
|
1781
1774
|
const { entities } = options;
|
|
1782
|
-
const
|
|
1783
|
-
const contentTypes2 = Object.values(
|
|
1784
|
-
strapi2.contentTypes
|
|
1785
|
-
);
|
|
1775
|
+
const models = strapi2.get("models").get();
|
|
1776
|
+
const contentTypes2 = Object.values(strapi2.contentTypes);
|
|
1786
1777
|
const contentTypesToClear = contentTypes2.filter((contentType) => {
|
|
1787
1778
|
let removeThisContentType = true;
|
|
1788
1779
|
if (entities?.include) {
|
|
@@ -1795,17 +1786,35 @@ const deleteEntitiesRecords = async (strapi2, options = {}) => {
|
|
|
1795
1786
|
removeThisContentType = entities.filters.every((filter2) => filter2(contentType));
|
|
1796
1787
|
}
|
|
1797
1788
|
return removeThisContentType;
|
|
1789
|
+
}).map((contentType) => contentType.uid);
|
|
1790
|
+
const modelsToClear = models.filter((model) => {
|
|
1791
|
+
if (contentTypesToClear.includes(model.uid)) {
|
|
1792
|
+
return false;
|
|
1793
|
+
}
|
|
1794
|
+
let removeThisModel = true;
|
|
1795
|
+
if (entities?.include) {
|
|
1796
|
+
removeThisModel = entities.include.includes(model.uid);
|
|
1797
|
+
}
|
|
1798
|
+
if (entities?.exclude && entities.exclude.includes(model.uid)) {
|
|
1799
|
+
removeThisModel = false;
|
|
1800
|
+
}
|
|
1801
|
+
return removeThisModel;
|
|
1802
|
+
}).map((model) => model.uid);
|
|
1803
|
+
const [results, updateResults] = useResults([...contentTypesToClear, ...modelsToClear]);
|
|
1804
|
+
const contentTypeQuery = createEntityQuery(strapi2);
|
|
1805
|
+
const contentTypePromises = contentTypesToClear.map(async (uid) => {
|
|
1806
|
+
const result = await contentTypeQuery(uid).deleteMany(entities?.params);
|
|
1807
|
+
if (result) {
|
|
1808
|
+
updateResults(result.count || 0, uid);
|
|
1809
|
+
}
|
|
1798
1810
|
});
|
|
1799
|
-
const
|
|
1800
|
-
|
|
1801
|
-
);
|
|
1802
|
-
const deletePromises = contentTypesToClear.map(async (contentType) => {
|
|
1803
|
-
const result = await query(contentType.uid).deleteMany(entities?.params);
|
|
1811
|
+
const modelsPromises = modelsToClear.map(async (uid) => {
|
|
1812
|
+
const result = await strapi2.db.query(uid).deleteMany({});
|
|
1804
1813
|
if (result) {
|
|
1805
|
-
updateResults(result.count || 0,
|
|
1814
|
+
updateResults(result.count || 0, uid);
|
|
1806
1815
|
}
|
|
1807
1816
|
});
|
|
1808
|
-
await Promise.all(
|
|
1817
|
+
await Promise.all([...contentTypePromises, ...modelsPromises]);
|
|
1809
1818
|
return results;
|
|
1810
1819
|
};
|
|
1811
1820
|
const deleteConfigurationRecords = async (strapi2, options = {}) => {
|
|
@@ -1815,7 +1824,7 @@ const deleteConfigurationRecords = async (strapi2, options = {}) => {
|
|
|
1815
1824
|
models.push("strapi::core-store");
|
|
1816
1825
|
}
|
|
1817
1826
|
if (webhook) {
|
|
1818
|
-
models.push("webhook");
|
|
1827
|
+
models.push("strapi::webhook");
|
|
1819
1828
|
}
|
|
1820
1829
|
const [results, updateResults] = useResults(models);
|
|
1821
1830
|
const deletePromises = models.map(async (uid) => {
|
|
@@ -1849,7 +1858,7 @@ const assertValidStrapi = (strapi2, msg = "") => {
|
|
|
1849
1858
|
}
|
|
1850
1859
|
};
|
|
1851
1860
|
const VALID_CONFLICT_STRATEGIES = ["restore"];
|
|
1852
|
-
const DEFAULT_CONFLICT_STRATEGY
|
|
1861
|
+
const DEFAULT_CONFLICT_STRATEGY = "restore";
|
|
1853
1862
|
class LocalStrapiDestinationProvider {
|
|
1854
1863
|
name = "destination::local-strapi";
|
|
1855
1864
|
type = "destination";
|
|
@@ -1916,10 +1925,10 @@ class LocalStrapiDestinationProvider {
|
|
|
1916
1925
|
return;
|
|
1917
1926
|
}
|
|
1918
1927
|
const stream2 = this.strapi.db.queryBuilder("plugin::upload.file").select("*").transacting(trx).stream();
|
|
1919
|
-
for await (const
|
|
1920
|
-
await this.strapi.plugin("upload").provider.delete(
|
|
1921
|
-
if (
|
|
1922
|
-
for (const fileFormat of Object.values(
|
|
1928
|
+
for await (const file of stream2) {
|
|
1929
|
+
await this.strapi.plugin("upload").provider.delete(file);
|
|
1930
|
+
if (file.formats) {
|
|
1931
|
+
for (const fileFormat of Object.values(file.formats)) {
|
|
1923
1932
|
await this.strapi.plugin("upload").provider.delete(fileFormat);
|
|
1924
1933
|
}
|
|
1925
1934
|
}
|
|
@@ -1990,7 +1999,7 @@ class LocalStrapiDestinationProvider {
|
|
|
1990
1999
|
if (!this.#areAssetsIncluded()) {
|
|
1991
2000
|
return;
|
|
1992
2001
|
}
|
|
1993
|
-
if (this.strapi.config.get("plugin
|
|
2002
|
+
if (this.strapi.config.get("plugin::upload").provider === "local") {
|
|
1994
2003
|
const assetsDirectory = path.join(this.strapi.dirs.static.public, "uploads");
|
|
1995
2004
|
const backupDirectory = path.join(
|
|
1996
2005
|
this.strapi.dirs.static.public,
|
|
@@ -2022,7 +2031,7 @@ class LocalStrapiDestinationProvider {
|
|
|
2022
2031
|
if (!this.#areAssetsIncluded()) {
|
|
2023
2032
|
return;
|
|
2024
2033
|
}
|
|
2025
|
-
if (this.strapi.config.get("plugin
|
|
2034
|
+
if (this.strapi.config.get("plugin::upload").provider === "local") {
|
|
2026
2035
|
assertValidStrapi(this.strapi);
|
|
2027
2036
|
const backupDirectory = path.join(
|
|
2028
2037
|
this.strapi.dirs.static.public,
|
|
@@ -2083,7 +2092,7 @@ class LocalStrapiDestinationProvider {
|
|
|
2083
2092
|
stream: Readable.from(chunk.stream),
|
|
2084
2093
|
buffer: chunk?.buffer
|
|
2085
2094
|
};
|
|
2086
|
-
const provider = strapi2.config.get("plugin
|
|
2095
|
+
const provider = strapi2.config.get("plugin::upload").provider;
|
|
2087
2096
|
try {
|
|
2088
2097
|
await strapi2.plugin("upload").provider.uploadStream(uploadData);
|
|
2089
2098
|
if (!restoreMediaEntitiesContent) {
|
|
@@ -2154,7 +2163,7 @@ class LocalStrapiDestinationProvider {
|
|
|
2154
2163
|
});
|
|
2155
2164
|
}
|
|
2156
2165
|
}
|
|
2157
|
-
const createLocalStrapiDestinationProvider
|
|
2166
|
+
const createLocalStrapiDestinationProvider = (options) => {
|
|
2158
2167
|
return new LocalStrapiDestinationProvider(options);
|
|
2159
2168
|
};
|
|
2160
2169
|
const createEntitiesStream = (strapi2) => {
|
|
@@ -2218,7 +2227,7 @@ const createConfigurationStream = (strapi2) => {
|
|
|
2218
2227
|
wrapConfigurationItem("core-store")
|
|
2219
2228
|
]);
|
|
2220
2229
|
const webhooksStream = chain([
|
|
2221
|
-
strapi2.db.queryBuilder("webhook").stream(),
|
|
2230
|
+
strapi2.db.queryBuilder("strapi::webhook").stream(),
|
|
2222
2231
|
wrapConfigurationItem("webhook")
|
|
2223
2232
|
]);
|
|
2224
2233
|
const streams = [coreStoreStream, webhooksStream];
|
|
@@ -2234,44 +2243,42 @@ const wrapConfigurationItem = (type) => (value) => ({
|
|
|
2234
2243
|
type,
|
|
2235
2244
|
value
|
|
2236
2245
|
});
|
|
2237
|
-
|
|
2238
|
-
return filepath?.startsWith("https") ? https : http;
|
|
2239
|
-
};
|
|
2240
|
-
function getFileStream(filepath, isLocal = false) {
|
|
2246
|
+
function getFileStream(filepath, strapi2, isLocal = false) {
|
|
2241
2247
|
if (isLocal) {
|
|
2242
2248
|
return createReadStream(filepath);
|
|
2243
2249
|
}
|
|
2244
2250
|
const readableStream = new PassThrough();
|
|
2245
|
-
|
|
2246
|
-
if (res.
|
|
2247
|
-
readableStream.emit(
|
|
2248
|
-
"error",
|
|
2249
|
-
new Error(`Request failed with status code ${res.statusCode}`)
|
|
2250
|
-
);
|
|
2251
|
+
strapi2.fetch(filepath).then((res) => {
|
|
2252
|
+
if (res.status !== 200) {
|
|
2253
|
+
readableStream.emit("error", new Error(`Request failed with status code ${res.status}`));
|
|
2251
2254
|
return;
|
|
2252
2255
|
}
|
|
2253
|
-
res.
|
|
2254
|
-
|
|
2256
|
+
if (res.body) {
|
|
2257
|
+
Readable.fromWeb(new webStream.ReadableStream(res.body)).pipe(readableStream);
|
|
2258
|
+
} else {
|
|
2259
|
+
readableStream.emit("error", new Error("Empty data found for file"));
|
|
2260
|
+
}
|
|
2261
|
+
}).catch((error) => {
|
|
2255
2262
|
readableStream.emit("error", error);
|
|
2256
2263
|
});
|
|
2257
2264
|
return readableStream;
|
|
2258
2265
|
}
|
|
2259
|
-
function getFileStats(filepath, isLocal = false) {
|
|
2266
|
+
function getFileStats(filepath, strapi2, isLocal = false) {
|
|
2260
2267
|
if (isLocal) {
|
|
2261
2268
|
return stat(filepath);
|
|
2262
2269
|
}
|
|
2263
2270
|
return new Promise((resolve, reject2) => {
|
|
2264
|
-
|
|
2265
|
-
if (res.
|
|
2266
|
-
reject2(new Error(`Request failed with status code ${res.
|
|
2271
|
+
strapi2.fetch(filepath).then((res) => {
|
|
2272
|
+
if (res.status !== 200) {
|
|
2273
|
+
reject2(new Error(`Request failed with status code ${res.status}`));
|
|
2267
2274
|
return;
|
|
2268
2275
|
}
|
|
2269
|
-
const contentLength = res.headers
|
|
2276
|
+
const contentLength = res.headers.get("content-length");
|
|
2270
2277
|
const stats = {
|
|
2271
2278
|
size: contentLength ? parseInt(contentLength, 10) : 0
|
|
2272
2279
|
};
|
|
2273
2280
|
resolve(stats);
|
|
2274
|
-
}).
|
|
2281
|
+
}).catch((error) => {
|
|
2275
2282
|
reject2(error);
|
|
2276
2283
|
});
|
|
2277
2284
|
});
|
|
@@ -2279,25 +2286,25 @@ function getFileStats(filepath, isLocal = false) {
|
|
|
2279
2286
|
const createAssetsStream = (strapi2) => {
|
|
2280
2287
|
const generator = async function* () {
|
|
2281
2288
|
const stream2 = strapi2.db.queryBuilder("plugin::upload.file").select("*").stream();
|
|
2282
|
-
for await (const
|
|
2283
|
-
const isLocalProvider =
|
|
2284
|
-
const filepath = isLocalProvider ? join(strapi2.dirs.static.public,
|
|
2285
|
-
const stats = await getFileStats(filepath, isLocalProvider);
|
|
2286
|
-
const stream22 = getFileStream(filepath, isLocalProvider);
|
|
2289
|
+
for await (const file of stream2) {
|
|
2290
|
+
const isLocalProvider = file.provider === "local";
|
|
2291
|
+
const filepath = isLocalProvider ? join(strapi2.dirs.static.public, file.url) : file.url;
|
|
2292
|
+
const stats = await getFileStats(filepath, strapi2, isLocalProvider);
|
|
2293
|
+
const stream22 = getFileStream(filepath, strapi2, isLocalProvider);
|
|
2287
2294
|
yield {
|
|
2288
|
-
metadata:
|
|
2295
|
+
metadata: file,
|
|
2289
2296
|
filepath,
|
|
2290
|
-
filename:
|
|
2297
|
+
filename: file.hash + file.ext,
|
|
2291
2298
|
stream: stream22,
|
|
2292
2299
|
stats: { size: stats.size }
|
|
2293
2300
|
};
|
|
2294
|
-
if (
|
|
2295
|
-
for (const format of Object.keys(
|
|
2296
|
-
const fileFormat =
|
|
2301
|
+
if (file.formats) {
|
|
2302
|
+
for (const format of Object.keys(file.formats)) {
|
|
2303
|
+
const fileFormat = file.formats[format];
|
|
2297
2304
|
const fileFormatFilepath = isLocalProvider ? join(strapi2.dirs.static.public, fileFormat.url) : fileFormat.url;
|
|
2298
|
-
const fileFormatStats = await getFileStats(fileFormatFilepath, isLocalProvider);
|
|
2299
|
-
const fileFormatStream = getFileStream(fileFormatFilepath, isLocalProvider);
|
|
2300
|
-
const metadata = { ...fileFormat, type: format, id:
|
|
2305
|
+
const fileFormatStats = await getFileStats(fileFormatFilepath, strapi2, isLocalProvider);
|
|
2306
|
+
const fileFormatStream = getFileStream(fileFormatFilepath, strapi2, isLocalProvider);
|
|
2307
|
+
const metadata = { ...fileFormat, type: format, id: file.id, mainHash: file.hash };
|
|
2301
2308
|
yield {
|
|
2302
2309
|
metadata,
|
|
2303
2310
|
filepath: fileFormatFilepath,
|
|
@@ -2311,7 +2318,7 @@ const createAssetsStream = (strapi2) => {
|
|
|
2311
2318
|
};
|
|
2312
2319
|
return Duplex.from(generator());
|
|
2313
2320
|
};
|
|
2314
|
-
const createLocalStrapiSourceProvider
|
|
2321
|
+
const createLocalStrapiSourceProvider = (options) => {
|
|
2315
2322
|
return new LocalStrapiSourceProvider(options);
|
|
2316
2323
|
};
|
|
2317
2324
|
class LocalStrapiSourceProvider {
|
|
@@ -2439,8 +2446,8 @@ const createDispatcher = (ws, retryMessageOptions = {
|
|
|
2439
2446
|
const dispatchCommand = (payload) => {
|
|
2440
2447
|
return dispatch({ type: "command", ...payload });
|
|
2441
2448
|
};
|
|
2442
|
-
const dispatchTransferAction = async (
|
|
2443
|
-
const payload = { type: "transfer", kind: "action", action
|
|
2449
|
+
const dispatchTransferAction = async (action) => {
|
|
2450
|
+
const payload = { type: "transfer", kind: "action", action };
|
|
2444
2451
|
return dispatch(payload, { attachTransfer: true }) ?? Promise.resolve(null);
|
|
2445
2452
|
};
|
|
2446
2453
|
const dispatchTransferStep = async (payload) => {
|
|
@@ -2774,7 +2781,7 @@ class RemoteStrapiDestinationProvider {
|
|
|
2774
2781
|
});
|
|
2775
2782
|
}
|
|
2776
2783
|
}
|
|
2777
|
-
const createRemoteStrapiDestinationProvider
|
|
2784
|
+
const createRemoteStrapiDestinationProvider = (options) => {
|
|
2778
2785
|
return new RemoteStrapiDestinationProvider(options);
|
|
2779
2786
|
};
|
|
2780
2787
|
class RemoteStrapiSourceProvider {
|
|
@@ -2846,15 +2853,15 @@ class RemoteStrapiSourceProvider {
|
|
|
2846
2853
|
const pass = new PassThrough({ objectMode: true });
|
|
2847
2854
|
stream2.on("data", async (payload) => {
|
|
2848
2855
|
for (const item of payload) {
|
|
2849
|
-
const { action
|
|
2850
|
-
if (
|
|
2856
|
+
const { action } = item;
|
|
2857
|
+
if (action === "start") {
|
|
2851
2858
|
assets[item.assetID] = { ...item.data, stream: new PassThrough() };
|
|
2852
2859
|
await this.writeAsync(pass, assets[item.assetID]);
|
|
2853
|
-
} else if (
|
|
2860
|
+
} else if (action === "stream") {
|
|
2854
2861
|
const rawBuffer = item.data;
|
|
2855
2862
|
const chunk = Buffer.from(rawBuffer.data);
|
|
2856
2863
|
await this.writeAsync(assets[item.assetID].stream, chunk);
|
|
2857
|
-
} else if (
|
|
2864
|
+
} else if (action === "end") {
|
|
2858
2865
|
await new Promise((resolve, reject2) => {
|
|
2859
2866
|
const { stream: assetStream } = assets[item.assetID];
|
|
2860
2867
|
assetStream.on("close", () => {
|
|
@@ -2982,17 +2989,17 @@ class RemoteStrapiSourceProvider {
|
|
|
2982
2989
|
return null;
|
|
2983
2990
|
}
|
|
2984
2991
|
}
|
|
2985
|
-
const createRemoteStrapiSourceProvider
|
|
2992
|
+
const createRemoteStrapiSourceProvider = (options) => {
|
|
2986
2993
|
return new RemoteStrapiSourceProvider(options);
|
|
2987
2994
|
};
|
|
2988
|
-
const index$
|
|
2995
|
+
const index$5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2989
2996
|
__proto__: null,
|
|
2990
|
-
DEFAULT_CONFLICT_STRATEGY
|
|
2997
|
+
DEFAULT_CONFLICT_STRATEGY,
|
|
2991
2998
|
VALID_CONFLICT_STRATEGIES,
|
|
2992
|
-
createLocalStrapiDestinationProvider
|
|
2993
|
-
createLocalStrapiSourceProvider
|
|
2994
|
-
createRemoteStrapiDestinationProvider
|
|
2995
|
-
createRemoteStrapiSourceProvider
|
|
2999
|
+
createLocalStrapiDestinationProvider,
|
|
3000
|
+
createLocalStrapiSourceProvider,
|
|
3001
|
+
createRemoteStrapiDestinationProvider,
|
|
3002
|
+
createRemoteStrapiSourceProvider
|
|
2996
3003
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2997
3004
|
const DEFAULT_TRANSFER_FLOW = [
|
|
2998
3005
|
{
|
|
@@ -3199,9 +3206,9 @@ const handlerControllerFactory = (implementation) => (options) => {
|
|
|
3199
3206
|
throw new Error("Invalid Transfer Process");
|
|
3200
3207
|
}
|
|
3201
3208
|
},
|
|
3202
|
-
assertValidTransferCommand(
|
|
3203
|
-
const isDefined = typeof this[
|
|
3204
|
-
const isValidTransferCommand = VALID_TRANSFER_COMMANDS.includes(
|
|
3209
|
+
assertValidTransferCommand(command) {
|
|
3210
|
+
const isDefined = typeof this[command] === "function";
|
|
3211
|
+
const isValidTransferCommand = VALID_TRANSFER_COMMANDS.includes(command);
|
|
3205
3212
|
if (!isDefined || !isValidTransferCommand) {
|
|
3206
3213
|
throw new Error("Invalid transfer command");
|
|
3207
3214
|
}
|
|
@@ -3385,12 +3392,12 @@ const createPushController = handlerControllerFactory((proto) => ({
|
|
|
3385
3392
|
throw new Error("Invalid Transfer Process");
|
|
3386
3393
|
}
|
|
3387
3394
|
},
|
|
3388
|
-
assertValidTransferAction(
|
|
3389
|
-
if (VALID_TRANSFER_ACTIONS$1.includes(
|
|
3395
|
+
assertValidTransferAction(action) {
|
|
3396
|
+
if (VALID_TRANSFER_ACTIONS$1.includes(action)) {
|
|
3390
3397
|
return;
|
|
3391
3398
|
}
|
|
3392
|
-
throw new ProviderTransferError(`Invalid action provided: "${
|
|
3393
|
-
action
|
|
3399
|
+
throw new ProviderTransferError(`Invalid action provided: "${action}"`, {
|
|
3400
|
+
action,
|
|
3394
3401
|
validActions: Object.keys(VALID_TRANSFER_ACTIONS$1)
|
|
3395
3402
|
});
|
|
3396
3403
|
},
|
|
@@ -3441,13 +3448,13 @@ const createPushController = handlerControllerFactory((proto) => ({
|
|
|
3441
3448
|
const { uuid, type } = msg;
|
|
3442
3449
|
proto.addUUID(uuid);
|
|
3443
3450
|
if (type === "command") {
|
|
3444
|
-
const { command
|
|
3451
|
+
const { command } = msg;
|
|
3445
3452
|
await this.executeAndRespond(uuid, () => {
|
|
3446
|
-
this.assertValidTransferCommand(
|
|
3447
|
-
if (
|
|
3453
|
+
this.assertValidTransferCommand(command);
|
|
3454
|
+
if (command === "status") {
|
|
3448
3455
|
return this.status();
|
|
3449
3456
|
}
|
|
3450
|
-
return this[
|
|
3457
|
+
return this[command](msg.params);
|
|
3451
3458
|
});
|
|
3452
3459
|
} else if (type === "transfer") {
|
|
3453
3460
|
await this.executeAndRespond(uuid, async () => {
|
|
@@ -3532,19 +3539,19 @@ const createPushController = handlerControllerFactory((proto) => ({
|
|
|
3532
3539
|
}
|
|
3533
3540
|
},
|
|
3534
3541
|
async onTransferAction(msg) {
|
|
3535
|
-
const { action
|
|
3536
|
-
this.assertValidTransferAction(
|
|
3537
|
-
const step = { kind: "action", action
|
|
3542
|
+
const { action } = msg;
|
|
3543
|
+
this.assertValidTransferAction(action);
|
|
3544
|
+
const step = { kind: "action", action };
|
|
3538
3545
|
const isStepRegistered = this.flow?.has(step);
|
|
3539
3546
|
if (isStepRegistered) {
|
|
3540
3547
|
if (this.flow?.cannot(step)) {
|
|
3541
|
-
throw new ProviderTransferError(`Invalid action "${
|
|
3542
|
-
action
|
|
3548
|
+
throw new ProviderTransferError(`Invalid action "${action}" found for the current flow `, {
|
|
3549
|
+
action
|
|
3543
3550
|
});
|
|
3544
3551
|
}
|
|
3545
3552
|
this.flow?.set(step);
|
|
3546
3553
|
}
|
|
3547
|
-
return this.provider?.[
|
|
3554
|
+
return this.provider?.[action]();
|
|
3548
3555
|
},
|
|
3549
3556
|
async streamAsset(payload) {
|
|
3550
3557
|
const assetsStream = this.streams?.assets;
|
|
@@ -3553,20 +3560,20 @@ const createPushController = handlerControllerFactory((proto) => ({
|
|
|
3553
3560
|
return;
|
|
3554
3561
|
}
|
|
3555
3562
|
for (const item of payload) {
|
|
3556
|
-
const { action
|
|
3563
|
+
const { action, assetID } = item;
|
|
3557
3564
|
if (!assetsStream) {
|
|
3558
3565
|
throw new Error("Stream not defined");
|
|
3559
3566
|
}
|
|
3560
|
-
if (
|
|
3567
|
+
if (action === "start") {
|
|
3561
3568
|
this.assets[assetID] = { ...item.data, stream: new PassThrough() };
|
|
3562
3569
|
writeAsync(assetsStream, this.assets[assetID]);
|
|
3563
3570
|
}
|
|
3564
|
-
if (
|
|
3571
|
+
if (action === "stream") {
|
|
3565
3572
|
const rawBuffer = item.data;
|
|
3566
3573
|
const chunk = Buffer.from(rawBuffer.data);
|
|
3567
3574
|
await writeAsync(this.assets[assetID].stream, chunk);
|
|
3568
3575
|
}
|
|
3569
|
-
if (
|
|
3576
|
+
if (action === "end") {
|
|
3570
3577
|
await new Promise((resolve, reject2) => {
|
|
3571
3578
|
const { stream: assetStream } = this.assets[assetID];
|
|
3572
3579
|
assetStream.on("close", () => {
|
|
@@ -3595,7 +3602,7 @@ const createPushController = handlerControllerFactory((proto) => ({
|
|
|
3595
3602
|
this.assets = {};
|
|
3596
3603
|
this.streams = {};
|
|
3597
3604
|
this.flow = createFlow(DEFAULT_TRANSFER_FLOW);
|
|
3598
|
-
this.provider = createLocalStrapiDestinationProvider
|
|
3605
|
+
this.provider = createLocalStrapiDestinationProvider({
|
|
3599
3606
|
...params.options,
|
|
3600
3607
|
autoDestroy: false,
|
|
3601
3608
|
getStrapi: () => strapi
|
|
@@ -3641,13 +3648,13 @@ const createPullController = handlerControllerFactory((proto) => ({
|
|
|
3641
3648
|
this.streams = {};
|
|
3642
3649
|
delete this.provider;
|
|
3643
3650
|
},
|
|
3644
|
-
assertValidTransferAction(
|
|
3651
|
+
assertValidTransferAction(action) {
|
|
3645
3652
|
const validActions = VALID_TRANSFER_ACTIONS;
|
|
3646
|
-
if (validActions.includes(
|
|
3653
|
+
if (validActions.includes(action)) {
|
|
3647
3654
|
return;
|
|
3648
3655
|
}
|
|
3649
|
-
throw new ProviderTransferError(`Invalid action provided: "${
|
|
3650
|
-
action
|
|
3656
|
+
throw new ProviderTransferError(`Invalid action provided: "${action}"`, {
|
|
3657
|
+
action,
|
|
3651
3658
|
validActions: Object.keys(VALID_TRANSFER_ACTIONS)
|
|
3652
3659
|
});
|
|
3653
3660
|
},
|
|
@@ -3669,13 +3676,13 @@ const createPullController = handlerControllerFactory((proto) => ({
|
|
|
3669
3676
|
const { uuid, type } = msg;
|
|
3670
3677
|
proto.addUUID(uuid);
|
|
3671
3678
|
if (type === "command") {
|
|
3672
|
-
const { command
|
|
3679
|
+
const { command } = msg;
|
|
3673
3680
|
await this.executeAndRespond(uuid, () => {
|
|
3674
|
-
this.assertValidTransferCommand(
|
|
3675
|
-
if (
|
|
3681
|
+
this.assertValidTransferCommand(command);
|
|
3682
|
+
if (command === "status") {
|
|
3676
3683
|
return this.status();
|
|
3677
3684
|
}
|
|
3678
|
-
return this[
|
|
3685
|
+
return this[command](msg.params);
|
|
3679
3686
|
});
|
|
3680
3687
|
} else if (type === "transfer") {
|
|
3681
3688
|
await this.executeAndRespond(uuid, async () => {
|
|
@@ -3697,9 +3704,9 @@ const createPullController = handlerControllerFactory((proto) => ({
|
|
|
3697
3704
|
}
|
|
3698
3705
|
},
|
|
3699
3706
|
async onTransferAction(msg) {
|
|
3700
|
-
const { action
|
|
3701
|
-
this.assertValidTransferAction(
|
|
3702
|
-
return this.provider?.[
|
|
3707
|
+
const { action } = msg;
|
|
3708
|
+
this.assertValidTransferAction(action);
|
|
3709
|
+
return this.provider?.[action]();
|
|
3703
3710
|
},
|
|
3704
3711
|
async flush(stage, id) {
|
|
3705
3712
|
const batchSize = 1024 * 1024;
|
|
@@ -3746,8 +3753,8 @@ const createPullController = handlerControllerFactory((proto) => ({
|
|
|
3746
3753
|
}
|
|
3747
3754
|
},
|
|
3748
3755
|
async onTransferStep(msg) {
|
|
3749
|
-
const { step, action
|
|
3750
|
-
if (
|
|
3756
|
+
const { step, action } = msg;
|
|
3757
|
+
if (action === "start") {
|
|
3751
3758
|
if (this.streams?.[step] instanceof Readable) {
|
|
3752
3759
|
throw new Error("Stream already created, something went wrong");
|
|
3753
3760
|
}
|
|
@@ -3756,7 +3763,7 @@ const createPullController = handlerControllerFactory((proto) => ({
|
|
|
3756
3763
|
this.flush(step, flushUUID);
|
|
3757
3764
|
return { ok: true, id: flushUUID };
|
|
3758
3765
|
}
|
|
3759
|
-
if (
|
|
3766
|
+
if (action === "end") {
|
|
3760
3767
|
const stream2 = this.streams?.[step];
|
|
3761
3768
|
if (stream2?.readableEnded === false) {
|
|
3762
3769
|
await new Promise((resolve) => {
|
|
@@ -3828,7 +3835,7 @@ const createPullController = handlerControllerFactory((proto) => ({
|
|
|
3828
3835
|
this.transferID = randomUUID();
|
|
3829
3836
|
this.startedAt = Date.now();
|
|
3830
3837
|
this.streams = {};
|
|
3831
|
-
this.provider = createLocalStrapiSourceProvider
|
|
3838
|
+
this.provider = createLocalStrapiSourceProvider({
|
|
3832
3839
|
autoDestroy: false,
|
|
3833
3840
|
getStrapi: () => strapi
|
|
3834
3841
|
});
|
|
@@ -3856,22 +3863,22 @@ const createPullController = handlerControllerFactory((proto) => ({
|
|
|
3856
3863
|
return { active: false, kind: null, elapsed: null, startedAt: null };
|
|
3857
3864
|
}
|
|
3858
3865
|
}));
|
|
3859
|
-
const index$
|
|
3866
|
+
const index$4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
3860
3867
|
__proto__: null,
|
|
3861
3868
|
createPullController,
|
|
3862
3869
|
createPushController,
|
|
3863
3870
|
handlerControllerFactory
|
|
3864
3871
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
3865
|
-
const index$
|
|
3872
|
+
const index$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
3866
3873
|
__proto__: null,
|
|
3867
3874
|
constants,
|
|
3868
|
-
handlers: index$
|
|
3875
|
+
handlers: index$4
|
|
3869
3876
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
3870
|
-
const
|
|
3877
|
+
const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
3871
3878
|
__proto__: null,
|
|
3872
|
-
providers: index$
|
|
3873
|
-
queries: index$
|
|
3874
|
-
remote: index$
|
|
3879
|
+
providers: index$5,
|
|
3880
|
+
queries: index$6,
|
|
3881
|
+
remote: index$3
|
|
3875
3882
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
3876
3883
|
const isFilePathInDirname = (posixDirName, filePath) => {
|
|
3877
3884
|
const normalizedDir = path.posix.dirname(unknownPathToPosix(filePath));
|
|
@@ -3889,7 +3896,7 @@ const unknownPathToPosix = (filePath) => {
|
|
|
3889
3896
|
return path.normalize(filePath).split(path.win32.sep).join(path.posix.sep);
|
|
3890
3897
|
};
|
|
3891
3898
|
const METADATA_FILE_PATH = "metadata.json";
|
|
3892
|
-
const createLocalFileSourceProvider
|
|
3899
|
+
const createLocalFileSourceProvider = (options) => {
|
|
3893
3900
|
return new LocalFileSourceProvider(options);
|
|
3894
3901
|
};
|
|
3895
3902
|
class LocalFileSourceProvider {
|
|
@@ -3974,18 +3981,18 @@ class LocalFileSourceProvider {
|
|
|
3974
3981
|
async onentry(entry) {
|
|
3975
3982
|
const { path: filePath, size: size2 = 0 } = entry;
|
|
3976
3983
|
const normalizedPath = unknownPathToPosix(filePath);
|
|
3977
|
-
const
|
|
3984
|
+
const file = path.basename(normalizedPath);
|
|
3978
3985
|
let metadata;
|
|
3979
3986
|
try {
|
|
3980
|
-
metadata = await loadAssetMetadata(`assets/metadata/${
|
|
3987
|
+
metadata = await loadAssetMetadata(`assets/metadata/${file}.json`);
|
|
3981
3988
|
} catch (error) {
|
|
3982
3989
|
console.warn(
|
|
3983
|
-
` Failed to read metadata for ${
|
|
3990
|
+
` Failed to read metadata for ${file}, Strapi will try to fix this issue automatically`
|
|
3984
3991
|
);
|
|
3985
3992
|
}
|
|
3986
3993
|
const asset = {
|
|
3987
3994
|
metadata,
|
|
3988
|
-
filename:
|
|
3995
|
+
filename: file,
|
|
3989
3996
|
filepath: normalizedPath,
|
|
3990
3997
|
stats: { size: size2 },
|
|
3991
3998
|
stream: entry
|
|
@@ -3999,10 +4006,10 @@ class LocalFileSourceProvider {
|
|
|
3999
4006
|
return outStream;
|
|
4000
4007
|
}
|
|
4001
4008
|
#getBackupStream() {
|
|
4002
|
-
const { file
|
|
4009
|
+
const { file, encryption, compression } = this.options;
|
|
4003
4010
|
const streams = [];
|
|
4004
4011
|
try {
|
|
4005
|
-
streams.push(fse__default.createReadStream(
|
|
4012
|
+
streams.push(fse__default.createReadStream(file.path));
|
|
4006
4013
|
} catch (e) {
|
|
4007
4014
|
throw new Error(`Could not read backup file path provided at "${this.options.file.path}"`);
|
|
4008
4015
|
}
|
|
@@ -4150,7 +4157,7 @@ const createTarEntryStream = (archive, pathFactory, maxSize = 256e6) => {
|
|
|
4150
4157
|
}
|
|
4151
4158
|
});
|
|
4152
4159
|
};
|
|
4153
|
-
const createLocalFileDestinationProvider
|
|
4160
|
+
const createLocalFileDestinationProvider = (options) => {
|
|
4154
4161
|
return new LocalFileDestinationProvider(options);
|
|
4155
4162
|
};
|
|
4156
4163
|
class LocalFileDestinationProvider {
|
|
@@ -4164,8 +4171,8 @@ class LocalFileDestinationProvider {
|
|
|
4164
4171
|
this.options = options;
|
|
4165
4172
|
}
|
|
4166
4173
|
get #archivePath() {
|
|
4167
|
-
const { encryption, compression, file
|
|
4168
|
-
let filePath = `${
|
|
4174
|
+
const { encryption, compression, file } = this.options;
|
|
4175
|
+
let filePath = `${file.path}.tar`;
|
|
4169
4176
|
if (compression.enabled) {
|
|
4170
4177
|
filePath += ".gz";
|
|
4171
4178
|
}
|
|
@@ -4329,953 +4336,17 @@ class LocalFileDestinationProvider {
|
|
|
4329
4336
|
}
|
|
4330
4337
|
const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4331
4338
|
__proto__: null,
|
|
4332
|
-
createLocalFileDestinationProvider
|
|
4333
|
-
createLocalFileSourceProvider
|
|
4334
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
4335
|
-
const file = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4336
|
-
__proto__: null,
|
|
4337
|
-
providers: index$1
|
|
4339
|
+
createLocalFileDestinationProvider,
|
|
4340
|
+
createLocalFileSourceProvider
|
|
4338
4341
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
4339
|
-
const bytesPerKb = 1024;
|
|
4340
|
-
const sizes = ["B ", "KB", "MB", "GB", "TB", "PB"];
|
|
4341
|
-
const readableBytes = (bytes, decimals = 1, padStart = 0) => {
|
|
4342
|
-
if (!bytes) {
|
|
4343
|
-
return "0";
|
|
4344
|
-
}
|
|
4345
|
-
const i = Math.floor(Math.log(bytes) / Math.log(bytesPerKb));
|
|
4346
|
-
const result = `${parseFloat((bytes / bytesPerKb ** i).toFixed(decimals))} ${sizes[i].padStart(
|
|
4347
|
-
2
|
|
4348
|
-
)}`;
|
|
4349
|
-
return result.padStart(padStart);
|
|
4350
|
-
};
|
|
4351
|
-
const exitWith = (code, message, options = {}) => {
|
|
4352
|
-
const { logger = console, prc = process } = options;
|
|
4353
|
-
const log = (message2) => {
|
|
4354
|
-
if (code === 0) {
|
|
4355
|
-
logger.log(chalk.green(message2));
|
|
4356
|
-
} else {
|
|
4357
|
-
logger.error(chalk.red(message2));
|
|
4358
|
-
}
|
|
4359
|
-
};
|
|
4360
|
-
if (isString(message)) {
|
|
4361
|
-
log(message);
|
|
4362
|
-
} else if (isArray(message)) {
|
|
4363
|
-
message.forEach((msg) => log(msg));
|
|
4364
|
-
}
|
|
4365
|
-
prc.exit(code);
|
|
4366
|
-
};
|
|
4367
|
-
const assertUrlHasProtocol = (url, protocol) => {
|
|
4368
|
-
if (!url.protocol) {
|
|
4369
|
-
exitWith(1, `${url.toString()} does not have a protocol`);
|
|
4370
|
-
}
|
|
4371
|
-
if (!protocol) {
|
|
4372
|
-
return;
|
|
4373
|
-
}
|
|
4374
|
-
if (isString(protocol)) {
|
|
4375
|
-
if (protocol !== url.protocol) {
|
|
4376
|
-
exitWith(1, `${url.toString()} must have the protocol ${protocol}`);
|
|
4377
|
-
}
|
|
4378
|
-
return;
|
|
4379
|
-
}
|
|
4380
|
-
if (!protocol.some((protocol2) => url.protocol === protocol2)) {
|
|
4381
|
-
return exitWith(
|
|
4382
|
-
1,
|
|
4383
|
-
`${url.toString()} must have one of the following protocols: ${protocol.join(",")}`
|
|
4384
|
-
);
|
|
4385
|
-
}
|
|
4386
|
-
};
|
|
4387
|
-
const ifOptions = (conditionCallback, isMetCallback = async () => {
|
|
4388
|
-
}, isNotMetCallback = async () => {
|
|
4389
|
-
}) => {
|
|
4390
|
-
return async (command2) => {
|
|
4391
|
-
const opts = command2.opts();
|
|
4392
|
-
if (await conditionCallback(opts)) {
|
|
4393
|
-
await isMetCallback(command2);
|
|
4394
|
-
} else {
|
|
4395
|
-
await isNotMetCallback(command2);
|
|
4396
|
-
}
|
|
4397
|
-
};
|
|
4398
|
-
};
|
|
4399
|
-
const parseList = (value) => {
|
|
4400
|
-
try {
|
|
4401
|
-
return value.split(",").map((item) => item.trim());
|
|
4402
|
-
} catch (e) {
|
|
4403
|
-
exitWith(1, `Unrecognized input: ${value}`);
|
|
4404
|
-
}
|
|
4405
|
-
return [];
|
|
4406
|
-
};
|
|
4407
|
-
const getParseListWithChoices = (choices, errorMessage = "Invalid options:") => {
|
|
4408
|
-
return (value) => {
|
|
4409
|
-
const list = parseList(value);
|
|
4410
|
-
const invalid = list.filter((item) => {
|
|
4411
|
-
return !choices.includes(item);
|
|
4412
|
-
});
|
|
4413
|
-
if (invalid.length > 0) {
|
|
4414
|
-
exitWith(1, `${errorMessage}: ${invalid.join(",")}`);
|
|
4415
|
-
}
|
|
4416
|
-
return list;
|
|
4417
|
-
};
|
|
4418
|
-
};
|
|
4419
|
-
const parseInteger = (value) => {
|
|
4420
|
-
const parsedValue = parseInt(value, 10);
|
|
4421
|
-
if (isNaN(parsedValue)) {
|
|
4422
|
-
throw new InvalidOptionArgumentError(`Not an integer: ${value}`);
|
|
4423
|
-
}
|
|
4424
|
-
return parsedValue;
|
|
4425
|
-
};
|
|
4426
|
-
const parseURL = (value) => {
|
|
4427
|
-
try {
|
|
4428
|
-
const url = new URL(value);
|
|
4429
|
-
if (!url.host) {
|
|
4430
|
-
throw new InvalidOptionArgumentError(`Could not parse url ${value}`);
|
|
4431
|
-
}
|
|
4432
|
-
return url;
|
|
4433
|
-
} catch (e) {
|
|
4434
|
-
throw new InvalidOptionArgumentError(`Could not parse url ${value}`);
|
|
4435
|
-
}
|
|
4436
|
-
};
|
|
4437
|
-
const promptEncryptionKey = async (thisCommand) => {
|
|
4438
|
-
const opts = thisCommand.opts();
|
|
4439
|
-
if (!opts.encrypt && opts.key) {
|
|
4440
|
-
return exitWith(1, "Key may not be present unless encryption is used");
|
|
4441
|
-
}
|
|
4442
|
-
if (opts.encrypt && !(opts.key && opts.key.length > 0)) {
|
|
4443
|
-
try {
|
|
4444
|
-
const answers = await inquirer.prompt([
|
|
4445
|
-
{
|
|
4446
|
-
type: "password",
|
|
4447
|
-
message: "Please enter an encryption key",
|
|
4448
|
-
name: "key",
|
|
4449
|
-
validate(key) {
|
|
4450
|
-
if (key.length > 0)
|
|
4451
|
-
return true;
|
|
4452
|
-
return "Key must be present when using the encrypt option";
|
|
4453
|
-
}
|
|
4454
|
-
}
|
|
4455
|
-
]);
|
|
4456
|
-
opts.key = answers.key;
|
|
4457
|
-
} catch (e) {
|
|
4458
|
-
return exitWith(1, "Failed to get encryption key");
|
|
4459
|
-
}
|
|
4460
|
-
if (!opts.key) {
|
|
4461
|
-
return exitWith(1, "Failed to get encryption key");
|
|
4462
|
-
}
|
|
4463
|
-
}
|
|
4464
|
-
};
|
|
4465
|
-
const getCommanderConfirmMessage = (message, { failMessage } = {}) => {
|
|
4466
|
-
return async (command2) => {
|
|
4467
|
-
const confirmed = await confirmMessage(message, { force: command2.opts().force });
|
|
4468
|
-
if (!confirmed) {
|
|
4469
|
-
exitWith(1, failMessage);
|
|
4470
|
-
}
|
|
4471
|
-
};
|
|
4472
|
-
};
|
|
4473
|
-
const confirmMessage = async (message, { force } = {}) => {
|
|
4474
|
-
if (force === true) {
|
|
4475
|
-
console.log(`${chalk.green("?")} ${chalk.bold(message)} ${chalk.cyan("Yes")}`);
|
|
4476
|
-
return true;
|
|
4477
|
-
}
|
|
4478
|
-
const answers = await inquirer.prompt([
|
|
4479
|
-
{
|
|
4480
|
-
type: "confirm",
|
|
4481
|
-
message,
|
|
4482
|
-
name: `confirm`,
|
|
4483
|
-
default: false
|
|
4484
|
-
}
|
|
4485
|
-
]);
|
|
4486
|
-
return answers.confirm;
|
|
4487
|
-
};
|
|
4488
|
-
const forceOption = new Option(
|
|
4489
|
-
"--force",
|
|
4490
|
-
`Automatically answer "yes" to all prompts, including potentially destructive requests, and run non-interactively.`
|
|
4491
|
-
);
|
|
4492
|
-
const {
|
|
4493
|
-
errors: { TransferEngineInitializationError: TransferEngineInitializationError2 }
|
|
4494
|
-
} = engineDatatransfer;
|
|
4495
|
-
const exitMessageText = (process2, error = false) => {
|
|
4496
|
-
const processCapitalized = process2[0].toUpperCase() + process2.slice(1);
|
|
4497
|
-
if (!error) {
|
|
4498
|
-
return chalk.bold(
|
|
4499
|
-
chalk.green(`${processCapitalized} process has been completed successfully!`)
|
|
4500
|
-
);
|
|
4501
|
-
}
|
|
4502
|
-
return chalk.bold(chalk.red(`${processCapitalized} process failed.`));
|
|
4503
|
-
};
|
|
4504
|
-
const pad = (n) => {
|
|
4505
|
-
return (n < 10 ? "0" : "") + String(n);
|
|
4506
|
-
};
|
|
4507
|
-
const yyyymmddHHMMSS = () => {
|
|
4508
|
-
const date = /* @__PURE__ */ new Date();
|
|
4509
|
-
return date.getFullYear() + pad(date.getMonth() + 1) + pad(date.getDate()) + pad(date.getHours()) + pad(date.getMinutes()) + pad(date.getSeconds());
|
|
4510
|
-
};
|
|
4511
|
-
const getDefaultExportName = () => {
|
|
4512
|
-
return `export_${yyyymmddHHMMSS()}`;
|
|
4513
|
-
};
|
|
4514
|
-
const buildTransferTable = (resultData) => {
|
|
4515
|
-
if (!resultData) {
|
|
4516
|
-
return;
|
|
4517
|
-
}
|
|
4518
|
-
const table = new Table({
|
|
4519
|
-
head: ["Type", "Count", "Size"].map((text) => chalk.bold.blue(text))
|
|
4520
|
-
});
|
|
4521
|
-
let totalBytes = 0;
|
|
4522
|
-
let totalItems = 0;
|
|
4523
|
-
Object.keys(resultData).forEach((stage) => {
|
|
4524
|
-
const item = resultData[stage];
|
|
4525
|
-
if (!item) {
|
|
4526
|
-
return;
|
|
4527
|
-
}
|
|
4528
|
-
table.push([
|
|
4529
|
-
{ hAlign: "left", content: chalk.bold(stage) },
|
|
4530
|
-
{ hAlign: "right", content: item.count },
|
|
4531
|
-
{ hAlign: "right", content: `${readableBytes(item.bytes, 1, 11)} ` }
|
|
4532
|
-
]);
|
|
4533
|
-
totalBytes += item.bytes;
|
|
4534
|
-
totalItems += item.count;
|
|
4535
|
-
if (item.aggregates) {
|
|
4536
|
-
Object.keys(item.aggregates).sort().forEach((subkey) => {
|
|
4537
|
-
if (!item.aggregates) {
|
|
4538
|
-
return;
|
|
4539
|
-
}
|
|
4540
|
-
const subitem = item.aggregates[subkey];
|
|
4541
|
-
table.push([
|
|
4542
|
-
{ hAlign: "left", content: `-- ${chalk.bold.grey(subkey)}` },
|
|
4543
|
-
{ hAlign: "right", content: chalk.grey(subitem.count) },
|
|
4544
|
-
{ hAlign: "right", content: chalk.grey(`(${readableBytes(subitem.bytes, 1, 11)})`) }
|
|
4545
|
-
]);
|
|
4546
|
-
});
|
|
4547
|
-
}
|
|
4548
|
-
});
|
|
4549
|
-
table.push([
|
|
4550
|
-
{ hAlign: "left", content: chalk.bold.green("Total") },
|
|
4551
|
-
{ hAlign: "right", content: chalk.bold.green(totalItems) },
|
|
4552
|
-
{ hAlign: "right", content: `${chalk.bold.green(readableBytes(totalBytes, 1, 11))} ` }
|
|
4553
|
-
]);
|
|
4554
|
-
return table;
|
|
4555
|
-
};
|
|
4556
|
-
const DEFAULT_IGNORED_CONTENT_TYPES = [
|
|
4557
|
-
"admin::permission",
|
|
4558
|
-
"admin::user",
|
|
4559
|
-
"admin::role",
|
|
4560
|
-
"admin::api-token",
|
|
4561
|
-
"admin::api-token-permission",
|
|
4562
|
-
"admin::transfer-token",
|
|
4563
|
-
"admin::transfer-token-permission",
|
|
4564
|
-
"admin::audit-log",
|
|
4565
|
-
"plugin::content-releases.release",
|
|
4566
|
-
"plugin::content-releases.release-action"
|
|
4567
|
-
];
|
|
4568
|
-
const abortTransfer = async ({
|
|
4569
|
-
engine,
|
|
4570
|
-
strapi: strapi2
|
|
4571
|
-
}) => {
|
|
4572
|
-
try {
|
|
4573
|
-
await engine.abortTransfer();
|
|
4574
|
-
await strapi2.destroy();
|
|
4575
|
-
} catch (e) {
|
|
4576
|
-
return false;
|
|
4577
|
-
}
|
|
4578
|
-
return true;
|
|
4579
|
-
};
|
|
4580
|
-
const setSignalHandler = async (handler, signals = ["SIGINT", "SIGTERM", "SIGQUIT"]) => {
|
|
4581
|
-
signals.forEach((signal) => {
|
|
4582
|
-
process.removeAllListeners(signal);
|
|
4583
|
-
process.on(signal, handler);
|
|
4584
|
-
});
|
|
4585
|
-
};
|
|
4586
|
-
const createStrapiInstance = async (opts = {}) => {
|
|
4587
|
-
try {
|
|
4588
|
-
const appContext = await strapiFactory.compile();
|
|
4589
|
-
const app = strapiFactory({ ...opts, ...appContext });
|
|
4590
|
-
app.log.level = opts.logLevel || "error";
|
|
4591
|
-
return await app.load();
|
|
4592
|
-
} catch (error) {
|
|
4593
|
-
if (error instanceof Error && "code" in error && error.code === "ECONNREFUSED") {
|
|
4594
|
-
throw new Error("Process failed. Check the database connection with your Strapi project.");
|
|
4595
|
-
}
|
|
4596
|
-
throw error;
|
|
4597
|
-
}
|
|
4598
|
-
};
|
|
4599
|
-
const transferDataTypes = Object.keys(TransferGroupPresets);
|
|
4600
|
-
const throttleOption = new Option(
|
|
4601
|
-
"--throttle <delay after each entity>",
|
|
4602
|
-
`Add a delay in milliseconds between each transferred entity`
|
|
4603
|
-
).argParser(parseInteger).hideHelp();
|
|
4604
|
-
const excludeOption = new Option(
|
|
4605
|
-
"--exclude <comma-separated data types>",
|
|
4606
|
-
`Exclude data using comma-separated types. Available types: ${transferDataTypes.join(",")}`
|
|
4607
|
-
).argParser(getParseListWithChoices(transferDataTypes, 'Invalid options for "exclude"'));
|
|
4608
|
-
const onlyOption = new Option(
|
|
4609
|
-
"--only <command-separated data types>",
|
|
4610
|
-
`Include only these types of data (plus schemas). Available types: ${transferDataTypes.join(",")}`
|
|
4611
|
-
).argParser(getParseListWithChoices(transferDataTypes, 'Invalid options for "only"'));
|
|
4612
|
-
const validateExcludeOnly = (command2) => {
|
|
4613
|
-
const { exclude, only } = command2.opts();
|
|
4614
|
-
if (!only || !exclude) {
|
|
4615
|
-
return;
|
|
4616
|
-
}
|
|
4617
|
-
const choicesInBoth = only.filter((n) => {
|
|
4618
|
-
return exclude.indexOf(n) !== -1;
|
|
4619
|
-
});
|
|
4620
|
-
if (choicesInBoth.length > 0) {
|
|
4621
|
-
exitWith(
|
|
4622
|
-
1,
|
|
4623
|
-
`Data types may not be used in both "exclude" and "only" in the same command. Found in both: ${choicesInBoth.join(
|
|
4624
|
-
","
|
|
4625
|
-
)}`
|
|
4626
|
-
);
|
|
4627
|
-
}
|
|
4628
|
-
};
|
|
4629
|
-
const errorColors = {
|
|
4630
|
-
fatal: chalk.red,
|
|
4631
|
-
error: chalk.red,
|
|
4632
|
-
silly: chalk.yellow
|
|
4633
|
-
};
|
|
4634
|
-
const formatDiagnostic = (operation) => ({ details, kind }) => {
|
|
4635
|
-
const logger = createLogger(
|
|
4636
|
-
configs.createOutputFileConfiguration(`${operation}_error_log_${Date.now()}.log`)
|
|
4637
|
-
);
|
|
4638
|
-
try {
|
|
4639
|
-
if (kind === "error") {
|
|
4640
|
-
const { message, severity = "fatal" } = details;
|
|
4641
|
-
const colorizeError = errorColors[severity];
|
|
4642
|
-
const errorMessage = colorizeError(`[${severity.toUpperCase()}] ${message}`);
|
|
4643
|
-
logger.error(errorMessage);
|
|
4644
|
-
}
|
|
4645
|
-
if (kind === "info") {
|
|
4646
|
-
const { message, params } = details;
|
|
4647
|
-
const msg = `${message}
|
|
4648
|
-
${params ? JSON.stringify(params, null, 2) : ""}`;
|
|
4649
|
-
logger.info(msg);
|
|
4650
|
-
}
|
|
4651
|
-
if (kind === "warning") {
|
|
4652
|
-
const { origin: origin2, message } = details;
|
|
4653
|
-
logger.warn(`(${origin2 ?? "transfer"}) ${message}`);
|
|
4654
|
-
}
|
|
4655
|
-
} catch (err) {
|
|
4656
|
-
logger.error(err);
|
|
4657
|
-
}
|
|
4658
|
-
};
|
|
4659
|
-
const loadersFactory = (defaultLoaders = {}) => {
|
|
4660
|
-
const loaders = defaultLoaders;
|
|
4661
|
-
const updateLoader = (stage, data) => {
|
|
4662
|
-
if (!(stage in loaders)) {
|
|
4663
|
-
createLoader(stage);
|
|
4664
|
-
}
|
|
4665
|
-
const stageData = data[stage];
|
|
4666
|
-
const elapsedTime = stageData?.startTime ? (stageData?.endTime || Date.now()) - stageData.startTime : 0;
|
|
4667
|
-
const size2 = `size: ${readableBytes(stageData?.bytes ?? 0)}`;
|
|
4668
|
-
const elapsed = `elapsed: ${elapsedTime} ms`;
|
|
4669
|
-
const speed = elapsedTime > 0 ? `(${readableBytes((stageData?.bytes ?? 0) * 1e3 / elapsedTime)}/s)` : "";
|
|
4670
|
-
loaders[stage].text = `${stage}: ${stageData?.count ?? 0} transfered (${size2}) (${elapsed}) ${!stageData?.endTime ? speed : ""}`;
|
|
4671
|
-
return loaders[stage];
|
|
4672
|
-
};
|
|
4673
|
-
const createLoader = (stage) => {
|
|
4674
|
-
Object.assign(loaders, { [stage]: ora() });
|
|
4675
|
-
return loaders[stage];
|
|
4676
|
-
};
|
|
4677
|
-
const getLoader = (stage) => {
|
|
4678
|
-
return loaders[stage];
|
|
4679
|
-
};
|
|
4680
|
-
return {
|
|
4681
|
-
updateLoader,
|
|
4682
|
-
createLoader,
|
|
4683
|
-
getLoader
|
|
4684
|
-
};
|
|
4685
|
-
};
|
|
4686
|
-
const getTransferTelemetryPayload = (engine) => {
|
|
4687
|
-
return {
|
|
4688
|
-
eventProperties: {
|
|
4689
|
-
source: engine?.sourceProvider?.name,
|
|
4690
|
-
destination: engine?.destinationProvider?.name
|
|
4691
|
-
}
|
|
4692
|
-
};
|
|
4693
|
-
};
|
|
4694
|
-
const getDiffHandler = (engine, {
|
|
4695
|
-
force,
|
|
4696
|
-
action: action2
|
|
4697
|
-
}) => {
|
|
4698
|
-
return async (context, next) => {
|
|
4699
|
-
setSignalHandler(async () => {
|
|
4700
|
-
await abortTransfer({ engine, strapi });
|
|
4701
|
-
exitWith(1, exitMessageText(action2, true));
|
|
4702
|
-
});
|
|
4703
|
-
let workflowsStatus;
|
|
4704
|
-
const source = "Schema Integrity";
|
|
4705
|
-
Object.entries(context.diffs).forEach(([uid, diffs]) => {
|
|
4706
|
-
for (const diff2 of diffs) {
|
|
4707
|
-
const path2 = [uid].concat(diff2.path).join(".");
|
|
4708
|
-
const endPath = diff2.path[diff2.path.length - 1];
|
|
4709
|
-
if (uid === "admin::workflow" || uid === "admin::workflow-stage" || endPath?.startsWith("strapi_stage") || endPath?.startsWith("strapi_assignee")) {
|
|
4710
|
-
workflowsStatus = diff2.kind;
|
|
4711
|
-
} else if (diff2.kind === "added") {
|
|
4712
|
-
engine.reportWarning(chalk.red(`${chalk.bold(path2)} does not exist on source`), source);
|
|
4713
|
-
} else if (diff2.kind === "deleted") {
|
|
4714
|
-
engine.reportWarning(
|
|
4715
|
-
chalk.red(`${chalk.bold(path2)} does not exist on destination`),
|
|
4716
|
-
source
|
|
4717
|
-
);
|
|
4718
|
-
} else if (diff2.kind === "modified") {
|
|
4719
|
-
engine.reportWarning(chalk.red(`${chalk.bold(path2)} has a different data type`), source);
|
|
4720
|
-
}
|
|
4721
|
-
}
|
|
4722
|
-
});
|
|
4723
|
-
if (workflowsStatus === "added") {
|
|
4724
|
-
engine.reportWarning(chalk.red(`Review workflows feature does not exist on source`), source);
|
|
4725
|
-
} else if (workflowsStatus === "deleted") {
|
|
4726
|
-
engine.reportWarning(
|
|
4727
|
-
chalk.red(`Review workflows feature does not exist on destination`),
|
|
4728
|
-
source
|
|
4729
|
-
);
|
|
4730
|
-
} else if (workflowsStatus === "modified") {
|
|
4731
|
-
engine.panic(
|
|
4732
|
-
new TransferEngineInitializationError2("Unresolved differences in schema [review workflows]")
|
|
4733
|
-
);
|
|
4734
|
-
}
|
|
4735
|
-
const confirmed = await confirmMessage(
|
|
4736
|
-
"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?",
|
|
4737
|
-
{
|
|
4738
|
-
force
|
|
4739
|
-
}
|
|
4740
|
-
);
|
|
4741
|
-
setSignalHandler(() => abortTransfer({ engine, strapi }));
|
|
4742
|
-
if (confirmed) {
|
|
4743
|
-
context.ignoredDiffs = merge(context.diffs, context.ignoredDiffs);
|
|
4744
|
-
}
|
|
4745
|
-
return next(context);
|
|
4746
|
-
};
|
|
4747
|
-
};
|
|
4748
|
-
const getAssetsBackupHandler = (engine, {
|
|
4749
|
-
force,
|
|
4750
|
-
action: action2
|
|
4751
|
-
}) => {
|
|
4752
|
-
return async (context, next) => {
|
|
4753
|
-
setSignalHandler(async () => {
|
|
4754
|
-
await abortTransfer({ engine, strapi });
|
|
4755
|
-
exitWith(1, exitMessageText(action2, true));
|
|
4756
|
-
});
|
|
4757
|
-
console.warn(
|
|
4758
|
-
"The backup for the assets could not be created inside the public directory. Ensure Strapi has write permissions on the public directory."
|
|
4759
|
-
);
|
|
4760
|
-
const confirmed = await confirmMessage(
|
|
4761
|
-
"Do you want to continue without backing up your public/uploads files?",
|
|
4762
|
-
{
|
|
4763
|
-
force
|
|
4764
|
-
}
|
|
4765
|
-
);
|
|
4766
|
-
if (confirmed) {
|
|
4767
|
-
context.ignore = true;
|
|
4768
|
-
}
|
|
4769
|
-
setSignalHandler(() => abortTransfer({ engine, strapi }));
|
|
4770
|
-
return next(context);
|
|
4771
|
-
};
|
|
4772
|
-
};
|
|
4773
|
-
const shouldSkipStage = (opts, dataKind) => {
|
|
4774
|
-
if (opts.exclude?.includes(dataKind)) {
|
|
4775
|
-
return true;
|
|
4776
|
-
}
|
|
4777
|
-
if (opts.only) {
|
|
4778
|
-
return !opts.only.includes(dataKind);
|
|
4779
|
-
}
|
|
4780
|
-
return false;
|
|
4781
|
-
};
|
|
4782
|
-
const parseRestoreFromOptions = (opts) => {
|
|
4783
|
-
const entitiesOptions = {
|
|
4784
|
-
exclude: DEFAULT_IGNORED_CONTENT_TYPES,
|
|
4785
|
-
include: void 0
|
|
4786
|
-
};
|
|
4787
|
-
if (opts.only && !opts.only.includes("content") || opts.exclude?.includes("content")) {
|
|
4788
|
-
entitiesOptions.include = [];
|
|
4789
|
-
}
|
|
4790
|
-
const restoreConfig = {
|
|
4791
|
-
entities: entitiesOptions,
|
|
4792
|
-
assets: !shouldSkipStage(opts, "files"),
|
|
4793
|
-
configuration: {
|
|
4794
|
-
webhook: !shouldSkipStage(opts, "config"),
|
|
4795
|
-
coreStore: !shouldSkipStage(opts, "config")
|
|
4796
|
-
}
|
|
4797
|
-
};
|
|
4798
|
-
return restoreConfig;
|
|
4799
|
-
};
|
|
4800
|
-
const {
|
|
4801
|
-
providers: { createLocalFileDestinationProvider }
|
|
4802
|
-
} = file;
|
|
4803
|
-
const {
|
|
4804
|
-
providers: { createLocalStrapiSourceProvider: createLocalStrapiSourceProvider$1 }
|
|
4805
|
-
} = strapiDatatransfer;
|
|
4806
|
-
const BYTES_IN_MB = 1024 * 1024;
|
|
4807
|
-
const action$2 = async (opts) => {
|
|
4808
|
-
if (!isObject(opts)) {
|
|
4809
|
-
exitWith(1, "Could not parse command arguments");
|
|
4810
|
-
}
|
|
4811
|
-
const strapi2 = await createStrapiInstance();
|
|
4812
|
-
const source = createSourceProvider(strapi2);
|
|
4813
|
-
const destination = createDestinationProvider(opts);
|
|
4814
|
-
const engine = createTransferEngine$2(source, destination, {
|
|
4815
|
-
versionStrategy: "ignore",
|
|
4816
|
-
// for an export to file, versionStrategy will always be skipped
|
|
4817
|
-
schemaStrategy: "ignore",
|
|
4818
|
-
// for an export to file, schemaStrategy will always be skipped
|
|
4819
|
-
exclude: opts.exclude,
|
|
4820
|
-
only: opts.only,
|
|
4821
|
-
throttle: opts.throttle,
|
|
4822
|
-
transforms: {
|
|
4823
|
-
links: [
|
|
4824
|
-
{
|
|
4825
|
-
filter(link2) {
|
|
4826
|
-
return !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.left.type) && !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.right.type);
|
|
4827
|
-
}
|
|
4828
|
-
}
|
|
4829
|
-
],
|
|
4830
|
-
entities: [
|
|
4831
|
-
{
|
|
4832
|
-
filter(entity2) {
|
|
4833
|
-
return !DEFAULT_IGNORED_CONTENT_TYPES.includes(entity2.type);
|
|
4834
|
-
}
|
|
4835
|
-
}
|
|
4836
|
-
]
|
|
4837
|
-
}
|
|
4838
|
-
});
|
|
4839
|
-
engine.diagnostics.onDiagnostic(formatDiagnostic("export"));
|
|
4840
|
-
const progress = engine.progress.stream;
|
|
4841
|
-
const { updateLoader } = loadersFactory();
|
|
4842
|
-
progress.on(`stage::start`, ({ stage, data }) => {
|
|
4843
|
-
updateLoader(stage, data).start();
|
|
4844
|
-
});
|
|
4845
|
-
progress.on("stage::finish", ({ stage, data }) => {
|
|
4846
|
-
updateLoader(stage, data).succeed();
|
|
4847
|
-
});
|
|
4848
|
-
progress.on("stage::progress", ({ stage, data }) => {
|
|
4849
|
-
updateLoader(stage, data);
|
|
4850
|
-
});
|
|
4851
|
-
progress.on("transfer::start", async () => {
|
|
4852
|
-
console.log(`Starting export...`);
|
|
4853
|
-
await strapi2.telemetry.send("didDEITSProcessStart", getTransferTelemetryPayload(engine));
|
|
4854
|
-
});
|
|
4855
|
-
let results;
|
|
4856
|
-
let outFile;
|
|
4857
|
-
try {
|
|
4858
|
-
setSignalHandler(() => abortTransfer({ engine, strapi: strapi2 }));
|
|
4859
|
-
results = await engine.transfer();
|
|
4860
|
-
outFile = results.destination?.file?.path ?? "";
|
|
4861
|
-
const outFileExists = await fse__default.pathExists(outFile);
|
|
4862
|
-
if (!outFileExists) {
|
|
4863
|
-
throw new TransferEngineTransferError(`Export file not created "${outFile}"`);
|
|
4864
|
-
}
|
|
4865
|
-
await strapi2.telemetry.send("didDEITSProcessFinish", getTransferTelemetryPayload(engine));
|
|
4866
|
-
try {
|
|
4867
|
-
const table = buildTransferTable(results.engine);
|
|
4868
|
-
console.log(table?.toString());
|
|
4869
|
-
} catch (e) {
|
|
4870
|
-
console.error("There was an error displaying the results of the transfer.");
|
|
4871
|
-
}
|
|
4872
|
-
console.log(`Export archive is in ${chalk.green(outFile)}`);
|
|
4873
|
-
exitWith(0, exitMessageText("export"));
|
|
4874
|
-
} catch {
|
|
4875
|
-
await strapi2.telemetry.send("didDEITSProcessFail", getTransferTelemetryPayload(engine));
|
|
4876
|
-
exitWith(1, exitMessageText("export", true));
|
|
4877
|
-
}
|
|
4878
|
-
};
|
|
4879
|
-
const createSourceProvider = (strapi2) => {
|
|
4880
|
-
return createLocalStrapiSourceProvider$1({
|
|
4881
|
-
async getStrapi() {
|
|
4882
|
-
return strapi2;
|
|
4883
|
-
}
|
|
4884
|
-
});
|
|
4885
|
-
};
|
|
4886
|
-
const createDestinationProvider = (opts) => {
|
|
4887
|
-
const { file: file2, compress, encrypt, key, maxSizeJsonl } = opts;
|
|
4888
|
-
const filepath = isString(file2) && file2.length > 0 ? file2 : getDefaultExportName();
|
|
4889
|
-
const maxSizeJsonlInMb = isFinite(toNumber(maxSizeJsonl)) ? toNumber(maxSizeJsonl) * BYTES_IN_MB : void 0;
|
|
4890
|
-
return createLocalFileDestinationProvider({
|
|
4891
|
-
file: {
|
|
4892
|
-
path: filepath,
|
|
4893
|
-
maxSizeJsonl: maxSizeJsonlInMb
|
|
4894
|
-
},
|
|
4895
|
-
encryption: {
|
|
4896
|
-
enabled: encrypt ?? false,
|
|
4897
|
-
key: encrypt ? key : void 0
|
|
4898
|
-
},
|
|
4899
|
-
compression: {
|
|
4900
|
-
enabled: compress ?? false
|
|
4901
|
-
}
|
|
4902
|
-
});
|
|
4903
|
-
};
|
|
4904
|
-
const command$2 = ({ command: command2 }) => {
|
|
4905
|
-
command2.command("export").description("Export data from Strapi to file").allowExcessArguments(false).addOption(
|
|
4906
|
-
new Option("--no-encrypt", `Disables 'aes-128-ecb' encryption of the output file`).default(
|
|
4907
|
-
true
|
|
4908
|
-
)
|
|
4909
|
-
).addOption(
|
|
4910
|
-
new Option("--no-compress", "Disables gzip compression of output file").default(true)
|
|
4911
|
-
).addOption(
|
|
4912
|
-
new Option(
|
|
4913
|
-
"-k, --key <string>",
|
|
4914
|
-
"Provide encryption key in command instead of using the prompt"
|
|
4915
|
-
)
|
|
4916
|
-
).addOption(
|
|
4917
|
-
new Option("-f, --file <file>", "name to use for exported file (without extensions)")
|
|
4918
|
-
).addOption(excludeOption).addOption(onlyOption).addOption(throttleOption).hook("preAction", validateExcludeOnly).hook("preAction", promptEncryptionKey).action(action$2);
|
|
4919
|
-
};
|
|
4920
|
-
const {
|
|
4921
|
-
providers: { createLocalFileSourceProvider }
|
|
4922
|
-
} = file;
|
|
4923
|
-
const {
|
|
4924
|
-
providers: { createLocalStrapiDestinationProvider: createLocalStrapiDestinationProvider$1, DEFAULT_CONFLICT_STRATEGY }
|
|
4925
|
-
} = strapiDatatransfer;
|
|
4926
|
-
const { createTransferEngine: createTransferEngine$1, DEFAULT_VERSION_STRATEGY, DEFAULT_SCHEMA_STRATEGY } = engineDatatransfer;
|
|
4927
|
-
const action$1 = async (opts) => {
|
|
4928
|
-
if (!isObject(opts)) {
|
|
4929
|
-
exitWith(1, "Could not parse arguments");
|
|
4930
|
-
}
|
|
4931
|
-
const sourceOptions = getLocalFileSourceOptions(opts);
|
|
4932
|
-
const source = createLocalFileSourceProvider(sourceOptions);
|
|
4933
|
-
const strapiInstance = await createStrapiInstance();
|
|
4934
|
-
const engineOptions = {
|
|
4935
|
-
versionStrategy: DEFAULT_VERSION_STRATEGY,
|
|
4936
|
-
schemaStrategy: DEFAULT_SCHEMA_STRATEGY,
|
|
4937
|
-
exclude: opts.exclude,
|
|
4938
|
-
only: opts.only,
|
|
4939
|
-
throttle: opts.throttle,
|
|
4940
|
-
transforms: {
|
|
4941
|
-
links: [
|
|
4942
|
-
{
|
|
4943
|
-
filter(link2) {
|
|
4944
|
-
return !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.left.type) && !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.right.type);
|
|
4945
|
-
}
|
|
4946
|
-
}
|
|
4947
|
-
],
|
|
4948
|
-
entities: [
|
|
4949
|
-
{
|
|
4950
|
-
filter: (entity2) => !DEFAULT_IGNORED_CONTENT_TYPES.includes(entity2.type)
|
|
4951
|
-
}
|
|
4952
|
-
]
|
|
4953
|
-
}
|
|
4954
|
-
};
|
|
4955
|
-
const destinationOptions = {
|
|
4956
|
-
async getStrapi() {
|
|
4957
|
-
return strapiInstance;
|
|
4958
|
-
},
|
|
4959
|
-
autoDestroy: false,
|
|
4960
|
-
strategy: opts.conflictStrategy || DEFAULT_CONFLICT_STRATEGY,
|
|
4961
|
-
restore: parseRestoreFromOptions(engineOptions)
|
|
4962
|
-
};
|
|
4963
|
-
const destination = createLocalStrapiDestinationProvider$1(destinationOptions);
|
|
4964
|
-
destination.onWarning = (message) => console.warn(`
|
|
4965
|
-
${chalk.yellow("warn")}: ${message}`);
|
|
4966
|
-
const engine2 = createTransferEngine$1(source, destination, engineOptions);
|
|
4967
|
-
engine2.diagnostics.onDiagnostic(formatDiagnostic("import"));
|
|
4968
|
-
const progress = engine2.progress.stream;
|
|
4969
|
-
const { updateLoader } = loadersFactory();
|
|
4970
|
-
engine2.onSchemaDiff(getDiffHandler(engine2, { force: opts.force, action: "import" }));
|
|
4971
|
-
progress.on(`stage::start`, ({ stage, data }) => {
|
|
4972
|
-
updateLoader(stage, data).start();
|
|
4973
|
-
});
|
|
4974
|
-
progress.on("stage::finish", ({ stage, data }) => {
|
|
4975
|
-
updateLoader(stage, data).succeed();
|
|
4976
|
-
});
|
|
4977
|
-
progress.on("stage::progress", ({ stage, data }) => {
|
|
4978
|
-
updateLoader(stage, data);
|
|
4979
|
-
});
|
|
4980
|
-
progress.on("transfer::start", async () => {
|
|
4981
|
-
console.log("Starting import...");
|
|
4982
|
-
await strapiInstance.telemetry.send(
|
|
4983
|
-
"didDEITSProcessStart",
|
|
4984
|
-
getTransferTelemetryPayload(engine2)
|
|
4985
|
-
);
|
|
4986
|
-
});
|
|
4987
|
-
let results;
|
|
4988
|
-
try {
|
|
4989
|
-
setSignalHandler(() => abortTransfer({ engine: engine2, strapi }));
|
|
4990
|
-
results = await engine2.transfer();
|
|
4991
|
-
try {
|
|
4992
|
-
const table = buildTransferTable(results.engine);
|
|
4993
|
-
console.log(table?.toString());
|
|
4994
|
-
} catch (e) {
|
|
4995
|
-
console.error("There was an error displaying the results of the transfer.");
|
|
4996
|
-
}
|
|
4997
|
-
await strapiInstance.telemetry.send(
|
|
4998
|
-
"didDEITSProcessFinish",
|
|
4999
|
-
getTransferTelemetryPayload(engine2)
|
|
5000
|
-
);
|
|
5001
|
-
await strapiInstance.destroy();
|
|
5002
|
-
exitWith(0, exitMessageText("import"));
|
|
5003
|
-
} catch (e) {
|
|
5004
|
-
await strapiInstance.telemetry.send("didDEITSProcessFail", getTransferTelemetryPayload(engine2));
|
|
5005
|
-
exitWith(1, exitMessageText("import", true));
|
|
5006
|
-
}
|
|
5007
|
-
};
|
|
5008
|
-
const getLocalFileSourceOptions = (opts) => {
|
|
5009
|
-
const options = {
|
|
5010
|
-
file: { path: opts.file ?? "" },
|
|
5011
|
-
compression: { enabled: !!opts.decompress },
|
|
5012
|
-
encryption: { enabled: !!opts.decrypt, key: opts.key }
|
|
5013
|
-
};
|
|
5014
|
-
return options;
|
|
5015
|
-
};
|
|
5016
|
-
const command$1 = ({ command: command2 }) => {
|
|
5017
|
-
command2.command("import").description("Import data from file to Strapi").allowExcessArguments(false).requiredOption(
|
|
5018
|
-
"-f, --file <file>",
|
|
5019
|
-
"path and filename for the Strapi export file you want to import"
|
|
5020
|
-
).addOption(
|
|
5021
|
-
new Option(
|
|
5022
|
-
"-k, --key <string>",
|
|
5023
|
-
"Provide encryption key in command instead of using the prompt"
|
|
5024
|
-
)
|
|
5025
|
-
).addOption(forceOption).addOption(excludeOption).addOption(onlyOption).addOption(throttleOption).hook("preAction", validateExcludeOnly).hook("preAction", async (thisCommand) => {
|
|
5026
|
-
const opts = thisCommand.opts();
|
|
5027
|
-
const ext = path.extname(String(opts.file));
|
|
5028
|
-
if (ext === ".enc") {
|
|
5029
|
-
if (!opts.key) {
|
|
5030
|
-
const answers = await inquirer.prompt([
|
|
5031
|
-
{
|
|
5032
|
-
type: "password",
|
|
5033
|
-
message: "Please enter your decryption key",
|
|
5034
|
-
name: "key"
|
|
5035
|
-
}
|
|
5036
|
-
]);
|
|
5037
|
-
if (!answers.key?.length) {
|
|
5038
|
-
exitWith(1, "No key entered, aborting import.");
|
|
5039
|
-
}
|
|
5040
|
-
opts.key = answers.key;
|
|
5041
|
-
}
|
|
5042
|
-
}
|
|
5043
|
-
}).hook("preAction", (thisCommand) => {
|
|
5044
|
-
const opts = thisCommand.opts();
|
|
5045
|
-
const { extname: extname2, parse } = path;
|
|
5046
|
-
let file2 = opts.file;
|
|
5047
|
-
if (extname2(file2) === ".enc") {
|
|
5048
|
-
file2 = parse(file2).name;
|
|
5049
|
-
thisCommand.opts().decrypt = true;
|
|
5050
|
-
} else {
|
|
5051
|
-
thisCommand.opts().decrypt = false;
|
|
5052
|
-
}
|
|
5053
|
-
if (extname2(file2) === ".gz") {
|
|
5054
|
-
file2 = parse(file2).name;
|
|
5055
|
-
thisCommand.opts().decompress = true;
|
|
5056
|
-
} else {
|
|
5057
|
-
thisCommand.opts().decompress = false;
|
|
5058
|
-
}
|
|
5059
|
-
if (extname2(file2) !== ".tar") {
|
|
5060
|
-
exitWith(
|
|
5061
|
-
1,
|
|
5062
|
-
`The file '${opts.file}' does not appear to be a valid Strapi data file. It must have an extension ending in .tar[.gz][.enc]`
|
|
5063
|
-
);
|
|
5064
|
-
}
|
|
5065
|
-
}).hook(
|
|
5066
|
-
"preAction",
|
|
5067
|
-
getCommanderConfirmMessage(
|
|
5068
|
-
"The import will delete your existing data! Are you sure you want to proceed?",
|
|
5069
|
-
{ failMessage: "Import process aborted" }
|
|
5070
|
-
)
|
|
5071
|
-
).action(action$1);
|
|
5072
|
-
};
|
|
5073
|
-
const { createTransferEngine } = engineDatatransfer;
|
|
5074
|
-
const {
|
|
5075
|
-
providers: {
|
|
5076
|
-
createRemoteStrapiDestinationProvider,
|
|
5077
|
-
createLocalStrapiSourceProvider,
|
|
5078
|
-
createLocalStrapiDestinationProvider,
|
|
5079
|
-
createRemoteStrapiSourceProvider
|
|
5080
|
-
}
|
|
5081
|
-
} = strapiDatatransfer;
|
|
5082
|
-
const action = async (opts) => {
|
|
5083
|
-
if (!isObject(opts)) {
|
|
5084
|
-
exitWith(1, "Could not parse command arguments");
|
|
5085
|
-
}
|
|
5086
|
-
if (!(opts.from || opts.to) || opts.from && opts.to) {
|
|
5087
|
-
exitWith(1, "Exactly one source (from) or destination (to) option must be provided");
|
|
5088
|
-
}
|
|
5089
|
-
const strapi2 = await createStrapiInstance();
|
|
5090
|
-
let source;
|
|
5091
|
-
let destination;
|
|
5092
|
-
if (!opts.from) {
|
|
5093
|
-
source = createLocalStrapiSourceProvider({
|
|
5094
|
-
getStrapi: () => strapi2
|
|
5095
|
-
});
|
|
5096
|
-
} else {
|
|
5097
|
-
if (!opts.fromToken) {
|
|
5098
|
-
exitWith(1, "Missing token for remote destination");
|
|
5099
|
-
}
|
|
5100
|
-
source = createRemoteStrapiSourceProvider({
|
|
5101
|
-
getStrapi: () => strapi2,
|
|
5102
|
-
url: opts.from,
|
|
5103
|
-
auth: {
|
|
5104
|
-
type: "token",
|
|
5105
|
-
token: opts.fromToken
|
|
5106
|
-
}
|
|
5107
|
-
});
|
|
5108
|
-
}
|
|
5109
|
-
if (!opts.to) {
|
|
5110
|
-
destination = createLocalStrapiDestinationProvider({
|
|
5111
|
-
getStrapi: () => strapi2,
|
|
5112
|
-
strategy: "restore",
|
|
5113
|
-
restore: parseRestoreFromOptions(opts)
|
|
5114
|
-
});
|
|
5115
|
-
} else {
|
|
5116
|
-
if (!opts.toToken) {
|
|
5117
|
-
exitWith(1, "Missing token for remote destination");
|
|
5118
|
-
}
|
|
5119
|
-
destination = createRemoteStrapiDestinationProvider({
|
|
5120
|
-
url: opts.to,
|
|
5121
|
-
auth: {
|
|
5122
|
-
type: "token",
|
|
5123
|
-
token: opts.toToken
|
|
5124
|
-
},
|
|
5125
|
-
strategy: "restore",
|
|
5126
|
-
restore: parseRestoreFromOptions(opts)
|
|
5127
|
-
});
|
|
5128
|
-
}
|
|
5129
|
-
if (!source || !destination) {
|
|
5130
|
-
exitWith(1, "Could not create providers");
|
|
5131
|
-
}
|
|
5132
|
-
const engine = createTransferEngine(source, destination, {
|
|
5133
|
-
versionStrategy: "exact",
|
|
5134
|
-
schemaStrategy: "strict",
|
|
5135
|
-
exclude: opts.exclude,
|
|
5136
|
-
only: opts.only,
|
|
5137
|
-
throttle: opts.throttle,
|
|
5138
|
-
transforms: {
|
|
5139
|
-
links: [
|
|
5140
|
-
{
|
|
5141
|
-
filter(link2) {
|
|
5142
|
-
return !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.left.type) && !DEFAULT_IGNORED_CONTENT_TYPES.includes(link2.right.type);
|
|
5143
|
-
}
|
|
5144
|
-
}
|
|
5145
|
-
],
|
|
5146
|
-
entities: [
|
|
5147
|
-
{
|
|
5148
|
-
filter(entity2) {
|
|
5149
|
-
return !DEFAULT_IGNORED_CONTENT_TYPES.includes(entity2.type);
|
|
5150
|
-
}
|
|
5151
|
-
}
|
|
5152
|
-
]
|
|
5153
|
-
}
|
|
5154
|
-
});
|
|
5155
|
-
engine.diagnostics.onDiagnostic(formatDiagnostic("transfer"));
|
|
5156
|
-
const progress = engine.progress.stream;
|
|
5157
|
-
const { updateLoader } = loadersFactory();
|
|
5158
|
-
engine.onSchemaDiff(getDiffHandler(engine, { force: opts.force, action: "transfer" }));
|
|
5159
|
-
engine.addErrorHandler(
|
|
5160
|
-
"ASSETS_DIRECTORY_ERR",
|
|
5161
|
-
getAssetsBackupHandler(engine, { force: opts.force, action: "transfer" })
|
|
5162
|
-
);
|
|
5163
|
-
progress.on(`stage::start`, ({ stage, data }) => {
|
|
5164
|
-
updateLoader(stage, data).start();
|
|
5165
|
-
});
|
|
5166
|
-
progress.on("stage::finish", ({ stage, data }) => {
|
|
5167
|
-
updateLoader(stage, data).succeed();
|
|
5168
|
-
});
|
|
5169
|
-
progress.on("stage::progress", ({ stage, data }) => {
|
|
5170
|
-
updateLoader(stage, data);
|
|
5171
|
-
});
|
|
5172
|
-
progress.on("stage::error", ({ stage, data }) => {
|
|
5173
|
-
updateLoader(stage, data).fail();
|
|
5174
|
-
});
|
|
5175
|
-
progress.on("transfer::start", async () => {
|
|
5176
|
-
console.log(`Starting transfer...`);
|
|
5177
|
-
await strapi2.telemetry.send("didDEITSProcessStart", getTransferTelemetryPayload(engine));
|
|
5178
|
-
});
|
|
5179
|
-
let results;
|
|
5180
|
-
try {
|
|
5181
|
-
setSignalHandler(() => abortTransfer({ engine, strapi: strapi2 }));
|
|
5182
|
-
results = await engine.transfer();
|
|
5183
|
-
await strapi2.telemetry.send("didDEITSProcessFinish", getTransferTelemetryPayload(engine));
|
|
5184
|
-
try {
|
|
5185
|
-
const table = buildTransferTable(results.engine);
|
|
5186
|
-
console.log(table?.toString());
|
|
5187
|
-
} catch (e) {
|
|
5188
|
-
console.error("There was an error displaying the results of the transfer.");
|
|
5189
|
-
}
|
|
5190
|
-
exitWith(0, exitMessageText("transfer"));
|
|
5191
|
-
} catch (e) {
|
|
5192
|
-
await strapi2.telemetry.send("didDEITSProcessFail", getTransferTelemetryPayload(engine));
|
|
5193
|
-
exitWith(1, exitMessageText("transfer", true));
|
|
5194
|
-
}
|
|
5195
|
-
};
|
|
5196
|
-
const command = ({ command: command2 }) => {
|
|
5197
|
-
command2.command("transfer").description("Transfer data from one source to another").allowExcessArguments(false).addOption(
|
|
5198
|
-
new Option(
|
|
5199
|
-
"--from <sourceURL>",
|
|
5200
|
-
`URL of the remote Strapi instance to get data from`
|
|
5201
|
-
).argParser(parseURL)
|
|
5202
|
-
).addOption(new Option("--from-token <token>", `Transfer token for the remote Strapi source`)).addOption(
|
|
5203
|
-
new Option(
|
|
5204
|
-
"--to <destinationURL>",
|
|
5205
|
-
`URL of the remote Strapi instance to send data to`
|
|
5206
|
-
).argParser(parseURL)
|
|
5207
|
-
).addOption(new Option("--to-token <token>", `Transfer token for the remote Strapi destination`)).addOption(forceOption).addOption(excludeOption).addOption(onlyOption).addOption(throttleOption).hook("preAction", validateExcludeOnly).hook(
|
|
5208
|
-
"preAction",
|
|
5209
|
-
ifOptions(
|
|
5210
|
-
(opts) => !(opts.from || opts.to) || opts.from && opts.to,
|
|
5211
|
-
async () => exitWith(
|
|
5212
|
-
1,
|
|
5213
|
-
"Exactly one remote source (from) or destination (to) option must be provided"
|
|
5214
|
-
)
|
|
5215
|
-
)
|
|
5216
|
-
).hook(
|
|
5217
|
-
"preAction",
|
|
5218
|
-
ifOptions(
|
|
5219
|
-
(opts) => opts.from,
|
|
5220
|
-
async (thisCommand) => {
|
|
5221
|
-
assertUrlHasProtocol(thisCommand.opts().from, ["https:", "http:"]);
|
|
5222
|
-
if (!thisCommand.opts().fromToken) {
|
|
5223
|
-
const answers = await inquirer.prompt([
|
|
5224
|
-
{
|
|
5225
|
-
type: "password",
|
|
5226
|
-
message: "Please enter your transfer token for the remote Strapi source",
|
|
5227
|
-
name: "fromToken"
|
|
5228
|
-
}
|
|
5229
|
-
]);
|
|
5230
|
-
if (!answers.fromToken?.length) {
|
|
5231
|
-
exitWith(1, "No token provided for remote source, aborting transfer.");
|
|
5232
|
-
}
|
|
5233
|
-
thisCommand.opts().fromToken = answers.fromToken;
|
|
5234
|
-
}
|
|
5235
|
-
await getCommanderConfirmMessage(
|
|
5236
|
-
"The transfer will delete all the local Strapi assets and its database. Are you sure you want to proceed?",
|
|
5237
|
-
{ failMessage: "Transfer process aborted" }
|
|
5238
|
-
)(thisCommand);
|
|
5239
|
-
}
|
|
5240
|
-
)
|
|
5241
|
-
).hook(
|
|
5242
|
-
"preAction",
|
|
5243
|
-
ifOptions(
|
|
5244
|
-
(opts) => opts.to,
|
|
5245
|
-
async (thisCommand) => {
|
|
5246
|
-
assertUrlHasProtocol(thisCommand.opts().to, ["https:", "http:"]);
|
|
5247
|
-
if (!thisCommand.opts().toToken) {
|
|
5248
|
-
const answers = await inquirer.prompt([
|
|
5249
|
-
{
|
|
5250
|
-
type: "password",
|
|
5251
|
-
message: "Please enter your transfer token for the remote Strapi destination",
|
|
5252
|
-
name: "toToken"
|
|
5253
|
-
}
|
|
5254
|
-
]);
|
|
5255
|
-
if (!answers.toToken?.length) {
|
|
5256
|
-
exitWith(1, "No token provided for remote destination, aborting transfer.");
|
|
5257
|
-
}
|
|
5258
|
-
thisCommand.opts().toToken = answers.toToken;
|
|
5259
|
-
}
|
|
5260
|
-
await getCommanderConfirmMessage(
|
|
5261
|
-
"The transfer will delete existing data from the remote Strapi! Are you sure you want to proceed?",
|
|
5262
|
-
{ failMessage: "Transfer process aborted" }
|
|
5263
|
-
)(thisCommand);
|
|
5264
|
-
}
|
|
5265
|
-
)
|
|
5266
|
-
).action(action);
|
|
5267
|
-
};
|
|
5268
4342
|
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
5269
4343
|
__proto__: null,
|
|
5270
|
-
|
|
5271
|
-
import: command$1,
|
|
5272
|
-
transfer: command
|
|
4344
|
+
providers: index$1
|
|
5273
4345
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
5274
4346
|
export {
|
|
5275
|
-
index as
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
index$6 as utils
|
|
4347
|
+
index$7 as engine,
|
|
4348
|
+
index as file,
|
|
4349
|
+
index$2 as strapi,
|
|
4350
|
+
index$8 as utils
|
|
5280
4351
|
};
|
|
5281
4352
|
//# sourceMappingURL=index.mjs.map
|