contentful-import 10.2.3 → 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 +32 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +514 -89
- package/dist/index.mjs +511 -86
- package/dist/usageParams.d.mts +8 -0
- package/dist/usageParams.d.ts +8 -0
- package/dist/usageParams.js +8 -0
- package/dist/usageParams.mjs +8 -0
- package/package.json +2 -2
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
|
|
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 =
|
|
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")} - ${
|
|
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 =
|
|
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,
|
|
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[
|
|
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);
|
|
@@ -2280,8 +2280,8 @@ function getNative(object, key) {
|
|
|
2280
2280
|
var getNative_default = getNative;
|
|
2281
2281
|
|
|
2282
2282
|
// node_modules/lodash-es/_WeakMap.js
|
|
2283
|
-
var
|
|
2284
|
-
var WeakMap_default =
|
|
2283
|
+
var WeakMap2 = getNative_default(root_default, "WeakMap");
|
|
2284
|
+
var WeakMap_default = WeakMap2;
|
|
2285
2285
|
|
|
2286
2286
|
// node_modules/lodash-es/_baseCreate.js
|
|
2287
2287
|
var objectCreate = Object.create;
|
|
@@ -3007,12 +3007,12 @@ function memoize(func, resolver) {
|
|
|
3007
3007
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
3008
3008
|
}
|
|
3009
3009
|
var memoized = function() {
|
|
3010
|
-
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0],
|
|
3011
|
-
if (
|
|
3012
|
-
return
|
|
3010
|
+
var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache2 = memoized.cache;
|
|
3011
|
+
if (cache2.has(key)) {
|
|
3012
|
+
return cache2.get(key);
|
|
3013
3013
|
}
|
|
3014
3014
|
var result = func.apply(this, args);
|
|
3015
|
-
memoized.cache =
|
|
3015
|
+
memoized.cache = cache2.set(key, result) || cache2;
|
|
3016
3016
|
return result;
|
|
3017
3017
|
};
|
|
3018
3018
|
memoized.cache = new (memoize.Cache || MapCache_default)();
|
|
@@ -3025,12 +3025,12 @@ var memoize_default = memoize;
|
|
|
3025
3025
|
var MAX_MEMOIZE_SIZE = 500;
|
|
3026
3026
|
function memoizeCapped(func) {
|
|
3027
3027
|
var result = memoize_default(func, function(key) {
|
|
3028
|
-
if (
|
|
3029
|
-
|
|
3028
|
+
if (cache2.size === MAX_MEMOIZE_SIZE) {
|
|
3029
|
+
cache2.clear();
|
|
3030
3030
|
}
|
|
3031
3031
|
return key;
|
|
3032
3032
|
});
|
|
3033
|
-
var
|
|
3033
|
+
var cache2 = result.cache;
|
|
3034
3034
|
return result;
|
|
3035
3035
|
}
|
|
3036
3036
|
var memoizeCapped_default = memoizeCapped;
|
|
@@ -4073,8 +4073,8 @@ function arraySome(array, predicate) {
|
|
|
4073
4073
|
var arraySome_default = arraySome;
|
|
4074
4074
|
|
|
4075
4075
|
// node_modules/lodash-es/_cacheHas.js
|
|
4076
|
-
function cacheHas(
|
|
4077
|
-
return
|
|
4076
|
+
function cacheHas(cache2, key) {
|
|
4077
|
+
return cache2.has(key);
|
|
4078
4078
|
}
|
|
4079
4079
|
var cacheHas_default = cacheHas;
|
|
4080
4080
|
|
|
@@ -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
|
|
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;
|
|
@@ -5210,7 +5238,7 @@ async function getDestinationData({
|
|
|
5210
5238
|
}
|
|
5211
5239
|
|
|
5212
5240
|
// lib/tasks/push-to-space/push-to-space.ts
|
|
5213
|
-
var
|
|
5241
|
+
var import_logging11 = __toESM(require_logging());
|
|
5214
5242
|
var import_listr2 = __toESM(require_listr());
|
|
5215
5243
|
import Listr from "listr";
|
|
5216
5244
|
import verboseRenderer from "listr-verbose-renderer";
|
|
@@ -5509,21 +5537,103 @@ function getPlainData(entity) {
|
|
|
5509
5537
|
|
|
5510
5538
|
// lib/tasks/push-to-space/publishing.ts
|
|
5511
5539
|
var import_get_entity_name3 = __toESM(require_get_entity_name());
|
|
5540
|
+
var import_logging7 = __toESM(require_logging());
|
|
5541
|
+
|
|
5542
|
+
// lib/utils/locale-publishing.ts
|
|
5512
5543
|
var import_logging6 = __toESM(require_logging());
|
|
5513
|
-
|
|
5544
|
+
var LOCALE_PUBLISHING_FEATURES = ["localeBasedPublishing", "localePublishing"];
|
|
5545
|
+
var ENABLE_ON_ENVIRONMENT = 'To preserve it, select "Locale-based (un)publishing" for the destination environment under Settings > Locales > Publishing options.';
|
|
5546
|
+
var NOT_ENTITLED = "Locale-based publishing is only available on some plans \u2014 contact Contentful to have it added.";
|
|
5547
|
+
async function spaceHasLocalePublishingEntitlement(client, spaceId) {
|
|
5548
|
+
try {
|
|
5549
|
+
const space = await client.space.get({ spaceId });
|
|
5550
|
+
const organizationId = space.sys.organization?.sys?.id;
|
|
5551
|
+
if (!organizationId) {
|
|
5552
|
+
return null;
|
|
5553
|
+
}
|
|
5554
|
+
const entitlements = await client.raw.get(
|
|
5555
|
+
`/organizations/${organizationId}/organization_entitlement_set`
|
|
5556
|
+
);
|
|
5557
|
+
const features = entitlements.features;
|
|
5558
|
+
const known = LOCALE_PUBLISHING_FEATURES.filter((feature) => features?.[feature]?.value !== void 0);
|
|
5559
|
+
if (!known.length) {
|
|
5560
|
+
return null;
|
|
5561
|
+
}
|
|
5562
|
+
return known.some((feature) => features?.[feature]?.value === true);
|
|
5563
|
+
} catch {
|
|
5564
|
+
return null;
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
var localeScopingUnavailable = /* @__PURE__ */ new WeakSet();
|
|
5568
|
+
var entitlementChecks = /* @__PURE__ */ new WeakMap();
|
|
5569
|
+
async function ensureLocalePublishingEntitlement(client, spaceId) {
|
|
5570
|
+
if (localeScopingUnavailable.has(client)) {
|
|
5571
|
+
return;
|
|
5572
|
+
}
|
|
5573
|
+
let check = entitlementChecks.get(client);
|
|
5574
|
+
if (!check) {
|
|
5575
|
+
check = spaceHasLocalePublishingEntitlement(client, spaceId);
|
|
5576
|
+
entitlementChecks.set(client, check);
|
|
5577
|
+
}
|
|
5578
|
+
if (await check === false) {
|
|
5579
|
+
markLocaleScopingUnavailable(client, "The destination organization is not entitled to locale-based publishing.", NOT_ENTITLED);
|
|
5580
|
+
}
|
|
5581
|
+
}
|
|
5582
|
+
function isLocaleScopingUnavailable(client) {
|
|
5583
|
+
return localeScopingUnavailable.has(client);
|
|
5584
|
+
}
|
|
5585
|
+
function markLocaleScopingUnavailable(client, reason, remedy = ENABLE_ON_ENVIRONMENT) {
|
|
5586
|
+
if (localeScopingUnavailable.has(client)) {
|
|
5587
|
+
return;
|
|
5588
|
+
}
|
|
5589
|
+
localeScopingUnavailable.add(client);
|
|
5590
|
+
import_logging6.logEmitter.emit("warning", `${reason} Publishing every locale instead \u2014 the per-locale publish state in the content file cannot be preserved. ${remedy}`);
|
|
5591
|
+
}
|
|
5592
|
+
function isLocalePublishingRejectedError(err) {
|
|
5593
|
+
if (!(err instanceof Error)) {
|
|
5594
|
+
return false;
|
|
5595
|
+
}
|
|
5596
|
+
const status = err.status ?? err.response?.status;
|
|
5597
|
+
if (status === 403 || status === 400) {
|
|
5598
|
+
return true;
|
|
5599
|
+
}
|
|
5600
|
+
try {
|
|
5601
|
+
const parsed = JSON.parse(err.message)?.status;
|
|
5602
|
+
return parsed === 403 || parsed === 400;
|
|
5603
|
+
} catch {
|
|
5604
|
+
return false;
|
|
5605
|
+
}
|
|
5606
|
+
}
|
|
5607
|
+
function destinationScopedThePublish(publishedEntity) {
|
|
5608
|
+
return Boolean(publishedEntity?.sys?.fieldStatus?.["*"]);
|
|
5609
|
+
}
|
|
5610
|
+
|
|
5611
|
+
// lib/tasks/push-to-space/publishing.ts
|
|
5612
|
+
function publishEntity(client, spaceId, environmentId, entity, locales2) {
|
|
5514
5613
|
const id = entity.sys.id;
|
|
5515
5614
|
const type = entity.sys.type;
|
|
5516
5615
|
if (type === "Entry") {
|
|
5517
|
-
return client.entry.publish({ spaceId, environmentId, entryId: id }, entity);
|
|
5616
|
+
return client.entry.publish({ spaceId, environmentId, entryId: id, locales: locales2 }, entity);
|
|
5518
5617
|
}
|
|
5519
5618
|
if (type === "Asset") {
|
|
5520
|
-
return client.asset.publish({ spaceId, environmentId, assetId: id }, entity);
|
|
5619
|
+
return client.asset.publish({ spaceId, environmentId, assetId: id, locales: locales2 }, entity);
|
|
5521
5620
|
}
|
|
5522
5621
|
if (type === "ContentType") {
|
|
5523
5622
|
return client.contentType.publish({ spaceId, environmentId, contentTypeId: id }, entity);
|
|
5524
5623
|
}
|
|
5525
5624
|
throw new Error(`publishEntity: unsupported type "${type}"`);
|
|
5526
5625
|
}
|
|
5626
|
+
function unpublishEntityLocales(client, spaceId, environmentId, entity, locales2) {
|
|
5627
|
+
const id = entity.sys.id;
|
|
5628
|
+
const type = entity.sys.type;
|
|
5629
|
+
if (type === "Entry") {
|
|
5630
|
+
return client.entry.unpublish({ spaceId, environmentId, entryId: id, locales: locales2 }, entity);
|
|
5631
|
+
}
|
|
5632
|
+
if (type === "Asset") {
|
|
5633
|
+
return client.asset.unpublish({ spaceId, environmentId, assetId: id, locales: locales2 }, entity);
|
|
5634
|
+
}
|
|
5635
|
+
throw new Error(`unpublishEntityLocales: unsupported type "${type}"`);
|
|
5636
|
+
}
|
|
5527
5637
|
function archiveEntity(client, spaceId, environmentId, entity) {
|
|
5528
5638
|
const id = entity.sys.id;
|
|
5529
5639
|
const type = entity.sys.type;
|
|
@@ -5535,26 +5645,26 @@ function archiveEntity(client, spaceId, environmentId, entity) {
|
|
|
5535
5645
|
}
|
|
5536
5646
|
throw new Error(`archiveEntity: unsupported type "${type}"`);
|
|
5537
5647
|
}
|
|
5538
|
-
async function publishEntities({ entities, client, spaceId, environmentId, requestQueue }) {
|
|
5648
|
+
async function publishEntities({ entities, client, spaceId, environmentId, requestQueue, localePublishing }) {
|
|
5539
5649
|
if (entities.length === 0) {
|
|
5540
|
-
|
|
5650
|
+
import_logging7.logEmitter.emit("info", "Skipping publishing since zero valid entities passed");
|
|
5541
5651
|
return [];
|
|
5542
5652
|
}
|
|
5543
5653
|
const entity = entities[0];
|
|
5544
5654
|
const type = entity.sys.type || "unknown type";
|
|
5545
|
-
|
|
5546
|
-
const result = await runQueue(entities, [], client, spaceId, environmentId, requestQueue);
|
|
5547
|
-
|
|
5655
|
+
import_logging7.logEmitter.emit("info", `Publishing ${entities.length} ${type}s`);
|
|
5656
|
+
const result = await runQueue(entities, [], client, spaceId, environmentId, requestQueue, localePublishing);
|
|
5657
|
+
import_logging7.logEmitter.emit("info", `Successfully published ${result.length} ${type}s`);
|
|
5548
5658
|
return result;
|
|
5549
5659
|
}
|
|
5550
5660
|
async function archiveEntities({ entities, client, spaceId, environmentId, requestQueue }) {
|
|
5551
5661
|
if (entities.length === 0) {
|
|
5552
|
-
|
|
5662
|
+
import_logging7.logEmitter.emit("info", "Skipping archiving since zero valid entities passed");
|
|
5553
5663
|
return [];
|
|
5554
5664
|
}
|
|
5555
5665
|
const entity = entities[0];
|
|
5556
5666
|
const type = entity.sys.type || "unknown type";
|
|
5557
|
-
|
|
5667
|
+
import_logging7.logEmitter.emit("info", `Archiving ${entities.length} ${type}s`);
|
|
5558
5668
|
const pendingArchivedEntities = entities.map((entity2) => {
|
|
5559
5669
|
return requestQueue.add(async () => {
|
|
5560
5670
|
try {
|
|
@@ -5564,28 +5674,66 @@ async function archiveEntities({ entities, client, spaceId, environmentId, reque
|
|
|
5564
5674
|
if (err instanceof ContentfulEntityError) {
|
|
5565
5675
|
err.entity = entity2;
|
|
5566
5676
|
}
|
|
5567
|
-
|
|
5677
|
+
import_logging7.logEmitter.emit("error", err);
|
|
5568
5678
|
return null;
|
|
5569
5679
|
}
|
|
5570
5680
|
});
|
|
5571
5681
|
});
|
|
5572
5682
|
const allPossiblyArchivedEntities = await Promise.all(pendingArchivedEntities);
|
|
5573
5683
|
const allArchivedEntities = allPossiblyArchivedEntities.filter((entity2) => entity2);
|
|
5574
|
-
|
|
5684
|
+
import_logging7.logEmitter.emit("info", `Successfully archived ${allArchivedEntities.length} ${type}s`);
|
|
5575
5685
|
return allArchivedEntities;
|
|
5576
5686
|
}
|
|
5577
|
-
async function
|
|
5687
|
+
async function publishEntityLocales(client, spaceId, environmentId, entity, locales2, localesToDemote) {
|
|
5688
|
+
let published;
|
|
5689
|
+
try {
|
|
5690
|
+
published = await publishEntity(client, spaceId, environmentId, entity, locales2);
|
|
5691
|
+
} catch (err) {
|
|
5692
|
+
if (!isLocalePublishingRejectedError(err)) {
|
|
5693
|
+
throw err;
|
|
5694
|
+
}
|
|
5695
|
+
markLocaleScopingUnavailable(client, `The destination rejected locale-scoped publishing, starting with ${entity.sys.type} ${(0, import_get_entity_name3.default)(entity)}.`);
|
|
5696
|
+
return publishEntity(client, spaceId, environmentId, entity);
|
|
5697
|
+
}
|
|
5698
|
+
if (!destinationScopedThePublish(published)) {
|
|
5699
|
+
markLocaleScopingUnavailable(client, `The destination published ${entity.sys.type} ${(0, import_get_entity_name3.default)(entity)} without honouring the requested locales (${locales2.join(", ")}) and reported no per-locale state back.`);
|
|
5700
|
+
return published;
|
|
5701
|
+
}
|
|
5702
|
+
if (!localesToDemote?.length) {
|
|
5703
|
+
return published;
|
|
5704
|
+
}
|
|
5705
|
+
import_logging7.logEmitter.emit("info", `Unpublishing locales ${localesToDemote.join(", ")} of ${entity.sys.type} ${(0, import_get_entity_name3.default)(entity)}`);
|
|
5706
|
+
try {
|
|
5707
|
+
return await unpublishEntityLocales(client, spaceId, environmentId, published, localesToDemote);
|
|
5708
|
+
} catch (err) {
|
|
5709
|
+
if (isLocalePublishingRejectedError(err)) {
|
|
5710
|
+
markLocaleScopingUnavailable(client, `The destination rejected locale-scoped unpublishing, starting with ${entity.sys.type} ${(0, import_get_entity_name3.default)(entity)}.`);
|
|
5711
|
+
return published;
|
|
5712
|
+
}
|
|
5713
|
+
if (err instanceof ContentfulEntityError) {
|
|
5714
|
+
err.entity = entity;
|
|
5715
|
+
}
|
|
5716
|
+
import_logging7.logEmitter.emit("error", err);
|
|
5717
|
+
return published;
|
|
5718
|
+
}
|
|
5719
|
+
}
|
|
5720
|
+
async function runQueue(queue, result = [], client, spaceId, environmentId, requestQueue, localePublishing) {
|
|
5578
5721
|
const publishedEntities = [];
|
|
5579
5722
|
for (const entity of queue) {
|
|
5580
|
-
|
|
5723
|
+
const locales2 = localePublishing && !isLocaleScopingUnavailable(client) ? localePublishing.localesByEntityId.get(entity.sys.id) : void 0;
|
|
5724
|
+
if (locales2) {
|
|
5725
|
+
import_logging7.logEmitter.emit("info", `Publishing ${entity.sys.type} ${(0, import_get_entity_name3.default)(entity)} for locales ${locales2.join(", ")}`);
|
|
5726
|
+
} else {
|
|
5727
|
+
import_logging7.logEmitter.emit("info", `Publishing ${entity.sys.type} ${(0, import_get_entity_name3.default)(entity)}`);
|
|
5728
|
+
}
|
|
5581
5729
|
try {
|
|
5582
|
-
const publishedEntity = await requestQueue.add(() => publishEntity(client, spaceId, environmentId, entity));
|
|
5730
|
+
const publishedEntity = await requestQueue.add(() => locales2 ? publishEntityLocales(client, spaceId, environmentId, entity, locales2, localePublishing?.demoteLocalesByEntityId.get(entity.sys.id)) : publishEntity(client, spaceId, environmentId, entity));
|
|
5583
5731
|
publishedEntities.push(publishedEntity);
|
|
5584
5732
|
} catch (err) {
|
|
5585
5733
|
if (err instanceof ContentfulEntityError) {
|
|
5586
5734
|
err.entity = entity;
|
|
5587
5735
|
}
|
|
5588
|
-
|
|
5736
|
+
import_logging7.logEmitter.emit("error", err);
|
|
5589
5737
|
}
|
|
5590
5738
|
}
|
|
5591
5739
|
result = [
|
|
@@ -5597,9 +5745,9 @@ async function runQueue(queue, result = [], client, spaceId, environmentId, requ
|
|
|
5597
5745
|
if (unpublishedEntities.length > 0) {
|
|
5598
5746
|
if (queue.length === unpublishedEntities.length) {
|
|
5599
5747
|
const unpublishedEntityNames = unpublishedEntities.map(import_get_entity_name3.default).join(", ");
|
|
5600
|
-
|
|
5748
|
+
import_logging7.logEmitter.emit("error", `Could not publish the following entities: ${unpublishedEntityNames}`);
|
|
5601
5749
|
} else {
|
|
5602
|
-
return runQueue(unpublishedEntities, result, client, spaceId, environmentId, requestQueue);
|
|
5750
|
+
return runQueue(unpublishedEntities, result, client, spaceId, environmentId, requestQueue, localePublishing);
|
|
5603
5751
|
}
|
|
5604
5752
|
}
|
|
5605
5753
|
return result;
|
|
@@ -5731,18 +5879,18 @@ function sortExperienceFragments(experienceFragments) {
|
|
|
5731
5879
|
}
|
|
5732
5880
|
|
|
5733
5881
|
// lib/utils/sort-or-report.ts
|
|
5734
|
-
var
|
|
5882
|
+
var import_logging8 = __toESM(require_logging());
|
|
5735
5883
|
function sortOrReport(sortFn) {
|
|
5736
5884
|
try {
|
|
5737
5885
|
return sortFn();
|
|
5738
5886
|
} catch (err) {
|
|
5739
|
-
|
|
5887
|
+
import_logging8.logEmitter.emit("error", err);
|
|
5740
5888
|
throw err;
|
|
5741
5889
|
}
|
|
5742
5890
|
}
|
|
5743
5891
|
|
|
5744
5892
|
// lib/utils/import-exo-folders.ts
|
|
5745
|
-
var
|
|
5893
|
+
var import_logging9 = __toESM(require_logging());
|
|
5746
5894
|
var FOLDER_CONCEPT_PREFIX = "contentful.folder-";
|
|
5747
5895
|
var PARENT_FOLDER_GROUP_IDS = {
|
|
5748
5896
|
designToken: "contentful.folder-group-designToken",
|
|
@@ -5812,7 +5960,7 @@ async function createOrPatchChildConcepts(client, organizationId, destinationSpa
|
|
|
5812
5960
|
existing = await client.concept.get({ organizationId, conceptId: destConceptId });
|
|
5813
5961
|
} catch (err) {
|
|
5814
5962
|
if (err?.name !== "NotFound") {
|
|
5815
|
-
|
|
5963
|
+
import_logging9.logEmitter.emit("warning", `Could not fetch destination child concept ${destConceptId}: ${err?.message ?? err}`);
|
|
5816
5964
|
}
|
|
5817
5965
|
}
|
|
5818
5966
|
if (!existing) {
|
|
@@ -5822,9 +5970,9 @@ async function createOrPatchChildConcepts(client, organizationId, destinationSpa
|
|
|
5822
5970
|
// @ts-expect-error - CMA.js type needs to be updated to be aware of purpose: 'internal'
|
|
5823
5971
|
{ purpose: "internal", prefLabel, metadata: { spaces: [spaceLink] } }
|
|
5824
5972
|
);
|
|
5825
|
-
|
|
5973
|
+
import_logging9.logEmitter.emit("info", `Created child folder concept ${destConceptId}`);
|
|
5826
5974
|
} catch (err) {
|
|
5827
|
-
|
|
5975
|
+
import_logging9.logEmitter.emit("error", `Failed to create child folder concept ${destConceptId}: ${err?.message ?? err}`);
|
|
5828
5976
|
}
|
|
5829
5977
|
} else {
|
|
5830
5978
|
const patches = [];
|
|
@@ -5838,9 +5986,9 @@ async function createOrPatchChildConcepts(client, organizationId, destinationSpa
|
|
|
5838
5986
|
{ organizationId, conceptId: destConceptId, version: existing.sys.version },
|
|
5839
5987
|
patches
|
|
5840
5988
|
);
|
|
5841
|
-
|
|
5989
|
+
import_logging9.logEmitter.emit("info", `Patched child folder concept ${destConceptId} (${patches.map((p) => p.path).join(", ")})`);
|
|
5842
5990
|
} catch (err) {
|
|
5843
|
-
|
|
5991
|
+
import_logging9.logEmitter.emit("error", `Failed to patch child folder concept ${destConceptId}: ${err?.message ?? err}`);
|
|
5844
5992
|
}
|
|
5845
5993
|
}
|
|
5846
5994
|
}
|
|
@@ -5858,9 +6006,9 @@ async function linkChildConceptsToParentGroups(client, organizationId, childConc
|
|
|
5858
6006
|
[{ op: "add", path: "/concepts/-", value: { sys: { type: "Link", linkType: "TaxonomyConcept", id: destConceptId } } }]
|
|
5859
6007
|
);
|
|
5860
6008
|
parentGroups.set(parentGroupId, updated);
|
|
5861
|
-
|
|
6009
|
+
import_logging9.logEmitter.emit("info", `Linked child concept ${destConceptId} to parent group ${parentGroupId}`);
|
|
5862
6010
|
} catch (err) {
|
|
5863
|
-
|
|
6011
|
+
import_logging9.logEmitter.emit("error", `Failed to link child concept ${destConceptId} to parent group ${parentGroupId}: ${err?.message ?? err}`);
|
|
5864
6012
|
}
|
|
5865
6013
|
}
|
|
5866
6014
|
}
|
|
@@ -5882,17 +6030,17 @@ async function importExoFolders({
|
|
|
5882
6030
|
}) {
|
|
5883
6031
|
const sourceSpaceId = getSourceSpaceId(sourceEntities);
|
|
5884
6032
|
if (sourceSpaceId === destinationSpaceId) {
|
|
5885
|
-
|
|
6033
|
+
import_logging9.logEmitter.emit("info", "Source and destination space are the same \u2014 skipping ExO folder import");
|
|
5886
6034
|
return;
|
|
5887
6035
|
}
|
|
5888
6036
|
const parentGroups = await ensureParentFolderGroupsExist(client, organizationId);
|
|
5889
6037
|
if (parentGroups.size === 0) {
|
|
5890
|
-
|
|
6038
|
+
import_logging9.logEmitter.emit("warn", "One or more Experience Orchestration folder group concept schemes are missing in the destination organization. Please create them before importing.");
|
|
5891
6039
|
return;
|
|
5892
6040
|
}
|
|
5893
6041
|
const childConceptMap = deriveChildConceptMap(sourceEntities, destinationSpaceId);
|
|
5894
6042
|
if (childConceptMap.size === 0) return;
|
|
5895
|
-
|
|
6043
|
+
import_logging9.logEmitter.emit("info", `Importing ${childConceptMap.size} ExO folder concept(s) into destination space ${destinationSpaceId}`);
|
|
5896
6044
|
await createOrPatchChildConcepts(client, organizationId, destinationSpaceId, childConceptMap);
|
|
5897
6045
|
await linkChildConceptsToParentGroups(client, organizationId, childConceptMap, parentGroups);
|
|
5898
6046
|
const allEntities = [
|
|
@@ -5905,6 +6053,79 @@ async function importExoFolders({
|
|
|
5905
6053
|
rewriteEntityFolderConcepts(allEntities, childConceptMap);
|
|
5906
6054
|
}
|
|
5907
6055
|
|
|
6056
|
+
// lib/utils/resolve-publish-locales.ts
|
|
6057
|
+
var LIVE_FIELD_STATUSES = ["published", "changed"];
|
|
6058
|
+
function resolvePublishLocales(sys, destinationLocaleCodes) {
|
|
6059
|
+
const fieldStatus = sys.fieldStatus?.["*"];
|
|
6060
|
+
if (!fieldStatus || !destinationLocaleCodes) {
|
|
6061
|
+
return null;
|
|
6062
|
+
}
|
|
6063
|
+
const liveLocales = Object.keys(fieldStatus).filter((locale) => LIVE_FIELD_STATUSES.indexOf(fieldStatus[locale]) !== -1);
|
|
6064
|
+
const availableLocales = liveLocales.filter((locale) => destinationLocaleCodes.indexOf(locale) !== -1);
|
|
6065
|
+
if (availableLocales.length === 0) {
|
|
6066
|
+
return [];
|
|
6067
|
+
}
|
|
6068
|
+
const everyLocaleIsLive = destinationLocaleCodes.every((locale) => availableLocales.indexOf(locale) !== -1);
|
|
6069
|
+
return everyLocaleIsLive ? null : availableLocales;
|
|
6070
|
+
}
|
|
6071
|
+
function resolveLocalesToDemote(sys, destinationSys, destinationLocaleCodes) {
|
|
6072
|
+
const fieldStatus = sys.fieldStatus?.["*"];
|
|
6073
|
+
const destinationFieldStatus = destinationSys?.fieldStatus?.["*"];
|
|
6074
|
+
if (!fieldStatus || !destinationFieldStatus) {
|
|
6075
|
+
return [];
|
|
6076
|
+
}
|
|
6077
|
+
return Object.keys(fieldStatus).filter((locale) => fieldStatus[locale] === "draft").filter((locale) => destinationLocaleCodes.indexOf(locale) !== -1).filter((locale) => LIVE_FIELD_STATUSES.indexOf(destinationFieldStatus[locale]) !== -1);
|
|
6078
|
+
}
|
|
6079
|
+
function buildLocalePublishPlan(sourceEntities, destinationLocaleCodes, { destinationEntitiesById } = {}) {
|
|
6080
|
+
const localesByEntityId = /* @__PURE__ */ new Map();
|
|
6081
|
+
const skippedEntityIds = /* @__PURE__ */ new Set();
|
|
6082
|
+
const demoteLocalesByEntityId = /* @__PURE__ */ new Map();
|
|
6083
|
+
for (const { original } of sourceEntities) {
|
|
6084
|
+
const locales2 = resolvePublishLocales(original.sys, destinationLocaleCodes);
|
|
6085
|
+
if (locales2 === null) {
|
|
6086
|
+
continue;
|
|
6087
|
+
}
|
|
6088
|
+
if (locales2.length === 0) {
|
|
6089
|
+
skippedEntityIds.add(original.sys.id);
|
|
6090
|
+
continue;
|
|
6091
|
+
}
|
|
6092
|
+
localesByEntityId.set(original.sys.id, locales2);
|
|
6093
|
+
if (!destinationEntitiesById) {
|
|
6094
|
+
continue;
|
|
6095
|
+
}
|
|
6096
|
+
const localesToDemote = resolveLocalesToDemote(
|
|
6097
|
+
original.sys,
|
|
6098
|
+
destinationEntitiesById.get(original.sys.id)?.sys,
|
|
6099
|
+
destinationLocaleCodes
|
|
6100
|
+
);
|
|
6101
|
+
if (localesToDemote.length) {
|
|
6102
|
+
demoteLocalesByEntityId.set(original.sys.id, localesToDemote);
|
|
6103
|
+
}
|
|
6104
|
+
}
|
|
6105
|
+
return { localesByEntityId, skippedEntityIds, demoteLocalesByEntityId };
|
|
6106
|
+
}
|
|
6107
|
+
|
|
6108
|
+
// lib/utils/destination-locales.ts
|
|
6109
|
+
var import_logging10 = __toESM(require_logging());
|
|
6110
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
6111
|
+
function getDestinationLocaleCodes({ client, spaceId, environmentId, requestQueue }) {
|
|
6112
|
+
let byEnvironment = cache.get(client);
|
|
6113
|
+
if (!byEnvironment) {
|
|
6114
|
+
byEnvironment = /* @__PURE__ */ new Map();
|
|
6115
|
+
cache.set(client, byEnvironment);
|
|
6116
|
+
}
|
|
6117
|
+
const key = `${spaceId}/${environmentId}`;
|
|
6118
|
+
let localeCodes = byEnvironment.get(key);
|
|
6119
|
+
if (!localeCodes) {
|
|
6120
|
+
localeCodes = batchedPageQuery({ client, spaceId, environmentId, type: "locales", requestQueue }).then((items) => items.map((locale) => locale.code)).catch((err) => {
|
|
6121
|
+
import_logging10.logEmitter.emit("warning", `Could not read the locales of the destination environment, falling back to publishing all locales: ${err.message}`);
|
|
6122
|
+
return null;
|
|
6123
|
+
});
|
|
6124
|
+
byEnvironment.set(key, localeCodes);
|
|
6125
|
+
}
|
|
6126
|
+
return localeCodes;
|
|
6127
|
+
}
|
|
6128
|
+
|
|
5908
6129
|
// lib/tasks/push-to-space/push-to-space.ts
|
|
5909
6130
|
async function withGraphQLSchemaBackoff(fn) {
|
|
5910
6131
|
let lastErr;
|
|
@@ -5916,7 +6137,7 @@ async function withGraphQLSchemaBackoff(fn) {
|
|
|
5916
6137
|
throw err;
|
|
5917
6138
|
}
|
|
5918
6139
|
const delay = GRAPHQL_SCHEMA_STALE_DELAYS_MS[attempt];
|
|
5919
|
-
|
|
6140
|
+
import_logging11.logEmitter.emit("warning", `DataAssembly GraphQL schema not yet current, retrying in ${delay}ms (attempt ${attempt + 1}/${GRAPHQL_SCHEMA_STALE_DELAYS_MS.length})`);
|
|
5920
6141
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
5921
6142
|
lastErr = err;
|
|
5922
6143
|
}
|
|
@@ -5939,11 +6160,13 @@ function pushToSpace({
|
|
|
5939
6160
|
spaceId,
|
|
5940
6161
|
environmentId,
|
|
5941
6162
|
includeExperienceOrchestration,
|
|
6163
|
+
skipExoVariants,
|
|
5942
6164
|
contentModelOnly,
|
|
5943
6165
|
skipContentModel,
|
|
5944
6166
|
skipContentUpdates,
|
|
5945
6167
|
skipLocales,
|
|
5946
6168
|
skipContentPublishing,
|
|
6169
|
+
unpublishDraftLocales,
|
|
5947
6170
|
timeout,
|
|
5948
6171
|
retryLimit,
|
|
5949
6172
|
listrOptions,
|
|
@@ -5960,6 +6183,13 @@ function pushToSpace({
|
|
|
5960
6183
|
...DEFAULT_CONTENT_STRUCTURE,
|
|
5961
6184
|
...destinationData
|
|
5962
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
|
+
}
|
|
5963
6193
|
listrOptions = listrOptions || {
|
|
5964
6194
|
renderer: verboseRenderer
|
|
5965
6195
|
};
|
|
@@ -6055,7 +6285,7 @@ function pushToSpace({
|
|
|
6055
6285
|
const ctEditorInterface = await requestQueue.add(
|
|
6056
6286
|
() => client.editorInterface.get({ spaceId, environmentId, contentTypeId: contentType.sys.id })
|
|
6057
6287
|
);
|
|
6058
|
-
|
|
6288
|
+
import_logging11.logEmitter.emit("info", `Fetched editor interface for ${contentType.name}`);
|
|
6059
6289
|
const updatedData = {
|
|
6060
6290
|
...ctEditorInterface,
|
|
6061
6291
|
controls: editorInterface.controls,
|
|
@@ -6073,7 +6303,7 @@ function pushToSpace({
|
|
|
6073
6303
|
return updatedEditorInterface;
|
|
6074
6304
|
} catch (err) {
|
|
6075
6305
|
err.entity = editorInterface;
|
|
6076
|
-
|
|
6306
|
+
import_logging11.logEmitter.emit("error", err);
|
|
6077
6307
|
return null;
|
|
6078
6308
|
}
|
|
6079
6309
|
});
|
|
@@ -6091,7 +6321,7 @@ function pushToSpace({
|
|
|
6091
6321
|
for (const file of Object.values(asset.transformed.fields.file)) {
|
|
6092
6322
|
allPendingUploads.push(requestQueue.add(async () => {
|
|
6093
6323
|
try {
|
|
6094
|
-
|
|
6324
|
+
import_logging11.logEmitter.emit("info", `Uploading Asset file ${file.upload}`);
|
|
6095
6325
|
const assetStream = await getAssetStreamForURL(file.upload, assetsDirectory);
|
|
6096
6326
|
const upload = await client.upload.create(
|
|
6097
6327
|
{ spaceId, environmentId },
|
|
@@ -6107,7 +6337,7 @@ function pushToSpace({
|
|
|
6107
6337
|
};
|
|
6108
6338
|
return upload;
|
|
6109
6339
|
} catch (err) {
|
|
6110
|
-
|
|
6340
|
+
import_logging11.logEmitter.emit("error", err);
|
|
6111
6341
|
}
|
|
6112
6342
|
}));
|
|
6113
6343
|
}
|
|
@@ -6152,7 +6382,8 @@ function pushToSpace({
|
|
|
6152
6382
|
client,
|
|
6153
6383
|
spaceId,
|
|
6154
6384
|
environmentId,
|
|
6155
|
-
requestQueue
|
|
6385
|
+
requestQueue,
|
|
6386
|
+
destinationEntitiesById: unpublishDraftLocales ? destinationDataById.assets : void 0
|
|
6156
6387
|
});
|
|
6157
6388
|
ctx.data.publishedAssets = publishedAssets;
|
|
6158
6389
|
}),
|
|
@@ -6196,7 +6427,8 @@ function pushToSpace({
|
|
|
6196
6427
|
client,
|
|
6197
6428
|
spaceId,
|
|
6198
6429
|
environmentId,
|
|
6199
|
-
requestQueue
|
|
6430
|
+
requestQueue,
|
|
6431
|
+
destinationEntitiesById: unpublishDraftLocales ? destinationDataById.entries : void 0
|
|
6200
6432
|
});
|
|
6201
6433
|
ctx.data.publishedEntries = publishedEntries;
|
|
6202
6434
|
}),
|
|
@@ -6251,7 +6483,7 @@ function pushToSpace({
|
|
|
6251
6483
|
}
|
|
6252
6484
|
});
|
|
6253
6485
|
} catch (error) {
|
|
6254
|
-
|
|
6486
|
+
import_logging11.logEmitter.emit("warning", `Unable to create Experience Orchestration (ExO) folders, error: ${error}`);
|
|
6255
6487
|
}
|
|
6256
6488
|
}),
|
|
6257
6489
|
skip: () => !includeExperienceOrchestration
|
|
@@ -6269,19 +6501,19 @@ function pushToSpace({
|
|
|
6269
6501
|
{ spaceId, environmentId, dataAssemblyId: entity.sys.id },
|
|
6270
6502
|
payload
|
|
6271
6503
|
));
|
|
6272
|
-
|
|
6504
|
+
import_logging11.logEmitter.emit("info", `UPDATE DataAssembly ${entity.sys.id}`);
|
|
6273
6505
|
} else {
|
|
6274
6506
|
const payload = { ...omitSys(entity), sys: buildDataAssemblySys(entity, 0) };
|
|
6275
6507
|
result = await withGraphQLSchemaBackoff(() => client.dataAssembly.update(
|
|
6276
6508
|
{ spaceId, environmentId, dataAssemblyId: entity.sys.id },
|
|
6277
6509
|
payload
|
|
6278
6510
|
));
|
|
6279
|
-
|
|
6511
|
+
import_logging11.logEmitter.emit("info", `CREATE DataAssembly ${entity.sys.id}`);
|
|
6280
6512
|
}
|
|
6281
6513
|
return result;
|
|
6282
6514
|
} catch (err) {
|
|
6283
6515
|
err.entity = entity;
|
|
6284
|
-
|
|
6516
|
+
import_logging11.logEmitter.emit("error", err);
|
|
6285
6517
|
return null;
|
|
6286
6518
|
}
|
|
6287
6519
|
}));
|
|
@@ -6311,17 +6543,17 @@ function pushToSpace({
|
|
|
6311
6543
|
if (existing) {
|
|
6312
6544
|
const payload = { ...entity, sys: { id: entity.sys.id, type: "DesignToken", version: existing.sys.version } };
|
|
6313
6545
|
const result = await client.designToken.upsert({ spaceId, environmentId, designTokenId: entity.sys.id }, payload);
|
|
6314
|
-
|
|
6546
|
+
import_logging11.logEmitter.emit("info", `UPDATE DesignToken ${entity.sys.id}`);
|
|
6315
6547
|
return result;
|
|
6316
6548
|
} else {
|
|
6317
6549
|
const payload = { ...omitSys(entity), sys: { id: entity.sys.id, type: "DesignToken" } };
|
|
6318
6550
|
const result = await client.designToken.upsert({ spaceId, environmentId, designTokenId: entity.sys.id }, payload);
|
|
6319
|
-
|
|
6551
|
+
import_logging11.logEmitter.emit("info", `CREATE DesignToken ${entity.sys.id}`);
|
|
6320
6552
|
return result;
|
|
6321
6553
|
}
|
|
6322
6554
|
} catch (err) {
|
|
6323
6555
|
err.entity = entity;
|
|
6324
|
-
|
|
6556
|
+
import_logging11.logEmitter.emit("error", err);
|
|
6325
6557
|
return null;
|
|
6326
6558
|
}
|
|
6327
6559
|
}));
|
|
@@ -6340,17 +6572,17 @@ function pushToSpace({
|
|
|
6340
6572
|
if (existing) {
|
|
6341
6573
|
const payload = { ...entity, sys: { id: entity.sys.id, type: "Component", version: existing.sys.version } };
|
|
6342
6574
|
const result = await client.component.upsert({ spaceId, environmentId, componentId: entity.sys.id }, payload);
|
|
6343
|
-
|
|
6575
|
+
import_logging11.logEmitter.emit("info", `UPDATE Component ${entity.sys.id}`);
|
|
6344
6576
|
results.push(result);
|
|
6345
6577
|
} else {
|
|
6346
6578
|
const payload = { ...omitSys(entity), sys: { id: entity.sys.id, type: "Component" } };
|
|
6347
6579
|
const result = await client.component.upsert({ spaceId, environmentId, componentId: entity.sys.id }, payload);
|
|
6348
|
-
|
|
6580
|
+
import_logging11.logEmitter.emit("info", `CREATE Component ${entity.sys.id}`);
|
|
6349
6581
|
results.push(result);
|
|
6350
6582
|
}
|
|
6351
6583
|
} catch (err) {
|
|
6352
6584
|
err.entity = entity;
|
|
6353
|
-
|
|
6585
|
+
import_logging11.logEmitter.emit("error", err);
|
|
6354
6586
|
}
|
|
6355
6587
|
}
|
|
6356
6588
|
ctx.data.components = results;
|
|
@@ -6382,17 +6614,17 @@ function pushToSpace({
|
|
|
6382
6614
|
if (existing) {
|
|
6383
6615
|
const payload = { ...entity, sys: { id: entity.sys.id, type: "ExperienceTemplate", version: existing.sys.version } };
|
|
6384
6616
|
const result = await client.experienceTemplate.upsert({ spaceId, environmentId, experienceTemplateId: entity.sys.id }, payload);
|
|
6385
|
-
|
|
6617
|
+
import_logging11.logEmitter.emit("info", `UPDATE ExperienceTemplate ${entity.sys.id}`);
|
|
6386
6618
|
return result;
|
|
6387
6619
|
} else {
|
|
6388
6620
|
const payload = { ...omitSys(entity), sys: { id: entity.sys.id, type: "ExperienceTemplate" } };
|
|
6389
6621
|
const result = await client.experienceTemplate.upsert({ spaceId, environmentId, experienceTemplateId: entity.sys.id }, payload);
|
|
6390
|
-
|
|
6622
|
+
import_logging11.logEmitter.emit("info", `CREATE ExperienceTemplate ${entity.sys.id}`);
|
|
6391
6623
|
return result;
|
|
6392
6624
|
}
|
|
6393
6625
|
} catch (err) {
|
|
6394
6626
|
err.entity = entity;
|
|
6395
|
-
|
|
6627
|
+
import_logging11.logEmitter.emit("error", err);
|
|
6396
6628
|
return null;
|
|
6397
6629
|
}
|
|
6398
6630
|
}));
|
|
@@ -6422,19 +6654,19 @@ function pushToSpace({
|
|
|
6422
6654
|
try {
|
|
6423
6655
|
const existing = destinationDataById.experienceFragments?.get(entity.sys.id);
|
|
6424
6656
|
if (existing) {
|
|
6425
|
-
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 } };
|
|
6426
6658
|
const result = await client.experienceFragment.upsert({ spaceId, environmentId, experienceFragmentId: entity.sys.id }, payload);
|
|
6427
|
-
|
|
6659
|
+
import_logging11.logEmitter.emit("info", `UPDATE ExperienceFragment ${entity.sys.id}`);
|
|
6428
6660
|
results.push(result);
|
|
6429
6661
|
} else {
|
|
6430
|
-
const payload = { ...
|
|
6662
|
+
const payload = { ...omitSysAndOptimizationVariants(entity), component: entity.sys.component, sys: { id: entity.sys.id, type: "ExperienceFragment" } };
|
|
6431
6663
|
const result = await client.experienceFragment.upsert({ spaceId, environmentId, experienceFragmentId: entity.sys.id }, payload);
|
|
6432
|
-
|
|
6664
|
+
import_logging11.logEmitter.emit("info", `CREATE ExperienceFragment ${entity.sys.id}`);
|
|
6433
6665
|
results.push(result);
|
|
6434
6666
|
}
|
|
6435
6667
|
} catch (err) {
|
|
6436
6668
|
err.entity = entity;
|
|
6437
|
-
|
|
6669
|
+
import_logging11.logEmitter.emit("error", err);
|
|
6438
6670
|
}
|
|
6439
6671
|
}
|
|
6440
6672
|
ctx.data.experienceFragments = results;
|
|
@@ -6464,19 +6696,19 @@ function pushToSpace({
|
|
|
6464
6696
|
try {
|
|
6465
6697
|
const existing = destinationDataById.experiences?.get(entity.sys.id);
|
|
6466
6698
|
if (existing) {
|
|
6467
|
-
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 } };
|
|
6468
6700
|
const result = await client.experience.upsert({ spaceId, environmentId, experienceId: entity.sys.id }, payload);
|
|
6469
|
-
|
|
6701
|
+
import_logging11.logEmitter.emit("info", `UPDATE Experience ${entity.sys.id}`);
|
|
6470
6702
|
return result;
|
|
6471
6703
|
} else {
|
|
6472
|
-
const payload = { ...
|
|
6704
|
+
const payload = { ...omitSysAndOptimizationVariants(entity), experienceTemplate: entity.sys.experienceTemplate, sys: { id: entity.sys.id, type: "Experience" } };
|
|
6473
6705
|
const result = await client.experience.upsert({ spaceId, environmentId, experienceId: entity.sys.id }, payload);
|
|
6474
|
-
|
|
6706
|
+
import_logging11.logEmitter.emit("info", `CREATE Experience ${entity.sys.id}`);
|
|
6475
6707
|
return result;
|
|
6476
6708
|
}
|
|
6477
6709
|
} catch (err) {
|
|
6478
6710
|
err.entity = entity;
|
|
6479
|
-
|
|
6711
|
+
import_logging11.logEmitter.emit("error", err);
|
|
6480
6712
|
return null;
|
|
6481
6713
|
}
|
|
6482
6714
|
}));
|
|
@@ -6497,6 +6729,85 @@ function pushToSpace({
|
|
|
6497
6729
|
}),
|
|
6498
6730
|
skip: () => !includeExperienceOrchestration || skipContentPublishing || !(sourceData.experiences || []).length
|
|
6499
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
|
+
},
|
|
6500
6811
|
// Unpublishing runs after all Importing/Publishing tasks, in reverse dependency order
|
|
6501
6812
|
// (Experience first, DataAssembly last) - the API rejects unpublishing an entity that a
|
|
6502
6813
|
// still-published parent references, so parents must unpublish before the children they embed.
|
|
@@ -6568,15 +6879,88 @@ function omitSys(entity) {
|
|
|
6568
6879
|
const { sys: _sys, ...rest } = entity;
|
|
6569
6880
|
return rest;
|
|
6570
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
|
+
}
|
|
6571
6924
|
function archiveEntities2({ entities, sourceEntities, client, spaceId, environmentId, requestQueue }) {
|
|
6572
6925
|
const entityIdsToArchive = sourceEntities.filter(({ original }) => original.sys.archivedVersion).map(({ original }) => original.sys.id);
|
|
6573
6926
|
const entitiesToArchive = entities.filter((entity) => entityIdsToArchive.indexOf(entity.sys.id) !== -1);
|
|
6574
6927
|
return archiveEntities({ entities: entitiesToArchive, client, spaceId, environmentId, requestQueue });
|
|
6575
6928
|
}
|
|
6576
|
-
function publishEntities2({ entities, sourceEntities, client, spaceId, environmentId, requestQueue }) {
|
|
6929
|
+
async function publishEntities2({ entities, sourceEntities, client, spaceId, environmentId, requestQueue, destinationEntitiesById }) {
|
|
6577
6930
|
const entityIdsToPublish = sourceEntities.filter(({ original }) => original.sys.publishedVersion).map(({ original }) => original.sys.id);
|
|
6578
|
-
|
|
6579
|
-
|
|
6931
|
+
let entitiesToPublish = entities.filter((entity) => entityIdsToPublish.indexOf(entity.sys.id) !== -1);
|
|
6932
|
+
const publishAllLocales = () => publishEntities({ entities: entitiesToPublish, client, spaceId, environmentId, requestQueue });
|
|
6933
|
+
const hasFieldStatus = sourceEntities.some(({ original }) => original.sys.fieldStatus);
|
|
6934
|
+
if (!hasFieldStatus) {
|
|
6935
|
+
return publishAllLocales();
|
|
6936
|
+
}
|
|
6937
|
+
await ensureLocalePublishingEntitlement(client, spaceId);
|
|
6938
|
+
if (isLocaleScopingUnavailable(client)) {
|
|
6939
|
+
return publishAllLocales();
|
|
6940
|
+
}
|
|
6941
|
+
const destinationLocaleCodes = await getDestinationLocaleCodes({ client, spaceId, environmentId, requestQueue });
|
|
6942
|
+
const localePublishing = buildLocalePublishPlan(
|
|
6943
|
+
sourceEntities,
|
|
6944
|
+
destinationLocaleCodes,
|
|
6945
|
+
{ destinationEntitiesById }
|
|
6946
|
+
);
|
|
6947
|
+
if (localePublishing.skippedEntityIds.size) {
|
|
6948
|
+
entitiesToPublish = entitiesToPublish.filter((entity) => {
|
|
6949
|
+
if (!localePublishing.skippedEntityIds.has(entity.sys.id)) {
|
|
6950
|
+
return true;
|
|
6951
|
+
}
|
|
6952
|
+
import_logging11.logEmitter.emit("warning", `Not publishing ${entity.sys.type} ${entity.sys.id} because none of the locales it was published for exist in the destination environment`);
|
|
6953
|
+
return false;
|
|
6954
|
+
});
|
|
6955
|
+
}
|
|
6956
|
+
return publishEntities({
|
|
6957
|
+
entities: entitiesToPublish,
|
|
6958
|
+
client,
|
|
6959
|
+
spaceId,
|
|
6960
|
+
environmentId,
|
|
6961
|
+
requestQueue,
|
|
6962
|
+
localePublishing
|
|
6963
|
+
});
|
|
6580
6964
|
}
|
|
6581
6965
|
|
|
6582
6966
|
// lib/transform/transformers.ts
|
|
@@ -7113,6 +7497,7 @@ async function parseOptions(params) {
|
|
|
7113
7497
|
skipContentModel: false,
|
|
7114
7498
|
skipLocales: false,
|
|
7115
7499
|
skipContentPublishing: false,
|
|
7500
|
+
unpublishDraftLocales: false,
|
|
7116
7501
|
skipAssetUpdates: false,
|
|
7117
7502
|
skipContentUpdates: false,
|
|
7118
7503
|
useVerboseRenderer: false,
|
|
@@ -7121,6 +7506,7 @@ async function parseOptions(params) {
|
|
|
7121
7506
|
uploadAssets: false,
|
|
7122
7507
|
rateLimit: 7,
|
|
7123
7508
|
includeExperienceOrchestration: true,
|
|
7509
|
+
skipExoVariants: false,
|
|
7124
7510
|
host: "api.contentful.com"
|
|
7125
7511
|
};
|
|
7126
7512
|
const configFile = params.config ? __require(resolve(process.cwd(), params.config)) : {};
|
|
@@ -7195,6 +7581,29 @@ async function parseOptions(params) {
|
|
|
7195
7581
|
return options;
|
|
7196
7582
|
}
|
|
7197
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
|
+
|
|
7198
7607
|
// lib/index.ts
|
|
7199
7608
|
var ONE_SECOND = 1e3;
|
|
7200
7609
|
var tableOptions = {
|
|
@@ -7221,7 +7630,7 @@ async function runContentfulImport(params) {
|
|
|
7221
7630
|
intervalCap: options.rateLimit,
|
|
7222
7631
|
carryoverConcurrencyCount: true
|
|
7223
7632
|
});
|
|
7224
|
-
(0,
|
|
7633
|
+
(0, import_logging13.setupLogging)(log);
|
|
7225
7634
|
const infoTable = new Table(tableOptions);
|
|
7226
7635
|
infoTable.push([{ colSpan: 2, content: "The following entities are going to be imported:" }]);
|
|
7227
7636
|
Object.keys(options.content).forEach((type) => {
|
|
@@ -7236,6 +7645,20 @@ async function runContentfulImport(params) {
|
|
|
7236
7645
|
}
|
|
7237
7646
|
infoTable.push([startCase_default(type), options.content[type].length]);
|
|
7238
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
|
+
}
|
|
7239
7662
|
console.log(infoTable.toString());
|
|
7240
7663
|
const tasks = new Listr2([
|
|
7241
7664
|
{
|
|
@@ -7284,11 +7707,13 @@ async function runContentfulImport(params) {
|
|
|
7284
7707
|
client: ctx.client,
|
|
7285
7708
|
spaceId: options.spaceId,
|
|
7286
7709
|
includeExperienceOrchestration: options.includeExperienceOrchestration,
|
|
7710
|
+
skipExoVariants: options.skipExoVariants,
|
|
7287
7711
|
environmentId: options.environmentId,
|
|
7288
7712
|
contentModelOnly: options.contentModelOnly,
|
|
7289
7713
|
skipLocales: options.skipLocales,
|
|
7290
7714
|
skipContentModel: options.skipContentModel,
|
|
7291
7715
|
skipContentPublishing: options.skipContentPublishing,
|
|
7716
|
+
unpublishDraftLocales: options.unpublishDraftLocales,
|
|
7292
7717
|
skipAssetUpdates: options.skipAssetUpdates,
|
|
7293
7718
|
skipContentUpdates: options.skipContentUpdates,
|
|
7294
7719
|
timeout: options.timeout,
|
|
@@ -7330,9 +7755,9 @@ async function runContentfulImport(params) {
|
|
|
7330
7755
|
}).then((data) => {
|
|
7331
7756
|
const errorLog = log.filter((logMessage) => logMessage.level !== "info" && logMessage.level !== "warning");
|
|
7332
7757
|
const displayLog = log.filter((logMessage) => logMessage.level !== "info");
|
|
7333
|
-
|
|
7758
|
+
displayErrorLog(displayLog);
|
|
7334
7759
|
if (errorLog.length) {
|
|
7335
|
-
return (0,
|
|
7760
|
+
return (0, import_logging13.writeErrorLogFile)(options.errorLogFile, errorLog).then(() => {
|
|
7336
7761
|
const multiError = new ContentfulMultiError("Errors occurred");
|
|
7337
7762
|
multiError.name = "ContentfulMultiError";
|
|
7338
7763
|
multiError.errors = errorLog;
|