@strapi/data-transfer 5.0.0-beta.1 → 5.0.0-beta.11

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 (51) hide show
  1. package/dist/engine/diagnostic.d.ts.map +1 -1
  2. package/dist/engine/index.d.ts.map +1 -1
  3. package/dist/engine/validation/provider.d.ts +1 -1
  4. package/dist/engine/validation/provider.d.ts.map +1 -1
  5. package/dist/engine/validation/schemas/index.d.ts.map +1 -1
  6. package/dist/file/providers/destination/utils.d.ts.map +1 -1
  7. package/dist/file/providers/source/index.d.ts +1 -3
  8. package/dist/file/providers/source/index.d.ts.map +1 -1
  9. package/dist/index.js +80 -45
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +81 -46
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/strapi/providers/local-destination/index.d.ts +2 -2
  14. package/dist/strapi/providers/local-destination/index.d.ts.map +1 -1
  15. package/dist/strapi/providers/local-destination/strategies/restore/configuration.d.ts +2 -2
  16. package/dist/strapi/providers/local-destination/strategies/restore/configuration.d.ts.map +1 -1
  17. package/dist/strapi/providers/local-destination/strategies/restore/entities.d.ts +3 -3
  18. package/dist/strapi/providers/local-destination/strategies/restore/entities.d.ts.map +1 -1
  19. package/dist/strapi/providers/local-destination/strategies/restore/index.d.ts +1 -1
  20. package/dist/strapi/providers/local-destination/strategies/restore/index.d.ts.map +1 -1
  21. package/dist/strapi/providers/local-destination/strategies/restore/links.d.ts +1 -1
  22. package/dist/strapi/providers/local-destination/strategies/restore/links.d.ts.map +1 -1
  23. package/dist/strapi/providers/local-source/assets.d.ts +1 -1
  24. package/dist/strapi/providers/local-source/assets.d.ts.map +1 -1
  25. package/dist/strapi/providers/local-source/configuration.d.ts +1 -1
  26. package/dist/strapi/providers/local-source/configuration.d.ts.map +1 -1
  27. package/dist/strapi/providers/local-source/entities.d.ts +1 -1
  28. package/dist/strapi/providers/local-source/entities.d.ts.map +1 -1
  29. package/dist/strapi/providers/local-source/index.d.ts +2 -2
  30. package/dist/strapi/providers/local-source/index.d.ts.map +1 -1
  31. package/dist/strapi/providers/local-source/links.d.ts +1 -1
  32. package/dist/strapi/providers/local-source/links.d.ts.map +1 -1
  33. package/dist/strapi/providers/remote-source/index.d.ts.map +1 -1
  34. package/dist/strapi/providers/utils.d.ts +1 -1
  35. package/dist/strapi/providers/utils.d.ts.map +1 -1
  36. package/dist/strapi/queries/entity.d.ts +1 -1
  37. package/dist/strapi/queries/entity.d.ts.map +1 -1
  38. package/dist/strapi/queries/link.d.ts +2 -1
  39. package/dist/strapi/queries/link.d.ts.map +1 -1
  40. package/dist/strapi/remote/handlers/utils.d.ts.map +1 -1
  41. package/dist/utils/components.d.ts +13 -74
  42. package/dist/utils/components.d.ts.map +1 -1
  43. package/dist/utils/middleware.d.ts.map +1 -1
  44. package/dist/utils/providers.d.ts +1 -1
  45. package/dist/utils/providers.d.ts.map +1 -1
  46. package/dist/utils/schema.d.ts +1 -0
  47. package/dist/utils/schema.d.ts.map +1 -1
  48. package/dist/utils/stream.d.ts.map +1 -1
  49. package/dist/utils/transaction.d.ts +1 -1
  50. package/dist/utils/transaction.d.ts.map +1 -1
  51. package/package.json +11 -11
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ 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 } from "lodash/fp";
5
+ import { isArray, zip, isObject, uniq, isEqual, mapValues, pick, reject as reject$1, capitalize, isNumber, isEmpty, last, set, get, has, pipe, omit, assign, map as map$1, size, isNil, clone, 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";
@@ -196,9 +196,13 @@ const VALID_SCHEMA_PROPERTIES = [
196
196
  const mapSchemasValues = (schemas) => {
197
197
  return mapValues(pick(VALID_SCHEMA_PROPERTIES), schemas);
198
198
  };
199
+ const schemasToValidJSON = (schemas) => {
200
+ return JSON.parse(JSON.stringify(schemas));
201
+ };
199
202
  const schema = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
200
203
  __proto__: null,
201
- mapSchemasValues
204
+ mapSchemasValues,
205
+ schemasToValidJSON
202
206
  }, Symbol.toStringTag, { value: "Module" }));
