contentful-import 9.0.21 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,172 +1,1325 @@
1
- "use strict";
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
2
28
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
29
+ // lib/index.ts
30
+ var lib_exports = {};
31
+ __export(lib_exports, {
32
+ default: () => lib_default
5
33
  });
6
- exports.default = runContentfulImport;
7
- var _cliTable = _interopRequireDefault(require("cli-table3"));
8
- var _differenceInSeconds = _interopRequireDefault(require("date-fns/differenceInSeconds"));
9
- var _formatDistance = _interopRequireDefault(require("date-fns/formatDistance"));
10
- var _listr = _interopRequireDefault(require("listr"));
11
- var _listrUpdateRenderer = _interopRequireDefault(require("listr-update-renderer"));
12
- var _listrVerboseRenderer = _interopRequireDefault(require("listr-verbose-renderer"));
13
- var _lodash = require("lodash");
14
- var _pQueue = _interopRequireDefault(require("p-queue"));
15
- var _logging = require("contentful-batch-libs/dist/logging");
16
- var _listr2 = require("contentful-batch-libs/dist/listr");
17
- var _initClient = _interopRequireDefault(require("./tasks/init-client"));
18
- var _getDestinationData = _interopRequireDefault(require("./tasks/get-destination-data"));
19
- var _pushToSpace = _interopRequireDefault(require("./tasks/push-to-space/push-to-space"));
20
- var _transformSpace = _interopRequireDefault(require("./transform/transform-space"));
21
- var _validations = require("./utils/validations");
22
- var _parseOptions = _interopRequireDefault(require("./parseOptions"));
23
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
25
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
26
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
27
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
28
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
29
- const ONE_SECOND = 1000;
34
+ module.exports = __toCommonJS(lib_exports);
35
+ var import_cli_table3 = __toESM(require("cli-table3"));
36
+ var import_differenceInSeconds = __toESM(require("date-fns/differenceInSeconds"));
37
+ var import_formatDistance = __toESM(require("date-fns/formatDistance"));
38
+ var import_listr3 = __toESM(require("listr"));
39
+ var import_listr_update_renderer = __toESM(require("listr-update-renderer"));
40
+ var import_listr_verbose_renderer2 = __toESM(require("listr-verbose-renderer"));
41
+ var import_lodash = require("lodash");
42
+ var import_p_queue = __toESM(require("p-queue"));
43
+ var import_logging7 = require("contentful-batch-libs/dist/logging");
44
+ var import_listr4 = require("contentful-batch-libs/dist/listr");
45
+
46
+ // lib/tasks/init-client.js
47
+ var import_contentful_management = require("contentful-management");
48
+ var import_logging = require("contentful-batch-libs/dist/logging");
49
+ function logHandler(level, data) {
50
+ import_logging.logEmitter.emit(level, data);
51
+ }
52
+ function initClient(opts) {
53
+ const defaultOpts = {
54
+ timeout: 3e4,
55
+ logHandler
56
+ };
57
+ const config = {
58
+ ...defaultOpts,
59
+ ...opts
60
+ };
61
+ return (0, import_contentful_management.createClient)(config);
62
+ }
63
+
64
+ // lib/tasks/get-destination-data.js
65
+ var import_bluebird = __toESM(require("bluebird"));
66
+ var import_logging2 = require("contentful-batch-libs/dist/logging");
67
+ var BATCH_CHAR_LIMIT = 1990;
68
+ var BATCH_SIZE_LIMIT = 100;
69
+ var METHODS = {
70
+ contentTypes: { name: "content types", method: "getContentTypes" },
71
+ locales: { name: "locales", method: "getLocales" },
72
+ entries: { name: "entries", method: "getEntries" },
73
+ assets: { name: "assets", method: "getAssets" }
74
+ };
75
+ async function batchedIdQuery({ environment, type, ids, requestQueue }) {
76
+ const method = METHODS[type].method;
77
+ const entityTypeName = METHODS[type].name;
78
+ const batches = getIdBatches(ids);
79
+ let totalFetched = 0;
80
+ const allPendingResponses = batches.map((idBatch) => {
81
+ return requestQueue.add(async () => {
82
+ const response = await environment[method]({
83
+ "sys.id[in]": idBatch,
84
+ limit: idBatch.split(",").length
85
+ });
86
+ totalFetched = totalFetched + response.items.length;
87
+ import_logging2.logEmitter.emit("info", `Fetched ${totalFetched} of ${response.total} ${entityTypeName}`);
88
+ return response.items;
89
+ });
90
+ });
91
+ const responses = await import_bluebird.default.all(allPendingResponses);
92
+ return responses.flat();
93
+ }
94
+ function getIdBatches(ids) {
95
+ const batches = [];
96
+ let currentBatch = "";
97
+ let currentSize = 0;
98
+ while (ids.length > 0) {
99
+ const id = ids.splice(0, 1);
100
+ currentBatch += id;
101
+ currentSize = currentSize + 1;
102
+ if (currentSize === BATCH_SIZE_LIMIT || currentBatch.length > BATCH_CHAR_LIMIT || ids.length === 0) {
103
+ batches.push(currentBatch);
104
+ currentBatch = "";
105
+ currentSize = 0;
106
+ } else {
107
+ currentBatch += ",";
108
+ }
109
+ }
110
+ return batches;
111
+ }
112
+ async function getDestinationData({
113
+ client,
114
+ spaceId,
115
+ environmentId,
116
+ sourceData,
117
+ contentModelOnly,
118
+ skipLocales,
119
+ skipContentModel,
120
+ requestQueue
121
+ }) {
122
+ const space = await client.getSpace(spaceId);
123
+ const environment = await space.getEnvironment(environmentId);
124
+ const result = {
125
+ contentTypes: [],
126
+ tags: [],
127
+ locales: [],
128
+ entries: [],
129
+ assets: []
130
+ };
131
+ sourceData = {
132
+ ...result,
133
+ ...sourceData
134
+ };
135
+ if (!skipContentModel) {
136
+ const contentTypeIds = sourceData.contentTypes.map((e) => e.sys.id);
137
+ result.contentTypes = batchedIdQuery({
138
+ environment,
139
+ type: "contentTypes",
140
+ ids: contentTypeIds,
141
+ requestQueue
142
+ });
143
+ if (!skipLocales) {
144
+ const localeIds = sourceData.locales.map((e) => e.sys.id);
145
+ result.locales = batchedIdQuery({
146
+ environment,
147
+ type: "locales",
148
+ ids: localeIds,
149
+ requestQueue
150
+ });
151
+ }
152
+ }
153
+ result.tags = environment.getTags().then((response) => response.items).catch((e) => {
154
+ delete result.tags;
155
+ });
156
+ if (contentModelOnly) {
157
+ return import_bluebird.default.props(result);
158
+ }
159
+ const entryIds = sourceData.entries.map((e) => e.sys.id);
160
+ const assetIds = sourceData.assets.map((e) => e.sys.id);
161
+ result.entries = batchedIdQuery({
162
+ environment,
163
+ type: "entries",
164
+ ids: entryIds,
165
+ requestQueue
166
+ });
167
+ result.assets = batchedIdQuery({
168
+ environment,
169
+ type: "assets",
170
+ ids: assetIds,
171
+ requestQueue
172
+ });
173
+ result.webhooks = [];
174
+ return import_bluebird.default.props(result);
175
+ }
176
+
177
+ // lib/tasks/push-to-space/push-to-space.js
178
+ var import_listr = __toESM(require("listr"));
179
+ var import_listr_verbose_renderer = __toESM(require("listr-verbose-renderer"));
180
+ var import_logging6 = require("contentful-batch-libs/dist/logging");
181
+ var import_listr2 = require("contentful-batch-libs/dist/listr");
182
+
183
+ // lib/tasks/push-to-space/assets.js
184
+ var import_fs = __toESM(require("fs"));
185
+ var import_path = require("path");
186
+ var import_util = require("util");
187
+ var import_get_entity_name = __toESM(require("contentful-batch-libs/dist/get-entity-name"));
188
+ var import_logging3 = require("contentful-batch-libs/dist/logging");
189
+ var stat = (0, import_util.promisify)(import_fs.default.stat);
190
+ async function getAssetStreamForURL(url, assetsDirectory) {
191
+ const [, assetPath] = url.split("//");
192
+ const filePath = (0, import_path.join)(assetsDirectory, assetPath);
193
+ try {
194
+ await stat(filePath);
195
+ return import_fs.default.createReadStream(filePath);
196
+ } catch (err) {
197
+ const error = new Error("Cannot open asset from filesystem");
198
+ error.filePath = filePath;
199
+ throw error;
200
+ }
201
+ }
202
+ async function processAssetForLocale(locale, asset, processingOptions) {
203
+ try {
204
+ return await asset.processForLocale(locale, processingOptions);
205
+ } catch (err) {
206
+ err.entity = asset;
207
+ import_logging3.logEmitter.emit("error", err);
208
+ throw err;
209
+ }
210
+ }
211
+ async function lastResult(promises) {
212
+ if (!promises.length)
213
+ throw new RangeError("No last result from no promises");
214
+ const results = [];
215
+ await Promise.all(
216
+ promises.map(
217
+ (p) => p.then((v) => {
218
+ results.push(v);
219
+ })
220
+ )
221
+ );
222
+ return results[results.length - 1];
223
+ }
224
+ async function processAssets({
225
+ assets: assets2,
226
+ timeout,
227
+ retryLimit,
228
+ requestQueue
229
+ }) {
230
+ const processingOptions = Object.assign(
231
+ {},
232
+ timeout && { processingCheckWait: timeout },
233
+ retryLimit && { processingCheckRetry: retryLimit }
234
+ );
235
+ const pendingProcessingAssets = assets2.map(async (asset) => {
236
+ import_logging3.logEmitter.emit("info", `Processing Asset ${(0, import_get_entity_name.default)(asset)}`);
237
+ const locales2 = Object.keys(asset.fields.file || {});
238
+ let latestAssetVersion = asset;
239
+ try {
240
+ latestAssetVersion = await lastResult(
241
+ locales2.map((locale) => {
242
+ return requestQueue.add(
243
+ () => processAssetForLocale(locale, asset, processingOptions)
244
+ );
245
+ })
246
+ );
247
+ } catch (err) {
248
+ return null;
249
+ }
250
+ return latestAssetVersion;
251
+ });
252
+ const potentiallyProcessedAssets = await Promise.all(pendingProcessingAssets);
253
+ return potentiallyProcessedAssets.filter((asset) => asset);
254
+ }
255
+
256
+ // lib/tasks/push-to-space/creation.js
257
+ var import_collection = require("lodash/collection");
258
+ var import_object = require("lodash/object");
259
+ var import_get_entity_name2 = __toESM(require("contentful-batch-libs/dist/get-entity-name"));
260
+ var import_logging4 = require("contentful-batch-libs/dist/logging");
261
+ function createEntities({ context, entities, destinationEntitiesById, requestQueue }) {
262
+ return createEntitiesWithConcurrency({ context, entities, destinationEntitiesById, requestQueue });
263
+ }
264
+ function createLocales({ context, entities, destinationEntitiesById, requestQueue }) {
265
+ return createEntitiesInSequence({ context, entities, destinationEntitiesById, requestQueue });
266
+ }
267
+ async function createEntitiesWithConcurrency({ context, entities, destinationEntitiesById, requestQueue }) {
268
+ const pendingCreatedEntities = entities.map((entity) => {
269
+ const destinationEntity = getDestinationEntityForSourceEntity(destinationEntitiesById, entity.transformed);
270
+ const operation = destinationEntity ? "update" : "create";
271
+ return requestQueue.add(async () => {
272
+ try {
273
+ const createdEntity = await (destinationEntity ? updateDestinationWithSourceData(destinationEntity, entity.transformed) : createInDestination(context, entity.transformed));
274
+ creationSuccessNotifier(operation, createdEntity);
275
+ return createdEntity;
276
+ } catch (err) {
277
+ return handleCreationErrors(entity, err);
278
+ }
279
+ });
280
+ });
281
+ const createdEntities = await Promise.all(pendingCreatedEntities);
282
+ return createdEntities.filter((entity) => entity);
283
+ }
284
+ async function createEntitiesInSequence({ context, entities, destinationEntitiesById, requestQueue }) {
285
+ const createdEntities = [];
286
+ for (const entity of entities) {
287
+ const destinationEntity = getDestinationEntityForSourceEntity(destinationEntitiesById, entity.transformed);
288
+ const operation = destinationEntity ? "update" : "create";
289
+ try {
290
+ const createdEntity = await requestQueue.add(async () => {
291
+ const createdOrUpdatedEntity = await (destinationEntity ? updateDestinationWithSourceData(destinationEntity, entity.transformed) : createInDestination(context, entity.transformed));
292
+ return createdOrUpdatedEntity;
293
+ });
294
+ creationSuccessNotifier(operation, createdEntity);
295
+ createdEntities.push(createdEntity);
296
+ } catch (err) {
297
+ const maybeSubstituteEntity = handleCreationErrors(entity, err);
298
+ if (maybeSubstituteEntity) {
299
+ createdEntities.push(maybeSubstituteEntity);
300
+ }
301
+ }
302
+ }
303
+ return createdEntities;
304
+ }
305
+ async function createEntries({ context, entities, destinationEntitiesById, requestQueue }) {
306
+ const createdEntries = await Promise.all(entities.map((entry) => {
307
+ return createEntry({ entry, target: context.target, skipContentModel: context.skipContentModel, destinationEntitiesById, requestQueue });
308
+ }));
309
+ return createdEntries.filter((entry) => entry);
310
+ }
311
+ async function createEntry({ entry, target, skipContentModel, destinationEntitiesById, requestQueue }) {
312
+ const contentTypeId = entry.original.sys.contentType.sys.id;
313
+ const destinationEntry = getDestinationEntityForSourceEntity(
314
+ destinationEntitiesById,
315
+ entry.transformed
316
+ );
317
+ const operation = destinationEntry ? "update" : "create";
318
+ try {
319
+ const createdOrUpdatedEntry = await requestQueue.add(() => {
320
+ return destinationEntry ? updateDestinationWithSourceData(destinationEntry, entry.transformed) : createEntryInDestination(target, contentTypeId, entry.transformed);
321
+ });
322
+ creationSuccessNotifier(operation, createdOrUpdatedEntry);
323
+ return createdOrUpdatedEntry;
324
+ } catch (err) {
325
+ if (skipContentModel && err.name === "UnknownField") {
326
+ const errors = (0, import_object.get)(JSON.parse(err.message), "details.errors");
327
+ entry.transformed.fields = cleanupUnknownFields(entry.transformed.fields, errors);
328
+ return createEntry({ entry, target, skipContentModel, destinationEntitiesById, requestQueue });
329
+ }
330
+ err.entity = entry;
331
+ import_logging4.logEmitter.emit("error", err);
332
+ return null;
333
+ }
334
+ }
335
+ function updateDestinationWithSourceData(destinationEntity, sourceEntity) {
336
+ const plainData = getPlainData(sourceEntity);
337
+ (0, import_object.assign)(destinationEntity, plainData);
338
+ return destinationEntity.update();
339
+ }
340
+ function createInDestination(context, sourceEntity) {
341
+ const { type, target } = context;
342
+ if (type === "Tag") {
343
+ return createTagInDestination(context, sourceEntity);
344
+ }
345
+ const id = (0, import_object.get)(sourceEntity, "sys.id");
346
+ const plainData = getPlainData(sourceEntity);
347
+ return id ? target[`create${type}WithId`](id, plainData) : target[`create${type}`](plainData);
348
+ }
349
+ function createEntryInDestination(space, contentTypeId, sourceEntity) {
350
+ const id = sourceEntity.sys.id;
351
+ const plainData = getPlainData(sourceEntity);
352
+ return id ? space.createEntryWithId(contentTypeId, id, plainData) : space.createEntry(contentTypeId, plainData);
353
+ }
354
+ function createTagInDestination(context, sourceEntity) {
355
+ const id = sourceEntity.sys.id;
356
+ const visibility = sourceEntity.sys.visibility || "private";
357
+ const name = sourceEntity.name;
358
+ return context.target.createTag(id, name, visibility);
359
+ }
360
+ function handleCreationErrors(entity, err) {
361
+ if ((0, import_object.get)(err, "error.sys.id") === "ValidationFailed") {
362
+ const errors = (0, import_object.get)(err, "error.details.errors");
363
+ if (errors && errors.length > 0 && errors[0].name === "taken") {
364
+ return entity;
365
+ }
366
+ }
367
+ err.entity = entity.original;
368
+ import_logging4.logEmitter.emit("error", err);
369
+ return null;
370
+ }
371
+ function cleanupUnknownFields(fields, errors) {
372
+ return (0, import_object.omitBy)(fields, (field, fieldId) => {
373
+ return (0, import_collection.find)(errors, (error) => {
374
+ const [, errorFieldId] = error.path;
375
+ return error.name === "unknown" && errorFieldId === fieldId;
376
+ });
377
+ });
378
+ }
379
+ function getDestinationEntityForSourceEntity(destinationEntitiesById, sourceEntity) {
380
+ return destinationEntitiesById.get((0, import_object.get)(sourceEntity, "sys.id")) || null;
381
+ }
382
+ function creationSuccessNotifier(method, createdEntity) {
383
+ const verb = method[0].toUpperCase() + method.substr(1, method.length) + "d";
384
+ import_logging4.logEmitter.emit("info", `${verb} ${createdEntity.sys.type} ${(0, import_get_entity_name2.default)(createdEntity)}`);
385
+ return createdEntity;
386
+ }
387
+ function getPlainData(entity) {
388
+ const data = entity.toPlainObject ? entity.toPlainObject() : entity;
389
+ return (0, import_object.omit)(data, "sys");
390
+ }
391
+
392
+ // lib/tasks/push-to-space/publishing.js
393
+ var import_get_entity_name3 = __toESM(require("contentful-batch-libs/dist/get-entity-name"));
394
+ var import_logging5 = require("contentful-batch-libs/dist/logging");
395
+ async function publishEntities({ entities, requestQueue }) {
396
+ const entitiesToPublish = entities.filter((entity2) => {
397
+ if (!entity2 || !entity2.publish) {
398
+ import_logging5.logEmitter.emit("warning", `Unable to publish ${(0, import_get_entity_name3.default)(entity2)}`);
399
+ return false;
400
+ }
401
+ return true;
402
+ });
403
+ if (entitiesToPublish.length === 0) {
404
+ import_logging5.logEmitter.emit("info", "Skipping publishing since zero valid entities passed");
405
+ return [];
406
+ }
407
+ const entity = entities[0].original || entities[0];
408
+ const type = entity.sys.type || "unknown type";
409
+ import_logging5.logEmitter.emit("info", `Publishing ${entities.length} ${type}s`);
410
+ const result = await runQueue(entitiesToPublish, [], requestQueue);
411
+ import_logging5.logEmitter.emit("info", `Successfully published ${result.length} ${type}s`);
412
+ return result;
413
+ }
414
+ async function archiveEntities({ entities, requestQueue }) {
415
+ const entitiesToArchive = entities.filter((entity2) => {
416
+ if (!entity2 || !entity2.archive) {
417
+ import_logging5.logEmitter.emit("warning", `Unable to archive ${(0, import_get_entity_name3.default)(entity2)}`);
418
+ return false;
419
+ }
420
+ return true;
421
+ });
422
+ if (entitiesToArchive.length === 0) {
423
+ import_logging5.logEmitter.emit("info", "Skipping archiving since zero valid entities passed");
424
+ return [];
425
+ }
426
+ const entity = entities[0].original || entities[0];
427
+ const type = entity.sys.type || "unknown type";
428
+ import_logging5.logEmitter.emit("info", `Archiving ${entities.length} ${type}s`);
429
+ const pendingArchivedEntities = entitiesToArchive.map((entity2) => {
430
+ return requestQueue.add(async () => {
431
+ try {
432
+ const archivedEntity = await entity2.archive();
433
+ return archivedEntity;
434
+ } catch (err) {
435
+ err.entity = entity2;
436
+ import_logging5.logEmitter.emit("error", err);
437
+ return null;
438
+ }
439
+ });
440
+ });
441
+ const allPossiblyArchivedEntities = await Promise.all(pendingArchivedEntities);
442
+ const allArchivedEntities = allPossiblyArchivedEntities.filter((entity2) => entity2);
443
+ import_logging5.logEmitter.emit("info", `Successfully archived ${allArchivedEntities.length} ${type}s`);
444
+ return allArchivedEntities;
445
+ }
446
+ async function runQueue(queue, result = [], requestQueue) {
447
+ const publishedEntities = [];
448
+ for (const entity of queue) {
449
+ import_logging5.logEmitter.emit("info", `Publishing ${entity.sys.type} ${(0, import_get_entity_name3.default)(entity)}`);
450
+ try {
451
+ const publishedEntity = await requestQueue.add(() => entity.publish());
452
+ publishedEntities.push(publishedEntity);
453
+ } catch (err) {
454
+ err.entity = entity;
455
+ import_logging5.logEmitter.emit("error", err);
456
+ }
457
+ }
458
+ result = [
459
+ ...result,
460
+ ...publishedEntities
461
+ ];
462
+ const publishedEntityIds = new Set(publishedEntities.map((entity) => entity.sys.id));
463
+ const unpublishedEntities = queue.filter((entity) => !publishedEntityIds.has(entity.sys.id));
464
+ if (unpublishedEntities.length > 0) {
465
+ if (queue.length === unpublishedEntities.length) {
466
+ const unpublishedEntityNames = unpublishedEntities.map(import_get_entity_name3.default).join(", ");
467
+ import_logging5.logEmitter.emit("error", `Could not publish the following entities: ${unpublishedEntityNames}`);
468
+ } else {
469
+ return runQueue(unpublishedEntities, result, requestQueue);
470
+ }
471
+ }
472
+ return result;
473
+ }
474
+
475
+ // lib/tasks/push-to-space/push-to-space.js
476
+ var DEFAULT_CONTENT_STRUCTURE = {
477
+ entries: [],
478
+ assets: [],
479
+ contentTypes: [],
480
+ tags: [],
481
+ locales: [],
482
+ webhooks: [],
483
+ editorInterfaces: []
484
+ };
485
+ function pushToSpace({
486
+ sourceData,
487
+ destinationData = {},
488
+ client,
489
+ spaceId,
490
+ environmentId,
491
+ contentModelOnly,
492
+ skipContentModel,
493
+ skipLocales,
494
+ skipContentPublishing,
495
+ timeout,
496
+ retryLimit,
497
+ listrOptions,
498
+ uploadAssets,
499
+ assetsDirectory,
500
+ requestQueue
501
+ }) {
502
+ sourceData = {
503
+ ...DEFAULT_CONTENT_STRUCTURE,
504
+ ...sourceData
505
+ };
506
+ destinationData = {
507
+ ...DEFAULT_CONTENT_STRUCTURE,
508
+ ...destinationData
509
+ };
510
+ listrOptions = listrOptions || {
511
+ renderer: import_listr_verbose_renderer.default
512
+ };
513
+ const destinationDataById = {};
514
+ for (const [entityType, entities] of Object.entries(destinationData)) {
515
+ const entitiesById = /* @__PURE__ */ new Map();
516
+ for (const entity of entities) {
517
+ entitiesById.set(entity.sys.id, entity);
518
+ }
519
+ destinationDataById[entityType] = entitiesById;
520
+ }
521
+ return new import_listr.default([
522
+ {
523
+ title: "Connecting to space",
524
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
525
+ const space = await client.getSpace(spaceId);
526
+ const environment = await space.getEnvironment(environmentId);
527
+ ctx.space = space;
528
+ ctx.environment = environment;
529
+ })
530
+ },
531
+ {
532
+ title: "Importing Locales",
533
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
534
+ const locales2 = await createLocales({
535
+ context: { target: ctx.environment, type: "Locale" },
536
+ entities: sourceData.locales,
537
+ destinationEntitiesById: destinationDataById.locales,
538
+ requestQueue
539
+ });
540
+ ctx.data.locales = locales2;
541
+ }),
542
+ skip: () => skipContentModel || skipLocales
543
+ },
544
+ {
545
+ title: "Importing Content Types",
546
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
547
+ const contentTypes2 = await createEntities({
548
+ context: { target: ctx.environment, type: "ContentType" },
549
+ entities: sourceData.contentTypes,
550
+ destinationEntitiesById: destinationDataById.contentTypes,
551
+ requestQueue
552
+ });
553
+ ctx.data.contentTypes = contentTypes2;
554
+ }),
555
+ skip: () => skipContentModel
556
+ },
557
+ {
558
+ title: "Publishing Content Types",
559
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
560
+ const publishedContentTypes = await publishEntities2({
561
+ entities: ctx.data.contentTypes,
562
+ sourceEntities: sourceData.contentTypes,
563
+ requestQueue
564
+ });
565
+ ctx.data.contentTypes = publishedContentTypes;
566
+ }),
567
+ skip: (ctx) => skipContentModel
568
+ },
569
+ {
570
+ title: "Importing Tags",
571
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
572
+ const tags2 = await createEntities({
573
+ context: { target: ctx.environment, type: "Tag" },
574
+ entities: sourceData.tags,
575
+ destinationEntitiesById: destinationDataById.tags,
576
+ requestQueue
577
+ });
578
+ ctx.data.tags = tags2;
579
+ }),
580
+ // we remove `tags` from destination data if an error was thrown trying to access them
581
+ // this means the user doesn't have access to this feature, skip importing tags
582
+ skip: () => !destinationDataById.tags
583
+ },
584
+ {
585
+ title: "Importing Editor Interfaces",
586
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
587
+ const allEditorInterfacesBeingFetched = ctx.data.contentTypes.map(async (contentType) => {
588
+ const editorInterface = sourceData.editorInterfaces.find((editorInterface2) => {
589
+ return editorInterface2.sys.contentType.sys.id === contentType.sys.id;
590
+ });
591
+ if (!editorInterface) {
592
+ return;
593
+ }
594
+ try {
595
+ const ctEditorInterface = await requestQueue.add(() => ctx.environment.getEditorInterfaceForContentType(contentType.sys.id));
596
+ import_logging6.logEmitter.emit("info", `Fetched editor interface for ${contentType.name}`);
597
+ ctEditorInterface.controls = editorInterface.controls;
598
+ ctEditorInterface.groupControls = editorInterface.groupControls;
599
+ ctEditorInterface.editorLayout = editorInterface.editorLayout;
600
+ const updatedEditorInterface = await requestQueue.add(() => ctEditorInterface.update());
601
+ return updatedEditorInterface;
602
+ } catch (err) {
603
+ err.entity = editorInterface;
604
+ throw err;
605
+ }
606
+ });
607
+ const allEditorInterfaces = await Promise.all(allEditorInterfacesBeingFetched);
608
+ const editorInterfaces = allEditorInterfaces.filter((editorInterface) => editorInterface);
609
+ ctx.data.editorInterfaces = editorInterfaces;
610
+ }),
611
+ skip: (ctx) => skipContentModel || ctx.data.contentTypes.length === 0
612
+ },
613
+ {
614
+ title: "Uploading Assets",
615
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
616
+ const allPendingUploads = [];
617
+ for (const asset of sourceData.assets) {
618
+ for (const file of Object.values(asset.transformed.fields.file)) {
619
+ allPendingUploads.push(requestQueue.add(async () => {
620
+ try {
621
+ import_logging6.logEmitter.emit("info", `Uploading Asset file ${file.upload}`);
622
+ const assetStream = await getAssetStreamForURL(file.upload, assetsDirectory);
623
+ const upload = await ctx.environment.createUpload({
624
+ fileName: asset.transformed.sys.id,
625
+ file: assetStream
626
+ });
627
+ delete file.upload;
628
+ file.uploadFrom = {
629
+ sys: {
630
+ type: "Link",
631
+ linkType: "Upload",
632
+ id: upload.sys.id
633
+ }
634
+ };
635
+ return upload;
636
+ } catch (err) {
637
+ import_logging6.logEmitter.emit("error", err);
638
+ }
639
+ }));
640
+ }
641
+ }
642
+ const uploads = await Promise.all(allPendingUploads);
643
+ ctx.data.uploadedAssetFiles = uploads;
644
+ }),
645
+ skip: (ctx) => !uploadAssets || !sourceData.assets.length
646
+ },
647
+ {
648
+ title: "Importing Assets",
649
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
650
+ const assetsToProcess = await createEntities({
651
+ context: { target: ctx.environment, type: "Asset" },
652
+ entities: sourceData.assets,
653
+ destinationEntitiesById: destinationDataById.assets,
654
+ requestQueue
655
+ });
656
+ const processedAssets = await processAssets({
657
+ assets: assetsToProcess,
658
+ timeout,
659
+ retryLimit,
660
+ requestQueue
661
+ });
662
+ ctx.data.assets = processedAssets;
663
+ }),
664
+ skip: (ctx) => contentModelOnly
665
+ },
666
+ {
667
+ title: "Publishing Assets",
668
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
669
+ const publishedAssets = await publishEntities2({
670
+ entities: ctx.data.assets,
671
+ sourceEntities: sourceData.assets,
672
+ requestQueue
673
+ });
674
+ ctx.data.publishedAssets = publishedAssets;
675
+ }),
676
+ skip: (ctx) => contentModelOnly || skipContentPublishing
677
+ },
678
+ {
679
+ title: "Archiving Assets",
680
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
681
+ const archivedAssets = await archiveEntities2({
682
+ entities: ctx.data.assets,
683
+ sourceEntities: sourceData.assets,
684
+ requestQueue
685
+ });
686
+ ctx.data.archivedAssets = archivedAssets;
687
+ }),
688
+ skip: (ctx) => contentModelOnly || skipContentPublishing
689
+ },
690
+ {
691
+ title: "Importing Content Entries",
692
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
693
+ const entries2 = await createEntries({
694
+ context: { target: ctx.environment, skipContentModel },
695
+ entities: sourceData.entries,
696
+ destinationEntitiesById: destinationDataById.entries,
697
+ requestQueue
698
+ });
699
+ ctx.data.entries = entries2;
700
+ }),
701
+ skip: (ctx) => contentModelOnly
702
+ },
703
+ {
704
+ title: "Publishing Content Entries",
705
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
706
+ const publishedEntries = await publishEntities2({
707
+ entities: ctx.data.entries,
708
+ sourceEntities: sourceData.entries,
709
+ requestQueue
710
+ });
711
+ ctx.data.publishedEntries = publishedEntries;
712
+ }),
713
+ skip: (ctx) => contentModelOnly || skipContentPublishing
714
+ },
715
+ {
716
+ title: "Archiving Entries",
717
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
718
+ const archivedEntries = await archiveEntities2({
719
+ entities: ctx.data.entries,
720
+ sourceEntities: sourceData.entries,
721
+ requestQueue
722
+ });
723
+ ctx.data.archivedEntries = archivedEntries;
724
+ }),
725
+ skip: (ctx) => contentModelOnly || skipContentPublishing
726
+ },
727
+ {
728
+ title: "Creating Web Hooks",
729
+ task: (0, import_listr2.wrapTask)(async (ctx, task) => {
730
+ const webhooks2 = await createEntities({
731
+ context: { target: ctx.space, type: "Webhook" },
732
+ entities: sourceData.webhooks,
733
+ destinationEntitiesById: destinationDataById.webhooks,
734
+ requestQueue
735
+ });
736
+ ctx.data.webhooks = webhooks2;
737
+ }),
738
+ skip: (ctx) => contentModelOnly || environmentId !== "master" && "Webhooks can only be imported in master environment"
739
+ }
740
+ ], listrOptions);
741
+ }
742
+ function archiveEntities2({ entities, sourceEntities, requestQueue }) {
743
+ const entityIdsToArchive = sourceEntities.filter(({ original }) => original.sys.archivedVersion).map(({ original }) => original.sys.id);
744
+ const entitiesToArchive = entities.filter((entity) => entityIdsToArchive.indexOf(entity.sys.id) !== -1);
745
+ return archiveEntities({ entities: entitiesToArchive, requestQueue });
746
+ }
747
+ function publishEntities2({ entities, sourceEntities, requestQueue }) {
748
+ const entityIdsToPublish = sourceEntities.filter(({ original }) => original.sys.publishedVersion).map(({ original }) => original.sys.id);
749
+ const entitiesToPublish = entities.filter((entity) => entityIdsToPublish.indexOf(entity.sys.id) !== -1);
750
+ return publishEntities({ entities: entitiesToPublish, requestQueue });
751
+ }
752
+
753
+ // lib/transform/transform-space.js
754
+ var import_object3 = require("lodash/object");
755
+
756
+ // lib/transform/transformers.js
757
+ var transformers_exports = {};
758
+ __export(transformers_exports, {
759
+ assets: () => assets,
760
+ contentTypes: () => contentTypes,
761
+ entries: () => entries,
762
+ locales: () => locales,
763
+ tags: () => tags,
764
+ webhooks: () => webhooks
765
+ });
766
+ var import_object2 = require("lodash/object");
767
+ var import_collection2 = require("lodash/collection");
768
+ function contentTypes(contentType) {
769
+ return contentType;
770
+ }
771
+ function tags(tag) {
772
+ return tag;
773
+ }
774
+ function entries(entry, _, tagsEnabled = false) {
775
+ return removeMetadataTags(entry, tagsEnabled);
776
+ }
777
+ function webhooks(webhook) {
778
+ if (webhook.httpBasicUsername) {
779
+ delete webhook.httpBasicUsername;
780
+ }
781
+ if (webhook.headers) {
782
+ webhook.headers = webhook.headers.filter((header) => !header.secret);
783
+ }
784
+ return webhook;
785
+ }
786
+ function assets(asset, _, tagsEnabled = false) {
787
+ const transformedAsset = (0, import_object2.omit)(asset, "sys");
788
+ transformedAsset.sys = (0, import_object2.pick)(asset.sys, "id");
789
+ transformedAsset.fields = (0, import_object2.pick)(asset.fields, "title", "description");
790
+ transformedAsset.fields.file = (0, import_collection2.reduce)(
791
+ asset.fields.file,
792
+ (newFile, localizedFile, locale) => {
793
+ newFile[locale] = (0, import_object2.pick)(localizedFile, "contentType", "fileName");
794
+ if (!localizedFile.uploadFrom) {
795
+ const assetUrl = localizedFile.url || localizedFile.upload;
796
+ newFile[locale].upload = `${/^(http|https):\/\//i.test(assetUrl) ? "" : "https:"}${assetUrl}`;
797
+ } else {
798
+ newFile[locale].uploadFrom = localizedFile.uploadFrom;
799
+ }
800
+ return newFile;
801
+ },
802
+ {}
803
+ );
804
+ return removeMetadataTags(transformedAsset, tagsEnabled);
805
+ }
806
+ function locales(locale, destinationLocales) {
807
+ const transformedLocale = (0, import_object2.pick)(locale, "code", "name", "contentManagementApi", "contentDeliveryApi", "fallbackCode", "optional");
808
+ const destinationLocale = (0, import_collection2.find)(destinationLocales, { code: locale.code });
809
+ if (destinationLocale) {
810
+ transformedLocale.sys = (0, import_object2.pick)(destinationLocale.sys, "id");
811
+ }
812
+ return transformedLocale;
813
+ }
814
+ function removeMetadataTags(entity, tagsEnabled = false) {
815
+ if (!tagsEnabled) {
816
+ delete entity.metadata;
817
+ }
818
+ return entity;
819
+ }
820
+
821
+ // lib/utils/sort-entries.js
822
+ var import_collection3 = require("lodash/collection");
823
+ var _o = __toESM(require("lodash/object"));
824
+ var import_array = require("lodash/array");
825
+ function sortEntries(entries2) {
826
+ const linkedEntries = getLinkedEntries(entries2);
827
+ const mergedLinkedEntries = mergeSort(linkedEntries, (a) => {
828
+ return hasLinkedIndexesInFront(a);
829
+ });
830
+ return (0, import_collection3.map)(mergedLinkedEntries, (linkInfo) => entries2[linkInfo.index]);
831
+ function hasLinkedIndexesInFront(item) {
832
+ if (hasLinkedIndexes(item)) {
833
+ return (0, import_collection3.some)(item.linkIndexes, (index) => index > item.index) ? 1 : -1;
834
+ }
835
+ return 0;
836
+ }
837
+ function hasLinkedIndexes(item) {
838
+ return item.linkIndexes.length > 0;
839
+ }
840
+ }
841
+ function getLinkedEntries(entries2) {
842
+ return (0, import_collection3.map)(entries2, function(entry) {
843
+ const entryIndex = entries2.indexOf(entry);
844
+ const rawLinks = (0, import_collection3.map)(entry.fields, (field) => {
845
+ field = _o.values(field)[0];
846
+ if (isEntryLink(field)) {
847
+ return getFieldEntriesIndex(field, entries2);
848
+ } else if (isEntityArray(field) && isEntryLink(field[0])) {
849
+ return (0, import_collection3.map)(field, (item) => getFieldEntriesIndex(item, entries2));
850
+ }
851
+ });
852
+ return {
853
+ index: entryIndex,
854
+ linkIndexes: (0, import_collection3.filter)((0, import_array.flatten)(rawLinks), (index) => index >= 0)
855
+ };
856
+ });
857
+ }
858
+ function getFieldEntriesIndex(field, entries2) {
859
+ const id = _o.get(field, "sys.id");
860
+ return entries2.findIndex((entry) => entry.sys.id === id);
861
+ }
862
+ function isEntryLink(item) {
863
+ return _o.get(item, "sys.type") === "Entry" || _o.get(item, "sys.linkType") === "Entry";
864
+ }
865
+ function isEntityArray(item) {
866
+ return Array.isArray(item) && item.length > 0 && _o.has(item[0], "sys");
867
+ }
868
+ function mergeSort(arr, compareFn) {
869
+ if (arr.length < 2)
870
+ return arr;
871
+ if (compareFn == null)
872
+ compareFn = defaultCompare;
873
+ const mid = ~~(arr.length / 2);
874
+ const left = mergeSort(arr.slice(0, mid), compareFn);
875
+ const right = mergeSort(arr.slice(mid, arr.length), compareFn);
876
+ return merge(left, right, compareFn);
877
+ }
878
+ function defaultCompare(a, b) {
879
+ return a < b ? -1 : a > b ? 1 : 0;
880
+ }
881
+ function merge(left, right, compareFn) {
882
+ const result = [];
883
+ while (left.length && right.length) {
884
+ if (compareFn(left[0], right[0]) <= 0) {
885
+ result.push(left.shift());
886
+ } else {
887
+ result.push(right.shift());
888
+ }
889
+ }
890
+ if (left.length)
891
+ result.push.apply(result, left);
892
+ if (right.length)
893
+ result.push.apply(result, right);
894
+ return result;
895
+ }
896
+
897
+ // lib/utils/sort-locales.js
898
+ function sortLocales(locales2) {
899
+ const localeByFallback = {};
900
+ locales2.forEach((locale) => {
901
+ if (locale.fallbackCode === null) {
902
+ locale.fallbackCode = void 0;
903
+ }
904
+ if (!localeByFallback[locale.fallbackCode]) {
905
+ localeByFallback[locale.fallbackCode] = [];
906
+ }
907
+ localeByFallback[locale.fallbackCode].push(locale);
908
+ });
909
+ return sortByFallbackKey(localeByFallback);
910
+ }
911
+ function sortByFallbackKey(localeByFallback, key) {
912
+ if (!localeByFallback[key]) {
913
+ return [];
914
+ }
915
+ const sortedLocales = localeByFallback[key];
916
+ sortedLocales.forEach((locale) => {
917
+ sortByFallbackKey(localeByFallback, locale.code).forEach((x) => sortedLocales.push(x));
918
+ });
919
+ sortedLocales.forEach((locale) => {
920
+ if (!locale.fallbackCode) {
921
+ locale.fallbackCode = null;
922
+ }
923
+ });
924
+ return sortedLocales;
925
+ }
926
+
927
+ // lib/transform/transform-space.js
928
+ var spaceEntities = [
929
+ "contentTypes",
930
+ "entries",
931
+ "assets",
932
+ "locales",
933
+ "webhooks",
934
+ "tags"
935
+ ];
936
+ function transform_space_default(sourceData, destinationData, customTransformers, entities = spaceEntities) {
937
+ const transformers = (0, import_object3.defaults)(customTransformers, transformers_exports);
938
+ const baseSpaceData = (0, import_object3.omit)(sourceData, ...entities);
939
+ sourceData.locales = sortLocales(sourceData.locales);
940
+ const tagsEnabled = !!destinationData.tags;
941
+ return entities.reduce((transformedSpaceData, type) => {
942
+ const sortedEntities = type === "tags" ? sourceData[type] : sortEntries(sourceData[type]);
943
+ const transformedEntities = sortedEntities.map((entity) => ({
944
+ original: entity,
945
+ transformed: transformers[type](entity, destinationData[type], tagsEnabled)
946
+ }));
947
+ transformedSpaceData[type] = transformedEntities;
948
+ return transformedSpaceData;
949
+ }, baseSpaceData);
950
+ }
951
+
952
+ // lib/utils/schema.js
953
+ var import_joi = __toESM(require("joi"));
954
+ var entrySchema = {
955
+ sys: import_joi.default.object(),
956
+ fields: import_joi.default.object()
957
+ };
958
+ var tagSchema = {
959
+ name: import_joi.default.string().required(),
960
+ sys: import_joi.default.object()
961
+ };
962
+ var contentTypeSchema = {
963
+ sys: import_joi.default.object(),
964
+ fields: import_joi.default.array().required().items(import_joi.default.object().keys({
965
+ id: import_joi.default.string().required(),
966
+ name: import_joi.default.string().required(),
967
+ type: import_joi.default.string().required().regex(/^Symbol|Text|Integer|Number|Date|Object|Boolean|Array|Link|Location$/),
968
+ validations: import_joi.default.array(),
969
+ disabled: import_joi.default.boolean(),
970
+ omitted: import_joi.default.boolean(),
971
+ required: import_joi.default.boolean(),
972
+ localized: import_joi.default.boolean(),
973
+ linkType: import_joi.default.string().when("type", { is: "Link", then: import_joi.default.string().regex(/^Asset|Entry$/), otherwise: import_joi.default.forbidden() })
974
+ }))
975
+ };
976
+ var assetSchema = {
977
+ sys: import_joi.default.object(),
978
+ fields: import_joi.default.object({
979
+ file: import_joi.default.object().pattern(/.+/, import_joi.default.object({
980
+ url: import_joi.default.string().required(),
981
+ details: import_joi.default.object({
982
+ size: import_joi.default.number(),
983
+ image: import_joi.default.object({
984
+ width: import_joi.default.number(),
985
+ height: import_joi.default.number()
986
+ })
987
+ }),
988
+ fileName: import_joi.default.string().required(),
989
+ contentType: import_joi.default.string().required()
990
+ }))
991
+ }).required()
992
+ };
993
+ var editorInterfaceSchema = {
994
+ sys: import_joi.default.object(),
995
+ controls: import_joi.default.array().items({ fieldId: import_joi.default.string(), widgetId: import_joi.default.string() })
996
+ };
997
+ var localeSchema = {
998
+ name: import_joi.default.string().required(),
999
+ internal_code: import_joi.default.string(),
1000
+ code: import_joi.default.string().required(),
1001
+ fallbackCode: import_joi.default.string().allow(null),
1002
+ default: import_joi.default.boolean(),
1003
+ contentManagementApi: import_joi.default.boolean(),
1004
+ contentDeliveryApi: import_joi.default.boolean(),
1005
+ optional: import_joi.default.boolean(),
1006
+ sys: import_joi.default.object()
1007
+ };
1008
+ var webhookSchema = {
1009
+ name: import_joi.default.string(),
1010
+ url: import_joi.default.string().replace(/{[^}{]+?}/g, "x").regex(/^https?:\/\/[^ /}{][^ }{]*$/i).required(),
1011
+ topics: import_joi.default.array().required(),
1012
+ httpBasicUsername: import_joi.default.string().allow("", null)
1013
+ };
1014
+ var payloadSchema = import_joi.default.object({
1015
+ entries: import_joi.default.array().items(entrySchema),
1016
+ contentTypes: import_joi.default.array().items(contentTypeSchema),
1017
+ tags: import_joi.default.array().items(tagSchema),
1018
+ assets: import_joi.default.array().items(assetSchema),
1019
+ locales: import_joi.default.array().items(localeSchema),
1020
+ editorInterfaces: import_joi.default.array().items(editorInterfaceSchema),
1021
+ webhooks: import_joi.default.array().items(webhookSchema)
1022
+ });
1023
+
1024
+ // lib/utils/validations.js
1025
+ var import_get_entity_name4 = __toESM(require("contentful-batch-libs/dist/get-entity-name"));
1026
+ var attachEntityName = (details, payload) => {
1027
+ details.map((detail) => {
1028
+ if (detail.path.length >= 2) {
1029
+ detail.entity = (0, import_get_entity_name4.default)(payload[detail.path[0]][detail.path[1]]);
1030
+ }
1031
+ return detail;
1032
+ });
1033
+ };
1034
+ var countInvalidEntities = (validationData) => {
1035
+ const entityCount = validationData.reduce((entities, currentDetail) => {
1036
+ if (!entities[currentDetail.path[0]]) {
1037
+ entities[currentDetail.path[0]] = 1;
1038
+ } else {
1039
+ entities[currentDetail.path[0]]++;
1040
+ }
1041
+ return entities;
1042
+ }, {});
1043
+ return Object.keys(entityCount).map((key) => `${key}:${entityCount[key]}`);
1044
+ };
1045
+ var assertPayload = (payload) => {
1046
+ const result = payloadSchema.validate(payload, { allowUnknown: true, abortEarly: false });
1047
+ if (result.error) {
1048
+ attachEntityName(result.error.details, payload);
1049
+ const invalidEntityCount = countInvalidEntities(result.error.details).join(", ");
1050
+ result.error.message = `${invalidEntityCount} - Get further details in the error log file`;
1051
+ delete result.error._object;
1052
+ throw result.error;
1053
+ }
1054
+ };
1055
+ var assertDefaultLocale = (source, destination) => {
1056
+ const sourceDefaultLocale = source.locales.find((locale) => locale.default === true);
1057
+ const destinationDefaultLocale = destination.locales.find((locale) => locale.default === true);
1058
+ if (!sourceDefaultLocale || !destinationDefaultLocale) {
1059
+ return;
1060
+ }
1061
+ if (sourceDefaultLocale.code !== destinationDefaultLocale.code) {
1062
+ throw new Error(`
1063
+ Please make sure the destination space have the same default locale as the source
1064
+
1065
+ Default locale for source space : ${sourceDefaultLocale.code}
1066
+
1067
+ Default locale for destination space: ${destinationDefaultLocale.code}
1068
+
1069
+ `);
1070
+ }
1071
+ };
1072
+
1073
+ // lib/parseOptions.js
1074
+ var import_fs2 = __toESM(require("fs"));
1075
+ var import_path2 = require("path");
1076
+ var import_format = __toESM(require("date-fns/format"));
1077
+
1078
+ // package.json
1079
+ var version = "0.0.0-determined-by-semantic-release";
1080
+
1081
+ // lib/utils/headers.js
1082
+ function getHeadersConfig(value) {
1083
+ if (!value) {
1084
+ return {};
1085
+ }
1086
+ const values2 = Array.isArray(value) ? value : [value];
1087
+ return values2.reduce((headers, value2) => {
1088
+ value2 = value2.trim();
1089
+ const separatorIndex = value2.indexOf(":");
1090
+ if (separatorIndex === -1) {
1091
+ return headers;
1092
+ }
1093
+ const headerKey = value2.slice(0, separatorIndex).trim();
1094
+ const headerValue = value2.slice(separatorIndex + 1).trim();
1095
+ return {
1096
+ ...headers,
1097
+ [headerKey]: headerValue
1098
+ };
1099
+ }, {});
1100
+ }
1101
+
1102
+ // lib/parseOptions.js
1103
+ var import_proxy = require("contentful-batch-libs/dist/proxy");
1104
+ var import_add_sequence_header = __toESM(require("contentful-batch-libs/dist/add-sequence-header"));
1105
+ var import_json_ext = require("@discoveryjs/json-ext");
1106
+ var SUPPORTED_ENTITY_TYPES = [
1107
+ "contentTypes",
1108
+ "tags",
1109
+ "entries",
1110
+ "assets",
1111
+ "locales",
1112
+ "webhooks",
1113
+ "editorInterfaces"
1114
+ ];
1115
+ async function parseOptions(params) {
1116
+ const defaultOptions = {
1117
+ skipContentModel: false,
1118
+ skipLocales: false,
1119
+ skipContentPublishing: false,
1120
+ useVerboseRenderer: false,
1121
+ environmentId: "master",
1122
+ rawProxy: false,
1123
+ uploadAssets: false,
1124
+ rateLimit: 7
1125
+ };
1126
+ const configFile = params.config ? require((0, import_path2.resolve)(process.cwd(), params.config)) : {};
1127
+ const options = {
1128
+ ...defaultOptions,
1129
+ ...configFile,
1130
+ ...params,
1131
+ headers: (0, import_add_sequence_header.default)(params.headers || getHeadersConfig(params.header))
1132
+ };
1133
+ if (!options.spaceId) {
1134
+ throw new Error("The `spaceId` option is required.");
1135
+ }
1136
+ if (!options.managementToken) {
1137
+ throw new Error("The `managementToken` option is required.");
1138
+ }
1139
+ if (!options.contentFile && !options.content) {
1140
+ throw new Error("Either the `contentFile` or `content` option are required.");
1141
+ }
1142
+ if (options.contentModelOnly && options.skipContentModel) {
1143
+ throw new Error("`contentModelOnly` and `skipContentModel` cannot be used together");
1144
+ }
1145
+ if (options.skipLocales && !options.contentModelOnly) {
1146
+ throw new Error("`skipLocales` can only be used together with `contentModelOnly`");
1147
+ }
1148
+ const proxySimpleExp = /.+:\d+/;
1149
+ const proxyAuthExp = /.+:.+@.+:\d+/;
1150
+ if (typeof options.proxy === "string" && options.proxy && !(proxySimpleExp.test(options.proxy) || proxyAuthExp.test(options.proxy))) {
1151
+ throw new Error("Please provide the proxy config in the following format:\nhost:port or user:password@host:port");
1152
+ }
1153
+ options.startTime = /* @__PURE__ */ new Date();
1154
+ if (!options.errorLogFile) {
1155
+ options.errorLogFile = (0, import_path2.resolve)(process.cwd(), `contentful-import-error-log-${options.spaceId}-${(0, import_format.default)(options.startTime, "yyyy-MM-dd'T'HH-mm-ss")}.json`);
1156
+ } else {
1157
+ options.errorLogFile = (0, import_path2.resolve)(process.cwd(), options.errorLogFile);
1158
+ }
1159
+ options.accessToken = options.managementToken;
1160
+ if (!options.content) {
1161
+ const fileStream = import_fs2.default.createReadStream(options.contentFile, { encoding: "utf8" });
1162
+ options.content = await (0, import_json_ext.parseChunked)(fileStream);
1163
+ }
1164
+ Object.keys(options.content).forEach((type) => {
1165
+ if (SUPPORTED_ENTITY_TYPES.indexOf(type) === -1) {
1166
+ delete options.content[type];
1167
+ }
1168
+ });
1169
+ SUPPORTED_ENTITY_TYPES.forEach((type) => {
1170
+ options.content[type] = options.content[type] || [];
1171
+ });
1172
+ if (typeof options.proxy === "string") {
1173
+ options.proxy = (0, import_proxy.proxyStringToObject)(options.proxy);
1174
+ }
1175
+ if (!options.rawProxy && options.proxy) {
1176
+ options.httpsAgent = (0, import_proxy.agentFromProxy)(options.proxy);
1177
+ delete options.proxy;
1178
+ }
1179
+ options.application = options.managementApplication || `contentful.import/${version}`;
1180
+ options.feature = options.managementFeature || "library-import";
1181
+ return options;
1182
+ }
1183
+
1184
+ // lib/index.ts
1185
+ var ONE_SECOND = 1e3;
30
1186
  function createListrOptions(options) {
31
1187
  if (options.useVerboseRenderer) {
32
1188
  return {
33
- renderer: _listrVerboseRenderer.default
1189
+ renderer: import_listr_verbose_renderer2.default
34
1190
  };
35
1191
  }
36
1192
  return {
37
- renderer: _listrUpdateRenderer.default,
1193
+ renderer: import_listr_update_renderer.default,
38
1194
  collapse: false
39
1195
  };
40
1196
  }
