contentful-import 10.3.0 → 10.4.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/README.md CHANGED
@@ -227,6 +227,10 @@ Path to a JSON file with the configuration options. This file will be merged wit
227
227
 
228
228
  Flag controlling whether Experience Orchestration (ExO) entities — Design Tokens, Components, Experience Templates, Experience Fragments, Data Assemblies, and Experiences — are imported when present in the source content. Requires the `exoM1` entitlement on the destination space's organization. Set to `false` to opt out. See the "Experience Orchestration (ExO) entities" section below for what happens when the destination isn't entitled.
229
229
 
230
+ #### `skipExoVariants` [boolean] [default: false]
231
+
232
+ Skip importing nested Experience and Experience Fragment Optimization Variants. This can be useful when re-importing the same export because the upstream API generates new variant IDs on every create and cannot upsert by the source variant ID.
233
+
230
234
  ## :rescue_worker_helmet: Troubleshooting
231
235
 
232
236
  ### Proxy
@@ -292,6 +296,8 @@ The `designTokens`, `components`, `experienceTemplates`, `dataAssemblies`, `expe
292
296
 
293
297
  ExO import is on by default (`includeExperienceOrchestration: true`) — for the CLI and the module API alike. Pass `includeExperienceOrchestration: false` (`--include-experience-orchestration=false` on the CLI) to opt out.
294
298
 
299
+ Optimization Variant import is on automatically when the source contains nested variants. Pass `skipExoVariants: true` (or `--skip-exo-variants`) to leave them out of the import. When variants are imported, a warning is logged because each run creates fresh destination variant IDs and re-importing can create duplicates.
300
+
295
301
  ```javascript
296
302
  import contentfulImport from 'contentful-import'
297
303
 
@@ -322,10 +328,21 @@ ExO entities are created and published in dependency order, then unpublished in
322
328
  4. Experience Templates — create, then publish
323
329
  5. Experience Fragments — create, then publish
324
330
  6. Experiences — create, then publish
325
- 7. Unpublish pass, in reverse: Experiences Experience Fragments Experience Templates Components Data Assemblies
331
+ 7. Experience Optimization Variants create, then publish/archive (only if the source has any; see below)
332
+ 8. Experience Fragment Optimization Variants — create, then publish/archive (only if the source has any; see below)
333
+ 9. Unpublish pass, in reverse: Experiences → Experience Fragments → Experience Templates → Components → Data Assemblies
326
334
 
327
335
  An entity that's published in the source is published in the destination on import. An entity that's unpublished (or removed) in the source but still published in the destination is unpublished on re-import — this propagates in both directions, so reverting a published ExO entity back to draft in the source and re-running the import will unpublish it in the destination too.
328
336
 