203
207
  const createTransaction = (strapi2) => {
204
208
  const fns = [];
@@ -308,7 +312,7 @@ const isAttributeIgnorable = (diff2) => {
308
312
  return diff2.path.length === 3 && // Root property must be attributes
309
313
  diff2.path[0] === "attributes" && // Need a valid string attribute name
310
314
  typeof diff2.path[1] === "string" && // The diff must be on ignorable attribute properties
311
- ["private", "required", "configurable"].includes(diff2.path[2]);
315
+ ["private", "required", "configurable", "default"].includes(diff2.path[2]);
312
316
  };
313
317
  const isOptionalAdminType = (diff2) => {
314
318
  if ("value" in diff2 && isObject(diff2.value)) {
@@ -1040,8 +1044,8 @@ ${formattedDiffs}`,
1040
1044
  }
1041
1045
  const { type, data } = entity2;
1042
1046
  const attributes = schemas[type].attributes;
1043
- const attributesToRemove = difference(Object.keys(data), Object.keys(attributes));
1044
- const updatedEntity = set("data", omit(attributesToRemove, data), entity2);
1047
+ const attributesToKeep = Object.keys(attributes).concat("documentId");
1048
+ const updatedEntity = set("data", pick(attributesToKeep, data), entity2);
1045
1049
  callback(null, updatedEntity);
1046
1050
  }
1047
1051
  })
@@ -1255,6 +1259,34 @@ const deleteComponent = async (uid, componentToDelete) => {
1255
1259
  await deleteComponents(uid, componentToDelete);
1256
1260
  await strapi.db.query(uid).delete({ where: { id: componentToDelete.id } });
1257
1261
  };
1262
+ const resolveComponentUID = ({
1263
+ paths,
1264
+ strapi: strapi2,
1265
+ data,
1266
+ contentType
1267
+ }) => {
1268
+ let value = data;
1269
+ let cType = contentType;
1270
+ for (const path2 of paths) {
1271
+ value = get(path2, value);
1272
+ if (typeof cType === "function") {
1273
+ cType = cType(value);
1274
+ }
1275
+ if (path2 in cType.attributes) {
1276
+ const attribute = cType.attributes[path2];
1277
+ if (attribute.type === "component") {
1278
+ cType = strapi2.getModel(attribute.component);
1279
+ }
1280
+ if (attribute.type === "dynamiczone") {
1281
+ cType = ({ __component }) => strapi2.getModel(__component);
1282
+ }
1283
+ }
1284
+ }
1285
+ if ("uid" in cType) {
1286
+ return cType.uid;
1287
+ }
1288
+ return void 0;
1289
+ };
1258
1290
  const sanitizeComponentLikeAttributes = (model, data) => {
1259
1291
  const { attributes } = model;
1260
1292
  const componentLikeAttributesKey = Object.entries(attributes).filter(([, attribute]) => attribute.type === "component" || attribute.type === "dynamiczone").map(([key]) => key);
@@ -1504,6 +1536,9 @@ const createLinkQuery = (strapi2, trx) => {
1504
1536
  const metadata = strapi2.db.metadata.get(left.type);
1505
1537
  const attribute = metadata.attributes[left.field];
1506
1538
  const payload = {};
1539
+ if (!attribute) {
1540
+ return;
1541
+ }
1507
1542
  if (attribute.type !== "relation") {
1508
1543
  throw new Error(`Attribute ${left.field} is not a relation`);
1509
1544
  }
@@ -1581,9 +1616,7 @@ const filterValidRelationalAttributes = (attributes) => {
1581
1616
  const isOwner = (attribute) => {
1582
1617
  return attribute.owner || !attribute.mappedBy && !attribute.morphBy;
1583
1618
  };
1584
- const isComponentLike = (attribute) => {
1585
- return attribute.component || attribute.components;
1586
- };
1619
+ const isComponentLike = (attribute) => attribute.joinTable?.name.endsWith("_cmps");
1587
1620
  return Object.entries(attributes).filter(([, attribute]) => {
1588
1621
  return attribute.type === "relation" && isOwner(attribute) && !isComponentLike(attribute);
1589
1622
  }).reduce((acc, [key, attribute]) => ({ ...acc, [key]: attribute }), {});
@@ -1599,7 +1632,8 @@ const getLinkKind = (attribute, uid) => {
1599
1632
  };
1600
1633
  const link = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1601
1634
  __proto__: null,
1602
- createLinkQuery
1635
+ createLinkQuery,
1636
+ filterValidRelationalAttributes
1603
1637
  }, Symbol.toStringTag, { value: "Module" }));
1604
1638
  const index$6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1605
1639
  __proto__: null,
@@ -1616,29 +1650,6 @@ const createEntitiesWriteStream = (options) => {
1616
1650
  const { type, id, data } = entity2;
1617
1651
  const { create, getDeepPopulateComponentLikeQuery } = query(type);
1618
1652
  const contentType = strapi2.getModel(type);
1619
- let cType = contentType;
1620
- const resolveType = (paths) => {
1621
- let value = data;
1622
- for (const path2 of paths) {
1623
- value = get(path2, value);
1624
- if (typeof cType === "function") {
1625
- cType = cType(value);
1626
- }
1627
- if (path2 in cType.attributes) {
1628
- const attribute = cType.attributes[path2];
1629
- if (attribute.type === "component") {
1630
- cType = strapi2.getModel(attribute.component);
1631
- }
1632
- if (attribute.type === "dynamiczone") {
1633
- cType = ({ __component }) => strapi2.getModel(__component);
1634
- }
1635
- }
1636
- }
1637
- if ("uid" in cType) {
1638
- return cType.uid;
1639
- }
1640
- return void 0;
1641
- };
1642
1653
  try {
1643
1654
  const created = await create({
1644
1655
  data,
@@ -1648,8 +1659,8 @@ const createEntitiesWriteStream = (options) => {
1648
1659
  const diffs = diff(data, created);
1649
1660
  updateMappingTable(type, id, created.id);
1650
1661
  diffs.forEach((diff2) => {
1651
- if (diff2.kind === "modified" && last(diff2.path) === "id") {
1652
- const target = resolveType(diff2.path);
1662
+ if (diff2.kind === "modified" && last(diff2.path) === "id" && "kind" in contentType) {
1663
+ const target = resolveComponentUID({ paths: diff2.path, data, contentType, strapi: strapi2 });
1653
1664
  if (!target) {
1654
1665
  return;
1655
1666
  }
@@ -1962,10 +1973,10 @@ class LocalStrapiDestinationProvider {
1962
1973
  }
1963
1974
  getSchemas() {
1964
1975
  assertValidStrapi(this.strapi, "Not able to get Schemas");
1965
- const schemas = {
1976
+ const schemas = schemasToValidJSON({
1966
1977
  ...this.strapi.contentTypes,
1967
1978
  ...this.strapi.components
1968
- };
1979
+ });
1969
1980
  return mapSchemasValues(schemas);
1970
1981
  }
1971
1982
  createEntitiesWriteStream() {
@@ -2279,11 +2290,31 @@ function getFileStats(filepath, strapi2, isLocal = false) {
2279
2290
  });
2280
2291
  });
2281
2292
  }
2293
+ async function signFile(file) {
2294
+ const { provider } = strapi.plugins.upload;
2295
+ const { provider: providerName } = strapi.config.get("plugin.upload");
2296
+ const isPrivate = await provider.isPrivate();
2297
+ if (file?.provider === providerName && isPrivate) {
2298
+ const signUrl = async (file2) => {
2299
+ const signedUrl = await provider.getSignedUrl(file2);
2300
+ file2.url = signedUrl.url;
2301
+ };
2302
+ await signUrl(file);
2303
+ if (file.formats) {
2304
+ for (const format of Object.keys(file.formats)) {
2305
+ await signUrl(file.formats[format]);
2306
+ }
2307
+ }
2308
+ }
2309
+ }
2282
2310
  const createAssetsStream = (strapi2) => {
2283
2311
  const generator = async function* () {
2284
2312
  const stream2 = strapi2.db.queryBuilder("plugin::upload.file").select("*").stream();
2285
2313
  for await (const file of stream2) {
2286
2314
  const isLocalProvider = file.provider === "local";
2315
+ if (!isLocalProvider) {
2316
+ await signFile(file);
2317
+ }
2287
2318
  const filepath = isLocalProvider ? join(strapi2.dirs.static.public, file.url) : file.url;
2288
2319
  const stats = await getFileStats(filepath, strapi2, isLocalProvider);
2289
2320
  const stream22 = getFileStream(filepath, strapi2, isLocalProvider);
@@ -2363,10 +2394,10 @@ class LocalStrapiSourceProvider {
2363
2394
  }
2364
2395
  getSchemas() {
2365
2396
  assertValidStrapi(this.strapi, "Not able to get Schemas");
2366
- const schemas = {
2397
+ const schemas = schemasToValidJSON({
2367
2398
  ...this.strapi.contentTypes,
2368
2399
  ...this.strapi.components
2369
- };
2400
+ });
2370
2401
  return mapSchemasValues(schemas);
2371
2402
  }
2372
2403
  createSchemasReadStream() {
@@ -2941,9 +2972,7 @@ class RemoteStrapiSourceProvider {
2941
2972
  });
2942
2973
  }
2943
2974
  async getSchemas() {
2944
- const schemas = await this.dispatcher?.dispatchTransferAction(
2945
- "getSchemas"
2946
- );
2975
+ const schemas = await this.dispatcher?.dispatchTransferAction("getSchemas");
2947
2976
  return schemas ?? null;
2948
2977
  }
2949
2978
  async #startStep(step) {
@@ -3082,8 +3111,11 @@ const transformUpgradeHeader = (header = "") => {
3082
3111
  return header.split(",").map((s) => s.trim().toLowerCase());
3083
3112
  };
3084
3113
  let timeouts;
3114
+ const hasHttpServer = () => {
3115
+ return typeof strapi !== "undefined" && !!strapi?.server?.httpServer;
3116
+ };
3085
3117
  const disableTimeouts = () => {
3086
- if (!strapi?.server?.httpServer) {
3118
+ if (!hasHttpServer()) {
3087
3119
  return;
3088
3120
  }
3089
3121
  const { httpServer } = strapi.server;
@@ -3098,7 +3130,7 @@ const disableTimeouts = () => {
3098
3130
  strapi.log.info("[Data transfer] Disabling http timeouts");
3099
3131
  };
3100
3132
  const resetTimeouts = () => {
3101
- if (!strapi?.server?.httpServer || !timeouts) {
3133
+ if (!hasHttpServer() || !timeouts) {
3102
3134
  return;
3103
3135
  }
3104
3136
  const { httpServer } = strapi.server;
@@ -3941,11 +3973,14 @@ class LocalFileSourceProvider {
3941
3973
  return this.#metadata ?? null;
3942
3974
  }
3943
3975
  async getSchemas() {
3944
- const schemas = await collect(this.createSchemasReadStream());
3945
- if (isEmpty(schemas)) {
3976
+ const schemaCollection = await collect(
3977
+ this.createSchemasReadStream()
3978
+ );
3979
+ if (isEmpty(schemaCollection)) {
3946
3980
  throw new ProviderInitializationError("Could not load schemas from Strapi data file.");
3947
3981
  }
3948
- return keyBy("uid", schemas);
3982
+ const schemas = keyBy("uid", schemaCollection);
3983
+ return schemasToValidJSON(schemas);
3949
3984
  }
3950
3985
  createEntitiesReadStream() {
3951
3986
  return this.#streamJsonlDirectory("entities");