41
1197
  async function runContentfulImport(params) {
42
1198
  const log = [];
43
- const options = await (0, _parseOptions.default)(params);
1199
+ const options = await parseOptions(params);
44
1200
  const listrOptions = createListrOptions(options);
45
- const requestQueue = new _pQueue.default({
1201
+ const requestQueue = new import_p_queue.default({
46
1202
  interval: ONE_SECOND,
47
1203
  intervalCap: options.rateLimit,
48
1204
  carryoverConcurrencyCount: true
49
1205
  });
50
-
51
- // Setup custom log listener to store log messages for later
52
- (0, _logging.setupLogging)(log);
53
- const infoTable = new _cliTable.default();
54
- infoTable.push([{
55
- colSpan: 2,
56
- content: 'The following entities are going to be imported:'
57
- }]);
58
- Object.keys(options.content).forEach(type => {
59
- if (options.skipLocales && type === 'locales') {
1206
+ (0, import_logging7.setupLogging)(log);
1207
+ const infoTable = new import_cli_table3.default();
1208
+ infoTable.push([{ colSpan: 2, content: "The following entities are going to be imported:" }]);
1209
+ Object.keys(options.content).forEach((type) => {
1210
+ if (options.skipLocales && type === "locales") {
60
1211
  return;
61
1212
  }
62
- if (options.skipContentModel && ['contentTypes', 'editorInterfaces'].indexOf(type) >= 0) {
1213
+ if (options.skipContentModel && ["contentTypes", "editorInterfaces"].indexOf(type) >= 0) {
63
1214
  return;
64
1215
  }
65
- if (options.contentModelOnly && !(['contentTypes', 'editorInterfaces', 'locales'].indexOf(type) >= 0)) {
1216
+ if (options.contentModelOnly && !(["contentTypes", "editorInterfaces", "locales"].indexOf(type) >= 0)) {
66
1217
  return;
67
1218
  }
68
- infoTable.push([(0, _lodash.startCase)(type), options.content[type].length]);
1219
+ infoTable.push([(0, import_lodash.startCase)(type), options.content[type].length]);
69
1220
  });
70
1221
  console.log(infoTable.toString());
71
- const tasks = new _listr.default([{
72
- title: 'Validating content-file',
73
- task: ctx => {
74
- (0, _validations.assertPayload)(options.content);
75
- }
76
- }, {
77
- title: 'Initialize client',
78
- task: (0, _listr2.wrapTask)(async ctx => {
79
- ctx.client = (0, _initClient.default)(_objectSpread(_objectSpread({}, options), {}, {
80
- content: undefined
81
- }));
82
- })
83
- }, {
84
- title: 'Checking if destination space already has any content and retrieving it',
85
- task: (0, _listr2.wrapTask)(async (ctx, task) => {
86
- const destinationData = await (0, _getDestinationData.default)({
87
- client: ctx.client,
88
- spaceId: options.spaceId,
89
- environmentId: options.environmentId,
90
- sourceData: options.content,
91
- skipLocales: options.skipLocales,
92
- skipContentModel: options.skipContentModel,
93
- requestQueue
94
- });
95
- ctx.sourceDataUntransformed = options.content;
96
- ctx.destinationData = destinationData;
97
- (0, _validations.assertDefaultLocale)(ctx.sourceDataUntransformed, ctx.destinationData);
98
- })
99
- }, {
100
- title: 'Apply transformations to source data',
101
- task: (0, _listr2.wrapTask)(async ctx => {
102
- const transformedSourceData = (0, _transformSpace.default)(ctx.sourceDataUntransformed, ctx.destinationData);
103
- ctx.sourceData = transformedSourceData;
104
- })
105
- }, {
106
- title: 'Push content to destination space',
107
- task: (ctx, task) => {
108
- return (0, _pushToSpace.default)({
109
- sourceData: ctx.sourceData,
110
- destinationData: ctx.destinationData,
111
- client: ctx.client,
112
- spaceId: options.spaceId,
113
- environmentId: options.environmentId,
114
- contentModelOnly: options.contentModelOnly,
115
- skipLocales: options.skipLocales,
116
- skipContentModel: options.skipContentModel,
117
- skipContentPublishing: options.skipContentPublishing,
118
- timeout: options.timeout,
119
- retryLimit: options.retryLimit,
120
- uploadAssets: options.uploadAssets,
121
- assetsDirectory: options.assetsDirectory,
122
- listrOptions,
123
- requestQueue
124
- });
1222
+ const tasks = new import_listr3.default([
1223
+ {
1224
+ title: "Validating content-file",
1225
+ task: (ctx) => {
1226
+ assertPayload(options.content);
1227
+ }
1228
+ },
1229
+ {
1230
+ title: "Initialize client",
1231
+ task: (0, import_listr4.wrapTask)(async (ctx) => {
1232
+ ctx.client = initClient({ ...options, content: void 0 });
1233
+ })
1234
+ },
1235
+ {
1236
+ title: "Checking if destination space already has any content and retrieving it",
1237
+ task: (0, import_listr4.wrapTask)(async (ctx, task) => {
1238
+ const destinationData = await getDestinationData({
1239
+ client: ctx.client,
1240
+ spaceId: options.spaceId,
1241
+ environmentId: options.environmentId,
1242
+ sourceData: options.content,
1243
+ skipLocales: options.skipLocales,
1244
+ skipContentModel: options.skipContentModel,
1245
+ requestQueue
1246
+ });
1247
+ ctx.sourceDataUntransformed = options.content;
1248
+ ctx.destinationData = destinationData;
1249
+ assertDefaultLocale(ctx.sourceDataUntransformed, ctx.destinationData);
1250
+ })
1251
+ },
1252
+ {
1253
+ title: "Apply transformations to source data",
1254
+ task: (0, import_listr4.wrapTask)(async (ctx) => {
1255
+ const transformedSourceData = transform_space_default(ctx.sourceDataUntransformed, ctx.destinationData);
1256
+ ctx.sourceData = transformedSourceData;
1257
+ })
1258
+ },
1259
+ {
1260
+ title: "Push content to destination space",
1261
+ task: (ctx, task) => {
1262
+ return pushToSpace({
1263
+ sourceData: ctx.sourceData,
1264
+ destinationData: ctx.destinationData,
1265
+ client: ctx.client,
1266
+ spaceId: options.spaceId,
1267
+ environmentId: options.environmentId,
1268
+ contentModelOnly: options.contentModelOnly,
1269
+ skipLocales: options.skipLocales,
1270
+ skipContentModel: options.skipContentModel,
1271
+ skipContentPublishing: options.skipContentPublishing,
1272
+ timeout: options.timeout,
1273
+ retryLimit: options.retryLimit,
1274
+ uploadAssets: options.uploadAssets,
1275
+ assetsDirectory: options.assetsDirectory,
1276
+ listrOptions,
1277
+ requestQueue
1278
+ });
1279
+ }
125
1280
  }
126
- }], listrOptions);
1281
+ ], listrOptions);
127
1282
  return tasks.run({
128
1283
  data: {}
129
- }).then(ctx => {
130
- console.log('Finished importing all data');
1284
+ }).then((ctx) => {
1285
+ console.log("Finished importing all data");
131
1286
  const resultTypes = Object.keys(ctx.data);
132
1287
  if (resultTypes.length) {
133
- const resultTable = new _cliTable.default();
134
- resultTable.push([{
135
- colSpan: 2,
136
- content: 'Imported entities'
137
- }]);
138
- resultTypes.forEach(type => {
139
- resultTable.push([(0, _lodash.startCase)(type), ctx.data[type].length]);
1288
+ const resultTable = new import_cli_table3.default();
1289
+ resultTable.push([{ colSpan: 2, content: "Imported entities" }]);
1290
+ resultTypes.forEach((type) => {
1291
+ resultTable.push([(0, import_lodash.startCase)(type), ctx.data[type].length]);
140
1292
  });
141
1293
  console.log(resultTable.toString());
142
1294
  } else {
143
- console.log('No data was imported');
1295
+ console.log("No data was imported");
144
1296
  }
145
- const endTime = new Date();
146
- const durationHuman = (0, _formatDistance.default)(endTime, options.startTime);
147
- const durationSeconds = (0, _differenceInSeconds.default)(endTime, options.startTime);
1297
+ const endTime = /* @__PURE__ */ new Date();
1298
+ const durationHuman = (0, import_formatDistance.default)(endTime, options.startTime);
1299
+ const durationSeconds = (0, import_differenceInSeconds.default)(endTime, options.startTime);
148
1300
  console.log(`The import took ${durationHuman} (${durationSeconds}s)`);
149
1301
  return ctx.data;
150
- }).catch(err => {
1302
+ }).catch((err) => {
151
1303
  log.push({
152
- ts: new Date().toJSON(),
153
- level: 'error',
1304
+ ts: (/* @__PURE__ */ new Date()).toJSON(),
1305
+ level: "error",
154
1306
  error: err
155
1307
  });
156
- }).then(data => {
157
- const errorLog = log.filter(logMessage => logMessage.level !== 'info' && logMessage.level !== 'warning');
158
- const displayLog = log.filter(logMessage => logMessage.level !== 'info');
159
- (0, _logging.displayErrorLog)(displayLog);
1308
+ }).then((data) => {
1309
+ const errorLog = log.filter((logMessage) => logMessage.level !== "info" && logMessage.level !== "warning");
1310
+ const displayLog = log.filter((logMessage) => logMessage.level !== "info");
1311
+ (0, import_logging7.displayErrorLog)(displayLog);
160
1312
  if (errorLog.length) {
161
- return (0, _logging.writeErrorLogFile)(options.errorLogFile, errorLog).then(() => {
162
- const multiError = new Error('Errors occurred');
163
- multiError.name = 'ContentfulMultiError';
1313
+ return (0, import_logging7.writeErrorLogFile)(options.errorLogFile, errorLog).then(() => {
1314
+ const multiError = new Error("Errors occurred");
1315
+ multiError.name = "ContentfulMultiError";
164
1316
  multiError.errors = errorLog;
165
1317
  throw multiError;
166
1318
  });
167
1319
  }
168
- console.log('The import was successful.');
1320
+ console.log("The import was successful.");
169
1321
  return data;
170
1322
  });
171
1323
  }
172
- module.exports = exports.default;
1324
+ var lib_default = runContentfulImport;
1325
+ module.exports = runContentfulImport;