337
+ ### Optimization Variants
338
+
339
+ Experiences and Experience Fragments each support **Optimization Variants** — alternate personalization versions nested onto their parent (`experience.optimizationVariants` / `experienceFragment.optimizationVariants`), not a flat top-level array like the other six ExO entity types. A variant's `sys.id` is borrowed from its parent rather than being globally unique — see the export tool's own doc ([contentful-export's ExO doc](https://github.com/contentful/contentful-export/blob/main/docs/exo-export.md#optimization-variants)) for the full rationale.
340
+
341
+ Two behaviors are worth calling out explicitly because they differ from every other ExO entity type:
342
+
343
+ - **No ID preservation.** Every other ExO entity is created via upsert-with-known-ID. Variants can't be: the upstream API's create endpoint always server-generates a fresh ID, and its update endpoint 404s on an unknown ID instead of creating one. Every import run creates brand-new destination variants — re-running an import with variants in the source data creates additional variants rather than updating existing ones.
344
+ - **The API's synthetic "default" entry is filtered out.** The upstream list endpoint always leads with an entry representing the parent's own base view (`sys.variantType: 'default'`) — not a real variant. `contentful-export` already excludes it; `contentful-import` filters it again defensively for older export files.
345
+
329
346
  ### URN rewriting / backward compatibility
330
347
 
331
348
  - Export files taken before the ExO entity rename (`ComponentType` → `Component`, `Fragment` → `ExperienceFragment`, `Template` → `ExperienceTemplate`) are upgraded automatically on import, including the corresponding resource-link `linkType`s and URN path segments. This upgrade is upgrade-only (there's no downgrade path) and idempotent, so it's safe to run against already-upgraded data.
package/dist/index.d.mts CHANGED
@@ -21,6 +21,7 @@ type RunContentfulImportParams = {
21
21
  errorLogFile?: string;
22
22
  useVerboseRenderer?: boolean;
23
23
  includeExperienceOrchestration?: boolean;
24
+ skipExoVariants?: boolean;
24
25
  timeout?: number;
25
26
  retryLimit?: number;
26
27
  config?: string;
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ type RunContentfulImportParams = {
21
21
  errorLogFile?: string;
22
22
  useVerboseRenderer?: boolean;
23
23
  includeExperienceOrchestration?: boolean;
24
+ skipExoVariants?: boolean;
24
25
  timeout?: number;
25
26
  retryLimit?: number;
26
27
  config?: string;
package/dist/index.js CHANGED
@@ -263,7 +263,7 @@ var require_logging = __commonJS({
263
263
  throw new Error("Unable to extract API error data");
264
264
  }
265
265
  }
266
- function formatLogMessageOneLine(logMessage) {
266
+ function formatLogMessageOneLine2(logMessage) {
267
267
  const { level } = logMessage;
268
268
  if (!level) {
269
269
  return logMessage.toString().replace(/\s+/g, " ");
@@ -299,7 +299,7 @@ var require_logging = __commonJS({
299
299
  return logMessage.error.toString().replace(/\s+/g, " ");
300
300
  }
301
301
  }
302
- exports2.formatLogMessageOneLine = formatLogMessageOneLine;
302
+ exports2.formatLogMessageOneLine = formatLogMessageOneLine2;
303
303
  function formatLogMessageLogfile(logMessage) {
304
304
  const { level } = logMessage;
305
305
  if (level === "info" || level === "warning") {
@@ -338,7 +338,7 @@ var require_logging = __commonJS({
338
338
 
339
339
  The following ${count.errors} errors and ${count.warnings} warnings occurred:
340
340
  `);
341
- errorLog.map((logMessage) => `${(0, format_1.default)((0, parseISO_1.default)(logMessage.ts), "HH:mm:ss")} - ${formatLogMessageOneLine(logMessage)}`).map((logMessage) => console.log(logMessage));
341
+ errorLog.map((logMessage) => `${(0, format_1.default)((0, parseISO_1.default)(logMessage.ts), "HH:mm:ss")} - ${formatLogMessageOneLine2(logMessage)}`).map((logMessage) => console.log(logMessage));
342
342
  return;
343
343
  }
344
344
  console.log("No errors or warnings occurred");
@@ -385,7 +385,7 @@ The following ${count.errors} errors and ${count.warnings} warnings occurred:
385
385
  exports2.setupLogging = setupLogging2;
386
386
  function logToTaskOutput(task) {
387
387
  function logToTask(logMessage) {
388
- const content = formatLogMessageOneLine(logMessage);
388
+ const content = formatLogMessageOneLine2(logMessage);
389
389
  const symbols = {
390
390
  info: figures_1.default.tick,
391
391
  warning: figures_1.default.warning,
@@ -598,12 +598,12 @@ var require_common = __commonJS({
598
598
  args.unshift("%O");
599
599
  }
600
600
  let index = 0;
601
- args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format2) => {
601
+ args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format3) => {
602
602
  if (match === "%%") {
603
603
  return "%";
604
604
  }
605
605
  index++;
606
- const formatter = createDebug.formatters[format2];
606
+ const formatter = createDebug.formatters[format3];
607
607
  if (typeof formatter === "function") {
608
608
  const val = args[index];
609
609
  match = formatter.call(self2, val);
@@ -2047,7 +2047,7 @@ __export(index_exports, {
2047
2047
  });
2048
2048
  module.exports = __toCommonJS(index_exports);
2049
2049
  var import_cli_table3 = __toESM(require("cli-table3"));
2050
- var import_date_fns2 = require("date-fns");
2050
+ var import_date_fns3 = require("date-fns");
2051
2051
  var import_listr3 = __toESM(require("listr"));
2052
2052
  var import_listr_update_renderer = __toESM(require("listr-update-renderer"));
2053
2053
  var import_listr_verbose_renderer2 = __toESM(require("listr-verbose-renderer"));
@@ -4889,7 +4889,7 @@ var startCase_default = startCase;
4889
4889
 
4890
4890
  // lib/index.ts
4891
4891
  var import_p_queue = __toESM(require("p-queue"));
4892
- var import_logging12 = __toESM(require_logging());
4892
+ var import_logging13 = __toESM(require_logging());
4893
4893
  var import_listr4 = __toESM(require_listr());
4894
4894
 
4895
4895
  // lib/tasks/init-client.ts
@@ -4955,6 +4955,34 @@ async function unpublishExoEntity(type, entity, unpublish) {
4955
4955
  return null;
4956
4956
  }
4957
4957
  }
4958
+ function filterVariantsToPublish(variants) {
4959
+ return variants.filter((v) => v.sys.publishedVersion);
4960
+ }
4961
+ function filterVariantsToArchive(variants) {
4962
+ return variants.filter((v) => v.sys.archivedVersion && !v.sys.publishedVersion);
4963
+ }
4964
+ async function publishVariant(type, entity, publish) {
4965
+ try {
4966
+ const result = await publish();
4967
+ import_logging2.logEmitter.emit("info", `PUBLISH ${type} ${entity.sys.variant}`);
4968
+ return result;
4969
+ } catch (err) {
4970
+ err.entity = entity;
4971
+ import_logging2.logEmitter.emit("error", err);
4972
+ return null;
4973
+ }
4974
+ }
4975
+ async function archiveVariant(type, entity, archive) {
4976
+ try {
4977
+ const result = await archive();
4978
+ import_logging2.logEmitter.emit("info", `ARCHIVE ${type} ${entity.sys.variant}`);
4979
+ return result;
4980
+ } catch (err) {
4981
+ err.entity = entity;
4982
+ import_logging2.logEmitter.emit("error", err);
4983
+ return null;
4984
+ }
4985
+ }
4958
4986
  function isExoEntitlementError(err) {
4959
4987
  if (!(err instanceof Error)) {
4960
4988
  return false;
@@ -6165,6 +6193,7 @@ function pushToSpace({
6165
6193
  spaceId,
6166
6194
  environmentId,
6167
6195
  includeExperienceOrchestration,
6196
+ skipExoVariants,
6168
6197
  contentModelOnly,
6169
6198
  skipContentModel,
6170
6199
  skipContentUpdates,
@@ -6187,6 +6216,13 @@ function pushToSpace({
6187
6216
  ...DEFAULT_CONTENT_STRUCTURE,
6188
6217
  ...destinationData
6189
6218
  };
6219
+ const hasOptimizationVariants = [
6220
+ ...sourceData.experiences || [],
6221
+ ...sourceData.experienceFragments || []
6222
+ ].some((parent2) => (parent2.optimizationVariants || []).some(isRealOptimizationVariant));
6223
+ if (includeExperienceOrchestration && !skipExoVariants && hasOptimizationVariants) {
6224
+ import_logging11.logEmitter.emit("warning", "Optimization Variants are imported with new destination IDs and can be duplicated by re-imports. Set skipExoVariants to true to skip them.");
6225
+ }
6190
6226
  listrOptions = listrOptions || {
6191
6227
  renderer: import_listr_verbose_renderer.default
6192
6228
  };
@@ -6651,12 +6687,12 @@ function pushToSpace({
6651
6687
  try {
6652
6688
  const existing = destinationDataById.experienceFragments?.get(entity.sys.id);
6653
6689
  if (existing) {
6654
- const payload = { ...entity, sys: { id: entity.sys.id, type: "ExperienceFragment", version: existing.sys.version } };
6690
+ const payload = { ...omitSysAndOptimizationVariants(entity), sys: { id: entity.sys.id, type: "ExperienceFragment", version: existing.sys.version } };
6655
6691
  const result = await client.experienceFragment.upsert({ spaceId, environmentId, experienceFragmentId: entity.sys.id }, payload);
6656
6692
  import_logging11.logEmitter.emit("info", `UPDATE ExperienceFragment ${entity.sys.id}`);
6657
6693
  results.push(result);
6658
6694
  } else {
6659
- const payload = { ...omitSys(entity), component: entity.sys.component, sys: { id: entity.sys.id, type: "ExperienceFragment" } };
6695
+ const payload = { ...omitSysAndOptimizationVariants(entity), component: entity.sys.component, sys: { id: entity.sys.id, type: "ExperienceFragment" } };
6660
6696
  const result = await client.experienceFragment.upsert({ spaceId, environmentId, experienceFragmentId: entity.sys.id }, payload);
6661
6697
  import_logging11.logEmitter.emit("info", `CREATE ExperienceFragment ${entity.sys.id}`);
6662
6698
  results.push(result);
@@ -6693,12 +6729,12 @@ function pushToSpace({
6693
6729
  try {
6694
6730
  const existing = destinationDataById.experiences?.get(entity.sys.id);
6695
6731
  if (existing) {
6696
- const payload = { ...entity, sys: { id: entity.sys.id, type: "Experience", version: existing.sys.version } };
6732
+ const payload = { ...omitSysAndOptimizationVariants(entity), sys: { id: entity.sys.id, type: "Experience", version: existing.sys.version } };
6697
6733
  const result = await client.experience.upsert({ spaceId, environmentId, experienceId: entity.sys.id }, payload);
6698
6734
  import_logging11.logEmitter.emit("info", `UPDATE Experience ${entity.sys.id}`);
6699
6735
  return result;
6700
6736
  } else {
6701
- const payload = { ...omitSys(entity), experienceTemplate: entity.sys.experienceTemplate, sys: { id: entity.sys.id, type: "Experience" } };
6737
+ const payload = { ...omitSysAndOptimizationVariants(entity), experienceTemplate: entity.sys.experienceTemplate, sys: { id: entity.sys.id, type: "Experience" } };
6702
6738
  const result = await client.experience.upsert({ spaceId, environmentId, experienceId: entity.sys.id }, payload);
6703
6739
  import_logging11.logEmitter.emit("info", `CREATE Experience ${entity.sys.id}`);
6704
6740
  return result;
@@ -6726,6 +6762,85 @@ function pushToSpace({
6726
6762
  }),
6727
6763
  skip: () => !includeExperienceOrchestration || skipContentPublishing || !(sourceData.experiences || []).length
6728
6764
  },
6765
+ // Optimization Variants are sub-resources nested on their parent Experience/ExperienceFragment
6766
+ // (sourceData.experiences[].optimizationVariants), not a flat top-level array. A variant's
6767
+ // sys.id is borrowed from its parent, not unique, so variant creation/publish/archive is
6768
+ // handled by new, self-contained functions (importVariantsForParents, filterVariantsToPublish,
6769
+ // filterVariantsToArchive, publishVariant, archiveVariant) rather than by generalizing
6770
+ // destinationDataById / filterExoEntitiesToPublish / filterExoEntitiesToUnpublish, which all
6771
+ // assume sys.id uniqueness.
6772
+ //
6773
+ // Unlike the base Experience/Fragment create/update, there is no upsert-by-known-ID for
6774
+ // variants: the upstream API's create endpoint always server-generates a fresh variantId
6775
+ // (crypto.randomUUID()) and its update endpoint 404s on an unknown variantId rather than
6776
+ // creating one. So every import run creates fresh destination variants via POST rather than
6777
+ // matching against any existing destination variant.
6778
+ {
6779
+ title: "Importing Experience Optimization Variants",
6780
+ task: (0, import_listr2.wrapTask)(async (ctx) => {
6781
+ const results = await importVariantsForParents({
6782
+ parents: ctx.data.experiences || [],
6783
+ sourceParents: sourceData.experiences || [],
6784
+ client,
6785
+ spaceId,
6786
+ environmentId,
6787
+ kind: "experience"
6788
+ });
6789
+ ctx.data.experienceVariants = results.flatMap((r) => r.created);
6790
+ }),
6791
+ skip: () => !includeExperienceOrchestration || skipExoVariants || !(sourceData.experiences || []).some((e) => (e.optimizationVariants || []).some(isRealOptimizationVariant))
6792
+ },
6793
+ {
6794
+ title: "Publishing Experience Optimization Variants",
6795
+ task: (0, import_listr2.wrapTask)(async (ctx) => {
6796
+ const toPublish = filterVariantsToPublish(ctx.data.experienceVariants || []);
6797
+ await Promise.all(toPublish.map(
6798
+ (v) => publishVariant("ExperienceVariant", v, () => client.experienceVariant.publish(
6799
+ { spaceId, environmentId, experienceId: v.sys.id, variantId: v.sys.variant, version: v.sys.version }
6800
+ ))
6801
+ ));
6802
+ const toArchive = filterVariantsToArchive(ctx.data.experienceVariants || []);
6803
+ await Promise.all(toArchive.map(
6804
+ (v) => archiveVariant("ExperienceVariant", v, () => client.experienceVariant.archive(
6805
+ { spaceId, environmentId, experienceId: v.sys.id, variantId: v.sys.variant, version: v.sys.version }
6806
+ ))
6807
+ ));
6808
+ }),
6809
+ skip: () => !includeExperienceOrchestration || skipExoVariants || skipContentPublishing || !(sourceData.experiences || []).some((e) => (e.optimizationVariants || []).some(isRealOptimizationVariant))
6810
+ },
6811
+ {
6812
+ title: "Importing Experience Fragment Optimization Variants",
6813
+ task: (0, import_listr2.wrapTask)(async (ctx) => {
6814
+ const results = await importVariantsForParents({
6815
+ parents: ctx.data.experienceFragments || [],
6816
+ sourceParents: sourceData.experienceFragments || [],
6817
+ client,
6818
+ spaceId,
6819
+ environmentId,
6820
+ kind: "experienceFragment"
6821
+ });
6822
+ ctx.data.experienceFragmentVariants = results.flatMap((r) => r.created);
6823
+ }),
6824
+ skip: () => !includeExperienceOrchestration || skipExoVariants || !(sourceData.experienceFragments || []).some((f) => (f.optimizationVariants || []).some(isRealOptimizationVariant))
6825
+ },
6826
+ {
6827
+ title: "Publishing Experience Fragment Optimization Variants",
6828
+ task: (0, import_listr2.wrapTask)(async (ctx) => {
6829
+ const toPublish = filterVariantsToPublish(ctx.data.experienceFragmentVariants || []);
6830
+ await Promise.all(toPublish.map(
6831
+ (v) => publishVariant("ExperienceFragmentVariant", v, () => client.experienceFragmentVariant.publish(
6832
+ { spaceId, environmentId, experienceFragmentId: v.sys.id, variantId: v.sys.variant, version: v.sys.version }
6833
+ ))
6834
+ ));
6835
+ const toArchive = filterVariantsToArchive(ctx.data.experienceFragmentVariants || []);
6836
+ await Promise.all(toArchive.map(
6837
+ (v) => archiveVariant("ExperienceFragmentVariant", v, () => client.experienceFragmentVariant.archive(
6838
+ { spaceId, environmentId, experienceFragmentId: v.sys.id, variantId: v.sys.variant, version: v.sys.version }
6839
+ ))
6840
+ ));
6841
+ }),
6842
+ skip: () => !includeExperienceOrchestration || skipExoVariants || skipContentPublishing || !(sourceData.experienceFragments || []).some((f) => (f.optimizationVariants || []).some(isRealOptimizationVariant))
6843
+ },
6729
6844
  // Unpublishing runs after all Importing/Publishing tasks, in reverse dependency order
6730
6845
  // (Experience first, DataAssembly last) - the API rejects unpublishing an entity that a
6731
6846
  // still-published parent references, so parents must unpublish before the children they embed.
@@ -6797,6 +6912,48 @@ function omitSys(entity) {
6797
6912
  const { sys: _sys, ...rest } = entity;
6798
6913
  return rest;
6799
6914
  }
6915
+ function omitSysAndOptimizationVariants(entity) {
6916
+ const { sys: _sys, optimizationVariants: _variants, ...rest } = entity;
6917
+ return rest;
6918
+ }
6919
+ function omitVariantSys(variant) {
6920
+ const { sys: _sys, ...rest } = variant;
6921
+ return rest;
6922
+ }
6923
+ function isRealOptimizationVariant(variant) {
6924
+ return Boolean(variant?.sys) && variant.sys.variantType !== "default";
6925
+ }
6926
+ async function importVariantsForParents({
6927
+ parents,
6928
+ sourceParents,
6929
+ client,
6930
+ spaceId,
6931
+ environmentId,
6932
+ kind
6933
+ }) {
6934
+ const ns = kind === "experience" ? client.experienceVariant : client.experienceFragmentVariant;
6935
+ const idParam = kind === "experience" ? "experienceId" : "experienceFragmentId";
6936
+ const label = kind === "experience" ? "ExperienceVariant" : "ExperienceFragmentVariant";
6937
+ const parentRefField = kind === "experience" ? "experienceTemplate" : "component";
6938
+ const sourceParentsById = new Map(sourceParents.map((sourceParent) => [sourceParent.sys.id, sourceParent]));
6939
+ return Promise.all(parents.map(async (parent2) => {
6940
+ const sourceParent = sourceParentsById.get(parent2.sys.id);
6941
+ const sourceVariants = (sourceParent?.optimizationVariants ?? []).filter(isRealOptimizationVariant);
6942
+ const created = [];
6943
+ for (const variant of sourceVariants) {
6944
+ try {
6945
+ const payload = { ...omitVariantSys(variant), [parentRefField]: variant.sys[parentRefField] };
6946
+ const result = await ns.create({ spaceId, environmentId, [idParam]: parent2.sys.id }, payload);
6947
+ import_logging11.logEmitter.emit("info", `CREATE ${label} ${result.sys.variant} (parent ${parent2.sys.id})`);
6948
+ created.push({ ...result, sys: { ...result.sys, publishedVersion: variant.sys.publishedVersion, archivedVersion: variant.sys.archivedVersion } });
6949
+ } catch (err) {
6950
+ err.entity = variant;
6951
+ import_logging11.logEmitter.emit("error", err);
6952
+ }
6953
+ }
6954
+ return { parentId: parent2.sys.id, created };
6955
+ }));
6956
+ }
6800
6957
  function archiveEntities2({ entities, sourceEntities, client, spaceId, environmentId, requestQueue }) {
6801
6958
  const entityIdsToArchive = sourceEntities.filter(({ original }) => original.sys.archivedVersion).map(({ original }) => original.sys.id);
6802
6959
  const entitiesToArchive = entities.filter((entity) => entityIdsToArchive.indexOf(entity.sys.id) !== -1);
@@ -7385,6 +7542,7 @@ async function parseOptions(params) {
7385
7542
  uploadAssets: false,
7386
7543
  rateLimit: 7,
7387
7544
  includeExperienceOrchestration: true,
7545
+ skipExoVariants: false,
7388
7546
  host: "api.contentful.com"
7389
7547
  };
7390
7548
  const configFile = params.config ? require((0, import_path2.resolve)(process.cwd(), params.config)) : {};
@@ -7459,6 +7617,29 @@ async function parseOptions(params) {
7459
7617
  return options;
7460
7618
  }
7461
7619
 
7620
+ // lib/utils/display-error-log.ts
7621
+ var import_date_fns2 = require("date-fns");
7622
+ var import_logging12 = __toESM(require_logging());
7623
+ function displayErrorLog(errorLog) {
7624
+ if (errorLog.length) {
7625
+ const count = errorLog.reduce((count2, curr) => {
7626
+ if (Object.prototype.hasOwnProperty.call(curr, "warning")) {
7627
+ count2.warnings++;
7628
+ } else if (Object.prototype.hasOwnProperty.call(curr, "error")) {
7629
+ count2.errors++;
7630
+ }
7631
+ return count2;
7632
+ }, { warnings: 0, errors: 0 });
7633
+ console.log(`
7634
+
7635
+ The following ${count.errors} errors and ${count.warnings} warnings occurred:
7636
+ `);
7637
+ errorLog.map((logMessage) => `${(0, import_date_fns2.format)((0, import_date_fns2.parseISO)(logMessage.ts), "HH:mm:ss")} - ${(0, import_logging12.formatLogMessageOneLine)(logMessage)}`).map((logMessage) => console.log(logMessage));
7638
+ return;
7639
+ }
7640
+ console.log("No errors or warnings occurred");
7641
+ }
7642
+
7462
7643
  // lib/index.ts
7463
7644
  var ONE_SECOND = 1e3;
7464
7645
  var tableOptions = {
@@ -7485,7 +7666,7 @@ async function runContentfulImport(params) {
7485
7666
  intervalCap: options.rateLimit,
7486
7667
  carryoverConcurrencyCount: true
7487
7668
  });
7488
- (0, import_logging12.setupLogging)(log);
7669
+ (0, import_logging13.setupLogging)(log);
7489
7670
  const infoTable = new import_cli_table3.default(tableOptions);
7490
7671
  infoTable.push([{ colSpan: 2, content: "The following entities are going to be imported:" }]);
7491
7672
  Object.keys(options.content).forEach((type) => {
@@ -7500,6 +7681,20 @@ async function runContentfulImport(params) {
7500
7681
  }
7501
7682
  infoTable.push([startCase_default(type), options.content[type].length]);
7502
7683
  });
7684
+ const experienceVariantCount = (options.content.experiences || []).reduce(
7685
+ (sum, e) => sum + (e.optimizationVariants?.length ?? 0),
7686
+ 0
7687
+ );
7688
+ if (!options.skipExoVariants && experienceVariantCount > 0) {
7689
+ infoTable.push(["Experience Optimization Variants", experienceVariantCount]);
7690
+ }
7691
+ const experienceFragmentVariantCount = (options.content.experienceFragments || []).reduce(
7692
+ (sum, f) => sum + (f.optimizationVariants?.length ?? 0),
7693
+ 0
7694
+ );
7695
+ if (!options.skipExoVariants && experienceFragmentVariantCount > 0) {
7696
+ infoTable.push(["Experience Fragment Optimization Variants", experienceFragmentVariantCount]);
7697
+ }
7503
7698
  console.log(infoTable.toString());
7504
7699
  const tasks = new import_listr3.default([
7505
7700
  {
@@ -7548,6 +7743,7 @@ async function runContentfulImport(params) {
7548
7743
  client: ctx.client,
7549
7744
  spaceId: options.spaceId,
7550
7745
  includeExperienceOrchestration: options.includeExperienceOrchestration,
7746
+ skipExoVariants: options.skipExoVariants,
7551
7747
  environmentId: options.environmentId,
7552
7748
  contentModelOnly: options.contentModelOnly,
7553
7749
  skipLocales: options.skipLocales,
@@ -7582,8 +7778,8 @@ async function runContentfulImport(params) {
7582
7778
  console.log("No data was imported");
7583
7779
  }
7584
7780
  const endTime = /* @__PURE__ */ new Date();
7585
- const durationHuman = (0, import_date_fns2.formatDistance)(endTime, options.startTime);
7586
- const durationSeconds = (0, import_date_fns2.differenceInSeconds)(endTime, options.startTime);
7781
+ const durationHuman = (0, import_date_fns3.formatDistance)(endTime, options.startTime);
7782
+ const durationSeconds = (0, import_date_fns3.differenceInSeconds)(endTime, options.startTime);
7587
7783
  console.log(`The import took ${durationHuman} (${durationSeconds}s)`);
7588
7784
  return ctx.data;
7589
7785
  }).catch((err) => {
@@ -7595,9 +7791,9 @@ async function runContentfulImport(params) {
7595
7791
  }).then((data) => {
7596
7792
  const errorLog = log.filter((logMessage) => logMessage.level !== "info" && logMessage.level !== "warning");
7597
7793
  const displayLog = log.filter((logMessage) => logMessage.level !== "info");
7598
- (0, import_logging12.displayErrorLog)(displayLog);
7794
+ displayErrorLog(displayLog);
7599
7795
  if (errorLog.length) {
7600
- return (0, import_logging12.writeErrorLogFile)(options.errorLogFile, errorLog).then(() => {
7796
+ return (0, import_logging13.writeErrorLogFile)(options.errorLogFile, errorLog).then(() => {
7601
7797
  const multiError = new ContentfulMultiError("Errors occurred");
7602
7798
  multiError.name = "ContentfulMultiError";
7603
7799
  multiError.errors = errorLog;
package/dist/index.mjs CHANGED
@@ -235,7 +235,7 @@ var require_logging = __commonJS({
235
235
  throw new Error("Unable to extract API error data");
236
236
  }
237
237
  }
238
- function formatLogMessageOneLine(logMessage) {
238
+ function formatLogMessageOneLine2(logMessage) {
239
239
  const { level } = logMessage;
240
240
  if (!level) {
241
241
  return logMessage.toString().replace(/\s+/g, " ");
@@ -271,7 +271,7 @@ var require_logging = __commonJS({
271
271
  return logMessage.error.toString().replace(/\s+/g, " ");
272
272
  }
273
273
  }
274
- exports2.formatLogMessageOneLine = formatLogMessageOneLine;
274
+ exports2.formatLogMessageOneLine = formatLogMessageOneLine2;
275
275
  function formatLogMessageLogfile(logMessage) {
276
276
  const { level } = logMessage;
277
277
  if (level === "info" || level === "warning") {
@@ -310,7 +310,7 @@ var require_logging = __commonJS({
310
310
 
311
311
  The following ${count.errors} errors and ${count.warnings} warnings occurred:
312
312
  `);
313
- errorLog.map((logMessage) => `${(0, format_1.default)((0, parseISO_1.default)(logMessage.ts), "HH:mm:ss")} - ${formatLogMessageOneLine(logMessage)}`).map((logMessage) => console.log(logMessage));
313
+ errorLog.map((logMessage) => `${(0, format_1.default)((0, parseISO_1.default)(logMessage.ts), "HH:mm:ss")} - ${formatLogMessageOneLine2(logMessage)}`).map((logMessage) => console.log(logMessage));
314
314
  return;
315
315
  }
316
316
  console.log("No errors or warnings occurred");
@@ -357,7 +357,7 @@ The following ${count.errors} errors and ${count.warnings} warnings occurred:
357
357
  exports2.setupLogging = setupLogging2;
358
358
  function logToTaskOutput(task) {
359
359
  function logToTask(logMessage) {
360
- const content = formatLogMessageOneLine(logMessage);
360
+ const content = formatLogMessageOneLine2(logMessage);
361
361
  const symbols = {
362
362
  info: figures_1.default.tick,
363
363
  warning: figures_1.default.warning,
@@ -570,12 +570,12 @@ var require_common = __commonJS({
570
570
  args.unshift("%O");
571
571
  }
572
572
  let index = 0;
573
- args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format2) => {
573
+ args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format3) => {
574
574
  if (match === "%%") {
575
575
  return "%";
576
576
  }
577
577
  index++;
578
- const formatter = createDebug.formatters[format2];
578
+ const formatter = createDebug.formatters[format3];
579
579
  if (typeof formatter === "function") {
580
580
  const val = args[index];
581
581
  match = formatter.call(self2, val);
@@ -4855,7 +4855,7 @@ var startCase = createCompounder_default(function(result, word, index) {
4855
4855
  var startCase_default = startCase;
4856
4856
 
4857
4857
  // lib/index.ts
4858
- var import_logging12 = __toESM(require_logging());
4858
+ var import_logging13 = __toESM(require_logging());
4859
4859
  var import_listr4 = __toESM(require_listr());
4860
4860
  import PQueue from "p-queue";
4861
4861
 
@@ -4922,6 +4922,34 @@ async function unpublishExoEntity(type, entity, unpublish) {
4922
4922
  return null;
4923
4923
  }
4924
4924
  }
4925
+ function filterVariantsToPublish(variants) {
4926
+ return variants.filter((v) => v.sys.publishedVersion);
4927
+ }
4928
+ function filterVariantsToArchive(variants) {
4929
+ return variants.filter((v) => v.sys.archivedVersion && !v.sys.publishedVersion);
4930
+ }
4931
+ async function publishVariant(type, entity, publish) {
4932
+ try {
4933
+ const result = await publish();
4934
+ import_logging2.logEmitter.emit("info", `PUBLISH ${type} ${entity.sys.variant}`);
4935
+ return result;
4936
+ } catch (err) {
4937
+ err.entity = entity;
4938
+ import_logging2.logEmitter.emit("error", err);
4939
+ return null;
4940
+ }
4941
+ }
4942
+ async function archiveVariant(type, entity, archive) {
4943
+ try {
4944
+ const result = await archive();
4945
+ import_logging2.logEmitter.emit("info", `ARCHIVE ${type} ${entity.sys.variant}`);
4946
+ return result;
4947
+ } catch (err) {
4948
+ err.entity = entity;
4949
+ import_logging2.logEmitter.emit("error", err);
4950
+ return null;
4951
+ }
4952
+ }
4925
4953
  function isExoEntitlementError(err) {
4926
4954
  if (!(err instanceof Error)) {
4927
4955
  return false;
@@ -6132,6 +6160,7 @@ function pushToSpace({
6132
6160
  spaceId,
6133
6161
  environmentId,
6134
6162
  includeExperienceOrchestration,
6163
+ skipExoVariants,
6135
6164
  contentModelOnly,
6136
6165
  skipContentModel,
6137
6166
  skipContentUpdates,
@@ -6154,6 +6183,13 @@ function pushToSpace({
6154
6183
  ...DEFAULT_CONTENT_STRUCTURE,
6155
6184
  ...destinationData
6156
6185
  };
6186
+ const hasOptimizationVariants = [
6187
+ ...sourceData.experiences || [],
6188
+ ...sourceData.experienceFragments || []
6189
+ ].some((parent2) => (parent2.optimizationVariants || []).some(isRealOptimizationVariant));
6190
+ if (includeExperienceOrchestration && !skipExoVariants && hasOptimizationVariants) {
6191
+ import_logging11.logEmitter.emit("warning", "Optimization Variants are imported with new destination IDs and can be duplicated by re-imports. Set skipExoVariants to true to skip them.");
6192
+ }
6157
6193
  listrOptions = listrOptions || {
6158
6194
  renderer: verboseRenderer
6159
6195
  };
@@ -6618,12 +6654,12 @@ function pushToSpace({
6618
6654
  try {
6619
6655
  const existing = destinationDataById.experienceFragments?.get(entity.sys.id);
6620
6656
  if (existing) {
6621
- const payload = { ...entity, sys: { id: entity.sys.id, type: "ExperienceFragment", version: existing.sys.version } };
6657
+ const payload = { ...omitSysAndOptimizationVariants(entity), sys: { id: entity.sys.id, type: "ExperienceFragment", version: existing.sys.version } };
6622
6658
  const result = await client.experienceFragment.upsert({ spaceId, environmentId, experienceFragmentId: entity.sys.id }, payload);
6623
6659
  import_logging11.logEmitter.emit("info", `UPDATE ExperienceFragment ${entity.sys.id}`);
6624
6660
  results.push(result);
6625
6661
  } else {
6626
- const payload = { ...omitSys(entity), component: entity.sys.component, sys: { id: entity.sys.id, type: "ExperienceFragment" } };
6662
+ const payload = { ...omitSysAndOptimizationVariants(entity), component: entity.sys.component, sys: { id: entity.sys.id, type: "ExperienceFragment" } };
6627
6663
  const result = await client.experienceFragment.upsert({ spaceId, environmentId, experienceFragmentId: entity.sys.id }, payload);
6628
6664
  import_logging11.logEmitter.emit("info", `CREATE ExperienceFragment ${entity.sys.id}`);
6629
6665
  results.push(result);
@@ -6660,12 +6696,12 @@ function pushToSpace({
6660
6696
  try {
6661
6697
  const existing = destinationDataById.experiences?.get(entity.sys.id);
6662
6698
  if (existing) {
6663
- const payload = { ...entity, sys: { id: entity.sys.id, type: "Experience", version: existing.sys.version } };
6699
+ const payload = { ...omitSysAndOptimizationVariants(entity), sys: { id: entity.sys.id, type: "Experience", version: existing.sys.version } };
6664
6700
  const result = await client.experience.upsert({ spaceId, environmentId, experienceId: entity.sys.id }, payload);
6665
6701
  import_logging11.logEmitter.emit("info", `UPDATE Experience ${entity.sys.id}`);
6666
6702
  return result;
6667
6703
  } else {
6668
- const payload = { ...omitSys(entity), experienceTemplate: entity.sys.experienceTemplate, sys: { id: entity.sys.id, type: "Experience" } };
6704
+ const payload = { ...omitSysAndOptimizationVariants(entity), experienceTemplate: entity.sys.experienceTemplate, sys: { id: entity.sys.id, type: "Experience" } };
6669
6705
  const result = await client.experience.upsert({ spaceId, environmentId, experienceId: entity.sys.id }, payload);
6670
6706
  import_logging11.logEmitter.emit("info", `CREATE Experience ${entity.sys.id}`);
6671
6707
  return result;
@@ -6693,6 +6729,85 @@ function pushToSpace({
6693
6729
  }),
6694
6730
  skip: () => !includeExperienceOrchestration || skipContentPublishing || !(sourceData.experiences || []).length
6695
6731
  },
6732
+ // Optimization Variants are sub-resources nested on their parent Experience/ExperienceFragment
6733
+ // (sourceData.experiences[].optimizationVariants), not a flat top-level array. A variant's
6734
+ // sys.id is borrowed from its parent, not unique, so variant creation/publish/archive is
6735
+ // handled by new, self-contained functions (importVariantsForParents, filterVariantsToPublish,
6736
+ // filterVariantsToArchive, publishVariant, archiveVariant) rather than by generalizing
6737
+ // destinationDataById / filterExoEntitiesToPublish / filterExoEntitiesToUnpublish, which all
6738
+ // assume sys.id uniqueness.
6739
+ //
6740
+ // Unlike the base Experience/Fragment create/update, there is no upsert-by-known-ID for
6741
+ // variants: the upstream API's create endpoint always server-generates a fresh variantId
6742
+ // (crypto.randomUUID()) and its update endpoint 404s on an unknown variantId rather than
6743
+ // creating one. So every import run creates fresh destination variants via POST rather than
6744
+ // matching against any existing destination variant.
6745
+ {
6746
+ title: "Importing Experience Optimization Variants",
6747
+ task: (0, import_listr2.wrapTask)(async (ctx) => {
6748
+ const results = await importVariantsForParents({
6749
+ parents: ctx.data.experiences || [],
6750
+ sourceParents: sourceData.experiences || [],
6751
+ client,
6752
+ spaceId,
6753
+ environmentId,
6754
+ kind: "experience"
6755
+ });
6756
+ ctx.data.experienceVariants = results.flatMap((r) => r.created);
6757
+ }),
6758
+ skip: () => !includeExperienceOrchestration || skipExoVariants || !(sourceData.experiences || []).some((e) => (e.optimizationVariants || []).some(isRealOptimizationVariant))
6759
+ },
6760
+ {
6761
+ title: "Publishing Experience Optimization Variants",
6762
+ task: (0, import_listr2.wrapTask)(async (ctx) => {
6763
+ const toPublish = filterVariantsToPublish(ctx.data.experienceVariants || []);
6764
+ await Promise.all(toPublish.map(
6765
+ (v) => publishVariant("ExperienceVariant", v, () => client.experienceVariant.publish(
6766
+ { spaceId, environmentId, experienceId: v.sys.id, variantId: v.sys.variant, version: v.sys.version }
6767
+ ))
6768
+ ));
6769
+ const toArchive = filterVariantsToArchive(ctx.data.experienceVariants || []);
6770
+ await Promise.all(toArchive.map(
6771
+ (v) => archiveVariant("ExperienceVariant", v, () => client.experienceVariant.archive(
6772
+ { spaceId, environmentId, experienceId: v.sys.id, variantId: v.sys.variant, version: v.sys.version }
6773
+ ))
6774
+ ));
6775
+ }),
6776
+ skip: () => !includeExperienceOrchestration || skipExoVariants || skipContentPublishing || !(sourceData.experiences || []).some((e) => (e.optimizationVariants || []).some(isRealOptimizationVariant))
6777
+ },
6778
+ {
6779
+ title: "Importing Experience Fragment Optimization Variants",
6780
+ task: (0, import_listr2.wrapTask)(async (ctx) => {
6781
+ const results = await importVariantsForParents({
6782
+ parents: ctx.data.experienceFragments || [],
6783
+ sourceParents: sourceData.experienceFragments || [],
6784
+ client,
6785
+ spaceId,
6786
+ environmentId,
6787
+ kind: "experienceFragment"
6788
+ });
6789
+ ctx.data.experienceFragmentVariants = results.flatMap((r) => r.created);
6790
+ }),
6791
+ skip: () => !includeExperienceOrchestration || skipExoVariants || !(sourceData.experienceFragments || []).some((f) => (f.optimizationVariants || []).some(isRealOptimizationVariant))
6792
+ },
6793
+ {
6794
+ title: "Publishing Experience Fragment Optimization Variants",
6795
+ task: (0, import_listr2.wrapTask)(async (ctx) => {
6796
+ const toPublish = filterVariantsToPublish(ctx.data.experienceFragmentVariants || []);
6797
+ await Promise.all(toPublish.map(
6798
+ (v) => publishVariant("ExperienceFragmentVariant", v, () => client.experienceFragmentVariant.publish(
6799
+ { spaceId, environmentId, experienceFragmentId: v.sys.id, variantId: v.sys.variant, version: v.sys.version }
6800
+ ))
6801
+ ));
6802
+ const toArchive = filterVariantsToArchive(ctx.data.experienceFragmentVariants || []);
6803
+ await Promise.all(toArchive.map(
6804
+ (v) => archiveVariant("ExperienceFragmentVariant", v, () => client.experienceFragmentVariant.archive(
6805
+ { spaceId, environmentId, experienceFragmentId: v.sys.id, variantId: v.sys.variant, version: v.sys.version }
6806
+ ))
6807
+ ));
6808
+ }),
6809
+ skip: () => !includeExperienceOrchestration || skipExoVariants || skipContentPublishing || !(sourceData.experienceFragments || []).some((f) => (f.optimizationVariants || []).some(isRealOptimizationVariant))
6810
+ },
6696
6811
  // Unpublishing runs after all Importing/Publishing tasks, in reverse dependency order
6697
6812
  // (Experience first, DataAssembly last) - the API rejects unpublishing an entity that a
6698
6813
  // still-published parent references, so parents must unpublish before the children they embed.
@@ -6764,6 +6879,48 @@ function omitSys(entity) {
6764
6879
  const { sys: _sys, ...rest } = entity;
6765
6880
  return rest;
6766
6881
  }
6882
+ function omitSysAndOptimizationVariants(entity) {
6883
+ const { sys: _sys, optimizationVariants: _variants, ...rest } = entity;
6884
+ return rest;
6885
+ }
6886
+ function omitVariantSys(variant) {
6887
+ const { sys: _sys, ...rest } = variant;
6888
+ return rest;
6889
+ }
6890
+ function isRealOptimizationVariant(variant) {
6891
+ return Boolean(variant?.sys) && variant.sys.variantType !== "default";
6892
+ }
6893
+ async function importVariantsForParents({
6894
+ parents,
6895
+ sourceParents,
6896
+ client,
6897
+ spaceId,
6898
+ environmentId,
6899
+ kind
6900
+ }) {
6901
+ const ns = kind === "experience" ? client.experienceVariant : client.experienceFragmentVariant;
6902
+ const idParam = kind === "experience" ? "experienceId" : "experienceFragmentId";
6903
+ const label = kind === "experience" ? "ExperienceVariant" : "ExperienceFragmentVariant";
6904
+ const parentRefField = kind === "experience" ? "experienceTemplate" : "component";
6905
+ const sourceParentsById = new Map(sourceParents.map((sourceParent) => [sourceParent.sys.id, sourceParent]));
6906
+ return Promise.all(parents.map(async (parent2) => {
6907
+ const sourceParent = sourceParentsById.get(parent2.sys.id);
6908
+ const sourceVariants = (sourceParent?.optimizationVariants ?? []).filter(isRealOptimizationVariant);
6909
+ const created = [];
6910
+ for (const variant of sourceVariants) {
6911
+ try {
6912
+ const payload = { ...omitVariantSys(variant), [parentRefField]: variant.sys[parentRefField] };
6913
+ const result = await ns.create({ spaceId, environmentId, [idParam]: parent2.sys.id }, payload);
6914
+ import_logging11.logEmitter.emit("info", `CREATE ${label} ${result.sys.variant} (parent ${parent2.sys.id})`);
6915
+ created.push({ ...result, sys: { ...result.sys, publishedVersion: variant.sys.publishedVersion, archivedVersion: variant.sys.archivedVersion } });
6916
+ } catch (err) {
6917
+ err.entity = variant;
6918
+ import_logging11.logEmitter.emit("error", err);
6919
+ }
6920
+ }
6921
+ return { parentId: parent2.sys.id, created };
6922
+ }));
6923
+ }
6767
6924
  function archiveEntities2({ entities, sourceEntities, client, spaceId, environmentId, requestQueue }) {
6768
6925
  const entityIdsToArchive = sourceEntities.filter(({ original }) => original.sys.archivedVersion).map(({ original }) => original.sys.id);
6769
6926
  const entitiesToArchive = entities.filter((entity) => entityIdsToArchive.indexOf(entity.sys.id) !== -1);
@@ -7349,6 +7506,7 @@ async function parseOptions(params) {
7349
7506
  uploadAssets: false,
7350
7507
  rateLimit: 7,
7351
7508
  includeExperienceOrchestration: true,
7509
+ skipExoVariants: false,
7352
7510
  host: "api.contentful.com"
7353
7511
  };
7354
7512
  const configFile = params.config ? __require(resolve(process.cwd(), params.config)) : {};
@@ -7423,6 +7581,29 @@ async function parseOptions(params) {
7423
7581
  return options;
7424
7582
  }
7425
7583
 
7584
+ // lib/utils/display-error-log.ts
7585
+ var import_logging12 = __toESM(require_logging());
7586
+ import { format as format2, parseISO } from "date-fns";
7587
+ function displayErrorLog(errorLog) {
7588
+ if (errorLog.length) {
7589
+ const count = errorLog.reduce((count2, curr) => {
7590
+ if (Object.prototype.hasOwnProperty.call(curr, "warning")) {
7591
+ count2.warnings++;
7592
+ } else if (Object.prototype.hasOwnProperty.call(curr, "error")) {
7593
+ count2.errors++;
7594
+ }
7595
+ return count2;
7596
+ }, { warnings: 0, errors: 0 });
7597
+ console.log(`
7598
+
7599
+ The following ${count.errors} errors and ${count.warnings} warnings occurred:
7600
+ `);
7601
+ errorLog.map((logMessage) => `${format2(parseISO(logMessage.ts), "HH:mm:ss")} - ${(0, import_logging12.formatLogMessageOneLine)(logMessage)}`).map((logMessage) => console.log(logMessage));
7602
+ return;
7603
+ }
7604
+ console.log("No errors or warnings occurred");
7605
+ }
7606
+
7426
7607
  // lib/index.ts
7427
7608
  var ONE_SECOND = 1e3;
7428
7609
  var tableOptions = {
@@ -7449,7 +7630,7 @@ async function runContentfulImport(params) {
7449
7630
  intervalCap: options.rateLimit,
7450
7631
  carryoverConcurrencyCount: true
7451
7632
  });
7452
- (0, import_logging12.setupLogging)(log);
7633
+ (0, import_logging13.setupLogging)(log);
7453
7634
  const infoTable = new Table(tableOptions);
7454
7635
  infoTable.push([{ colSpan: 2, content: "The following entities are going to be imported:" }]);
7455
7636
  Object.keys(options.content).forEach((type) => {
@@ -7464,6 +7645,20 @@ async function runContentfulImport(params) {
7464
7645
  }
7465
7646
  infoTable.push([startCase_default(type), options.content[type].length]);
7466
7647
  });
7648
+ const experienceVariantCount = (options.content.experiences || []).reduce(
7649
+ (sum, e) => sum + (e.optimizationVariants?.length ?? 0),
7650
+ 0
7651
+ );
7652
+ if (!options.skipExoVariants && experienceVariantCount > 0) {
7653
+ infoTable.push(["Experience Optimization Variants", experienceVariantCount]);
7654
+ }
7655
+ const experienceFragmentVariantCount = (options.content.experienceFragments || []).reduce(
7656
+ (sum, f) => sum + (f.optimizationVariants?.length ?? 0),
7657
+ 0
7658
+ );
7659
+ if (!options.skipExoVariants && experienceFragmentVariantCount > 0) {
7660
+ infoTable.push(["Experience Fragment Optimization Variants", experienceFragmentVariantCount]);
7661
+ }
7467
7662
  console.log(infoTable.toString());
7468
7663
  const tasks = new Listr2([
7469
7664
  {
@@ -7512,6 +7707,7 @@ async function runContentfulImport(params) {
7512
7707
  client: ctx.client,
7513
7708
  spaceId: options.spaceId,
7514
7709
  includeExperienceOrchestration: options.includeExperienceOrchestration,
7710
+ skipExoVariants: options.skipExoVariants,
7515
7711
  environmentId: options.environmentId,
7516
7712
  contentModelOnly: options.contentModelOnly,
7517
7713
  skipLocales: options.skipLocales,
@@ -7559,9 +7755,9 @@ async function runContentfulImport(params) {
7559
7755
  }).then((data) => {
7560
7756
  const errorLog = log.filter((logMessage) => logMessage.level !== "info" && logMessage.level !== "warning");
7561
7757
  const displayLog = log.filter((logMessage) => logMessage.level !== "info");
7562
- (0, import_logging12.displayErrorLog)(displayLog);
7758
+ displayErrorLog(displayLog);
7563
7759
  if (errorLog.length) {
7564
- return (0, import_logging12.writeErrorLogFile)(options.errorLogFile, errorLog).then(() => {
7760
+ return (0, import_logging13.writeErrorLogFile)(options.errorLogFile, errorLog).then(() => {
7565
7761
  const multiError = new ContentfulMultiError("Errors occurred");
7566
7762
  multiError.name = "ContentfulMultiError";
7567
7763
  multiError.errors = errorLog;
@@ -36,6 +36,8 @@ declare const _default: {
36
36
  header: string | undefined;
37
37
  "include-experience-orchestration": boolean;
38
38
  includeExperienceOrchestration: boolean;
39
+ "skip-exo-variants": boolean;
40
+ skipExoVariants: boolean;
39
41
  _: (string | number)[];
40
42
  $0: string;
41
43
  } | Promise<{
@@ -76,6 +78,8 @@ declare const _default: {
76
78
  header: string | undefined;
77
79
  "include-experience-orchestration": boolean;
78
80
  includeExperienceOrchestration: boolean;
81
+ "skip-exo-variants": boolean;
82
+ skipExoVariants: boolean;
79
83
  _: (string | number)[];
80
84
  $0: string;
81
85
  }>;
@@ -36,6 +36,8 @@ declare const _default: {
36
36
  header: string | undefined;
37
37
  "include-experience-orchestration": boolean;
38
38
  includeExperienceOrchestration: boolean;
39
+ "skip-exo-variants": boolean;
40
+ skipExoVariants: boolean;
39
41
  _: (string | number)[];
40
42
  $0: string;
41
43
  } | Promise<{
@@ -76,6 +78,8 @@ declare const _default: {
76
78
  header: string | undefined;
77
79
  "include-experience-orchestration": boolean;
78
80
  includeExperienceOrchestration: boolean;
81
+ "skip-exo-variants": boolean;
82
+ skipExoVariants: boolean;
79
83
  _: (string | number)[];
80
84
  $0: string;
81
85
  }>;
@@ -118,5 +118,9 @@ var usageParams_default = import_yargs.default.version(version || "Version only
118
118
  describe: "Import Experience Orchestration entities (designTokens, components, experienceTemplates, experienceFragments, dataAssemblies, experiences). Requires a space with ExO enabled.",
119
119
  type: "boolean",
120
120
  default: true
121
+ }).option("skip-exo-variants", {
122
+ describe: "Skip importing Experience and Experience Fragment Optimization Variants",
123
+ type: "boolean",
124
+ default: false
121
125
  }).config("config", "An optional configuration JSON file containing all the options for a single run").argv;
122
126
  module.exports = module.exports.default || module.exports;
@@ -80,6 +80,10 @@ var usageParams_default = yargs.version(version || "Version only available on in
80
80
  describe: "Import Experience Orchestration entities (designTokens, components, experienceTemplates, experienceFragments, dataAssemblies, experiences). Requires a space with ExO enabled.",
81
81
  type: "boolean",
82
82
  default: true
83
+ }).option("skip-exo-variants", {
84
+ describe: "Skip importing Experience and Experience Fragment Optimization Variants",
85
+ type: "boolean",
86
+ default: false
83
87
  }).config("config", "An optional configuration JSON file containing all the options for a single run").argv;
84
88
  export {
85
89
  usageParams_default as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contentful-import",
3
- "version": "10.3.0",
3
+ "version": "10.4.0",
4
4
  "description": "this tool allows you to import JSON dump exported by contentful-export",
5
5
  "main": "dist/index.mjs",
6
6
  "typings": "dist/index.d.ts",
@@ -64,7 +64,7 @@
64
64
  "bluebird": "^3.7.2",
65
65
  "cli-table3": "^0.6.5",
66
66
  "contentful-batch-libs": "^9.7.0",
67
- "contentful-management": "^12.13.0",
67
+ "contentful-management": "^12.17.0",
68
68
  "date-fns": "^4.4.0",
69
69
  "joi": "^18.2.3",
70
70
  "listr": "^0.14.3",