@contentstack/cli-cm-import 2.0.0-beta.2 → 2.0.0-beta.4
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/LICENSE +1 -1
- package/README.md +50 -96
- package/lib/commands/cm/stacks/import.d.ts +0 -1
- package/lib/commands/cm/stacks/import.js +9 -42
- package/lib/config/index.js +7 -0
- package/lib/import/module-importer.js +0 -4
- package/lib/import/modules/composable-studio.d.ts +44 -0
- package/lib/import/modules/composable-studio.js +234 -0
- package/lib/import/modules/content-types.d.ts +2 -0
- package/lib/import/modules/content-types.js +48 -9
- package/lib/import/modules/entries.d.ts +2 -0
- package/lib/import/modules/entries.js +19 -10
- package/lib/import/modules/global-fields.d.ts +1 -1
- package/lib/import/modules/global-fields.js +8 -8
- package/lib/import/modules/locales.d.ts +1 -1
- package/lib/import/modules/locales.js +6 -6
- package/lib/import/modules/marketplace-apps.js +2 -2
- package/lib/import/modules/personalize.js +1 -1
- package/lib/import/modules/stack.js +1 -1
- package/lib/import/modules/variant-entries.js +2 -2
- package/lib/import/modules/workflows.js +1 -1
- package/lib/types/default-config.d.ts +6 -0
- package/lib/types/import-config.d.ts +0 -1
- package/lib/types/index.d.ts +37 -11
- package/lib/utils/asset-helper.js +1 -1
- package/lib/utils/common-helper.d.ts +1 -1
- package/lib/utils/common-helper.js +6 -6
- package/lib/utils/content-type-helper.d.ts +1 -1
- package/lib/utils/content-type-helper.js +3 -3
- package/lib/utils/extension-helper.js +1 -1
- package/lib/utils/file-helper.js +1 -1
- package/lib/utils/import-config-handler.js +7 -11
- package/lib/utils/import-path-resolver.js +2 -8
- package/lib/utils/logger.d.ts +1 -1
- package/lib/utils/logger.js +2 -2
- package/lib/utils/login-handler.d.ts +1 -1
- package/lib/utils/login-handler.js +4 -4
- package/lib/utils/marketplace-app-helper.js +9 -6
- package/lib/utils/taxonomies-helper.js +1 -1
- package/messages/index.json +10 -1
- package/oclif.manifest.json +4 -48
- package/package.json +9 -13
|
@@ -25,6 +25,8 @@ export default class ContentTypesImport extends BaseClass {
|
|
|
25
25
|
private extPendingPath;
|
|
26
26
|
private isExtensionsUpdate;
|
|
27
27
|
private pendingExts;
|
|
28
|
+
private composableStudioSuccessPath;
|
|
29
|
+
private composableStudioExportPath;
|
|
28
30
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
29
31
|
start(): Promise<any>;
|
|
30
32
|
seedCTs(): Promise<any>;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
+
/* eslint-disable no-prototype-builtins */
|
|
5
|
+
/*!
|
|
6
|
+
* Contentstack Import
|
|
7
|
+
* Copyright (c) 2026 Contentstack LLC
|
|
8
|
+
* MIT Licensed
|
|
9
|
+
*/
|
|
4
10
|
const path = tslib_1.__importStar(require("path"));
|
|
5
11
|
const lodash_1 = require("lodash");
|
|
6
12
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
@@ -16,19 +22,28 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
16
22
|
this.cTsConfig = importConfig.modules['content-types'];
|
|
17
23
|
this.gFsConfig = importConfig.modules['global-fields'];
|
|
18
24
|
this.reqConcurrency = this.cTsConfig.writeConcurrency || this.importConfig.writeConcurrency;
|
|
19
|
-
this.cTsFolderPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.
|
|
20
|
-
this.cTsMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.
|
|
21
|
-
this.cTsSuccessPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.
|
|
22
|
-
this.gFsFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.importConfig.
|
|
23
|
-
this.gFsMapperFolderPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
24
|
-
this.gFsPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
25
|
-
this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.
|
|
25
|
+
this.cTsFolderPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.contentDir), (0, cli_utilities_1.sanitizePath)(this.cTsConfig.dirName));
|
|
26
|
+
this.cTsMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.contentDir), 'mapper', 'content_types');
|
|
27
|
+
this.cTsSuccessPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.contentDir), 'mapper', 'content_types', 'success.json');
|
|
28
|
+
this.gFsFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.importConfig.contentDir), (0, cli_utilities_1.sanitizePath)(this.gFsConfig.dirName));
|
|
29
|
+
this.gFsMapperFolderPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), 'mapper', 'global_fields', 'success.json');
|
|
30
|
+
this.gFsPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), 'mapper', 'global_fields', 'pending_global_fields.js');
|
|
31
|
+
this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.contentDir), 'mapper', 'marketplace_apps', 'uid-mapping.json');
|
|
26
32
|
this.ignoredFilesInContentTypesFolder = new Map([
|
|
27
33
|
['__master.json', 'true'],
|
|
28
34
|
['__priority.json', 'true'],
|
|
29
35
|
['schema.json', 'true'],
|
|
30
36
|
['.DS_Store', 'true'],
|
|
31
37
|
]);
|
|
38
|
+
// Initialize composable studio paths if config exists
|
|
39
|
+
if (this.importConfig.modules['composable-studio']) {
|
|
40
|
+
this.composableStudioSuccessPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), 'mapper', this.importConfig.modules['composable-studio'].dirName, this.importConfig.modules['composable-studio'].fileName);
|
|
41
|
+
this.composableStudioExportPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), this.importConfig.modules['composable-studio'].dirName, this.importConfig.modules['composable-studio'].fileName);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.composableStudioSuccessPath = '';
|
|
45
|
+
this.composableStudioExportPath = '';
|
|
46
|
+
}
|
|
32
47
|
this.cTs = [];
|
|
33
48
|
this.createdCTs = [];
|
|
34
49
|
this.titleToUIdMap = new Map();
|
|
@@ -37,8 +52,8 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
37
52
|
this.createdGFs = [];
|
|
38
53
|
this.pendingGFs = [];
|
|
39
54
|
this.pendingExts = [];
|
|
40
|
-
this.taxonomiesPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
41
|
-
this.extPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
55
|
+
this.taxonomiesPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), 'mapper', 'taxonomies', 'success.json');
|
|
56
|
+
this.extPendingPath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), 'mapper', 'extensions', 'pending_extensions.js');
|
|
42
57
|
}
|
|
43
58
|
async start() {
|
|
44
59
|
var _a;
|
|
@@ -49,6 +64,30 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
49
64
|
cli_utilities_1.log.info('No content type found to import', this.importConfig.context);
|
|
50
65
|
return;
|
|
51
66
|
}
|
|
67
|
+
// If success file doesn't exist but export file does, skip the composition content type
|
|
68
|
+
// Only check if composable studio paths are configured
|
|
69
|
+
if (this.composableStudioSuccessPath &&
|
|
70
|
+
this.composableStudioExportPath &&
|
|
71
|
+
!utils_1.fileHelper.fileExistsSync(this.composableStudioSuccessPath) &&
|
|
72
|
+
utils_1.fileHelper.fileExistsSync(this.composableStudioExportPath)) {
|
|
73
|
+
const exportedProject = utils_1.fileHelper.readFileSync(this.composableStudioExportPath);
|
|
74
|
+
if (exportedProject === null || exportedProject === void 0 ? void 0 : exportedProject.contentTypeUid) {
|
|
75
|
+
const originalCount = this.cTs.length;
|
|
76
|
+
this.cTs = this.cTs.filter((ct) => {
|
|
77
|
+
const shouldSkip = ct.uid === exportedProject.contentTypeUid;
|
|
78
|
+
if (shouldSkip) {
|
|
79
|
+
cli_utilities_1.log.info(`Skipping content type '${ct.uid}' as Composable Studio project was not created successfully`, this.importConfig.context);
|
|
80
|
+
}
|
|
81
|
+
return !shouldSkip;
|
|
82
|
+
});
|
|
83
|
+
const skippedCount = originalCount - this.cTs.length;
|
|
84
|
+
if (skippedCount > 0) {
|
|
85
|
+
cli_utilities_1.log.debug(`Filtered out ${skippedCount} composition content type(s) from import`, this.importConfig.context);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
await utils_1.fsUtil.makeDirectory(this.cTsMapperPath);
|
|
90
|
+
cli_utilities_1.log.debug('Created content types mapper directory.', this.importConfig.context);
|
|
52
91
|
await utils_1.fsUtil.makeDirectory(this.cTsMapperPath);
|
|
53
92
|
cli_utilities_1.log.debug('Created content types mapper directory', this.importConfig.context);
|
|
54
93
|
const progress = this.initializeProgress();
|
|
@@ -38,6 +38,8 @@ export default class EntriesImport extends BaseClass {
|
|
|
38
38
|
locale: string;
|
|
39
39
|
entry_uid: string;
|
|
40
40
|
}>;
|
|
41
|
+
private composableStudioSuccessPath;
|
|
42
|
+
private composableStudioExportPath;
|
|
41
43
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
42
44
|
start(): Promise<any>;
|
|
43
45
|
private analyzeEntryData;
|
|
@@ -4,7 +4,7 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
/* eslint-disable no-prototype-builtins */
|
|
5
5
|
/*!
|
|
6
6
|
* Contentstack Import
|
|
7
|
-
* Copyright (c)
|
|
7
|
+
* Copyright (c) 2026 Contentstack LLC
|
|
8
8
|
* MIT Licensed
|
|
9
9
|
*/
|
|
10
10
|
const path = tslib_1.__importStar(require("path"));
|
|
@@ -19,19 +19,28 @@ class EntriesImport extends base_class_1.default {
|
|
|
19
19
|
this.entriesForVariant = [];
|
|
20
20
|
this.importConfig.context.module = utils_1.MODULE_CONTEXTS.ENTRIES;
|
|
21
21
|
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.ENTRIES];
|
|
22
|
-
this.assetUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
23
|
-
this.assetUrlMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
24
|
-
this.entriesMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
25
|
-
this.envPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
22
|
+
this.assetUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), 'mapper', 'assets', 'uid-mapping.json');
|
|
23
|
+
this.assetUrlMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), 'mapper', 'assets', 'url-mapping.json');
|
|
24
|
+
this.entriesMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), 'mapper', 'entries');
|
|
25
|
+
this.envPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), 'environments', 'environments.json');
|
|
26
26
|
this.entriesUIDMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'uid-mapping.json');
|
|
27
27
|
this.uniqueUidMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'unique-mapping.json');
|
|
28
28
|
this.modifiedCTsPath = path.join((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'modified-schemas.json');
|
|
29
|
-
this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.
|
|
30
|
-
this.taxonomiesPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.
|
|
29
|
+
this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.contentDir), 'mapper', 'marketplace_apps', 'uid-mapping.json');
|
|
30
|
+
this.taxonomiesPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.contentDir), 'mapper', 'taxonomies', 'terms', 'success.json');
|
|
31
31
|
this.entriesConfig = importConfig.modules.entries;
|
|
32
|
-
this.entriesPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
33
|
-
this.cTsPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
34
|
-
this.localesPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
32
|
+
this.entriesPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), (0, cli_utilities_1.sanitizePath)(this.entriesConfig.dirName));
|
|
33
|
+
this.cTsPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), (0, cli_utilities_1.sanitizePath)(importConfig.modules['content-types'].dirName));
|
|
34
|
+
this.localesPath = path.resolve((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), (0, cli_utilities_1.sanitizePath)(importConfig.modules.locales.dirName), (0, cli_utilities_1.sanitizePath)(importConfig.modules.locales.fileName));
|
|
35
|
+
// Initialize composable studio paths if config exists
|
|
36
|
+
if (this.importConfig.modules['composable-studio']) {
|
|
37
|
+
this.composableStudioSuccessPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), 'mapper', this.importConfig.modules['composable-studio'].dirName, this.importConfig.modules['composable-studio'].fileName);
|
|
38
|
+
this.composableStudioExportPath = path.join((0, cli_utilities_1.sanitizePath)(this.importConfig.data), this.importConfig.modules['composable-studio'].dirName, this.importConfig.modules['composable-studio'].fileName);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.composableStudioSuccessPath = '';
|
|
42
|
+
this.composableStudioExportPath = '';
|
|
43
|
+
}
|
|
35
44
|
this.importConcurrency = this.entriesConfig.importConcurrency || importConfig.importConcurrency;
|
|
36
45
|
this.entriesUidMapper = {};
|
|
37
46
|
this.modifiedCTs = [];
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* eslint-disable no-prototype-builtins */
|
|
3
3
|
/*!
|
|
4
4
|
* Contentstack Import
|
|
5
|
-
* Copyright (c)
|
|
5
|
+
* Copyright (c) 2026 Contentstack LLC
|
|
6
6
|
* MIT Licensed
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -27,13 +27,13 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
27
27
|
this.pendingGFs = [];
|
|
28
28
|
this.existingGFs = [];
|
|
29
29
|
this.reqConcurrency = this.gFsConfig.writeConcurrency || this.config.writeConcurrency;
|
|
30
|
-
this.gFsMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
31
|
-
this.gFsFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
32
|
-
this.gFsFailsPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
33
|
-
this.gFsSuccessPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
34
|
-
this.gFsUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
35
|
-
this.gFsPendingPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
36
|
-
this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.config.
|
|
30
|
+
this.gFsMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'global_fields');
|
|
31
|
+
this.gFsFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), (0, cli_utilities_1.sanitizePath)(this.gFsConfig.dirName));
|
|
32
|
+
this.gFsFailsPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'global_fields', 'fails.json');
|
|
33
|
+
this.gFsSuccessPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'global_fields', 'success.json');
|
|
34
|
+
this.gFsUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'global_fields', 'uid-mapping.json');
|
|
35
|
+
this.gFsPendingPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'global_fields', 'pending_global_fields.js');
|
|
36
|
+
this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'marketplace_apps', 'uid-mapping.json');
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* @method start
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* eslint-disable no-prototype-builtins */
|
|
3
3
|
/*!
|
|
4
4
|
* Contentstack Import
|
|
5
|
-
* Copyright (c)
|
|
5
|
+
* Copyright (c) 2026 Contentstack LLC
|
|
6
6
|
* MIT Licensed
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -27,11 +27,11 @@ class ImportLocales extends base_class_1.default {
|
|
|
27
27
|
this.createdLocales = [];
|
|
28
28
|
this.failedLocales = [];
|
|
29
29
|
this.reqConcurrency = this.localeConfig.writeConcurrency || this.config.writeConcurrency;
|
|
30
|
-
this.langMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
31
|
-
this.langFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
32
|
-
this.langFailsPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
33
|
-
this.langSuccessPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
34
|
-
this.langUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
30
|
+
this.langMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'languages');
|
|
31
|
+
this.langFolderPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), (0, cli_utilities_1.sanitizePath)(this.localeConfig.dirName));
|
|
32
|
+
this.langFailsPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'languages', 'fails.json');
|
|
33
|
+
this.langSuccessPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'languages', 'success.json');
|
|
34
|
+
this.langUidMapperPath = path.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'languages', 'uid-mapper.json');
|
|
35
35
|
}
|
|
36
36
|
async start() {
|
|
37
37
|
try {
|
|
@@ -347,11 +347,11 @@ class ImportMarketplaceApps extends base_class_1.default {
|
|
|
347
347
|
*/
|
|
348
348
|
async installApp(config, appManifestUid) {
|
|
349
349
|
cli_utilities_1.log.debug(`Installing app with manifest UID: ${appManifestUid}`, this.importConfig.context);
|
|
350
|
-
cli_utilities_1.log.debug(`Target stack: ${config.
|
|
350
|
+
cli_utilities_1.log.debug(`Target stack: ${config.apiKey}`, this.importConfig.context);
|
|
351
351
|
return await this.appSdk
|
|
352
352
|
.marketplace(this.importConfig.org_uid)
|
|
353
353
|
.app(appManifestUid)
|
|
354
|
-
.install({ targetUid: config.
|
|
354
|
+
.install({ targetUid: config.apiKey, targetType: 'stack' })
|
|
355
355
|
.then((response) => {
|
|
356
356
|
cli_utilities_1.log.debug(`App installation successful: ${appManifestUid}`, this.importConfig.context);
|
|
357
357
|
return response;
|
|
@@ -145,7 +145,7 @@ class ImportPersonalize extends base_class_1.default {
|
|
|
145
145
|
}
|
|
146
146
|
const personalize = this.config.modules.personalize;
|
|
147
147
|
const { dirName, fileName } = personalize.projects;
|
|
148
|
-
const projectPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.
|
|
148
|
+
const projectPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.contentDir), (0, cli_utilities_1.sanitizePath)(personalize.dirName), (0, cli_utilities_1.sanitizePath)(dirName), (0, cli_utilities_1.sanitizePath)(fileName));
|
|
149
149
|
cli_utilities_1.log.debug(`Checking for project file: ${projectPath}`, this.config.context);
|
|
150
150
|
if (!(0, fs_1.existsSync)(projectPath)) {
|
|
151
151
|
this.config.modules.personalize.importData = false;
|
|
@@ -47,7 +47,7 @@ class ImportStack extends base_class_1.default {
|
|
|
47
47
|
var _a, _b, _c;
|
|
48
48
|
cli_utilities_1.log.debug('Processing stack settings for import', this.importConfig.context);
|
|
49
49
|
// Update environment UID mapping if live preview is configured
|
|
50
|
-
if (((_a = this.stackSettings) === null || _a === void 0 ? void 0 : _a.live_preview) && ((_b = this.stackSettings) === null || _b === void 0 ? void 0 : _b.live_preview['default-env'])) {
|
|
50
|
+
if (((_a = this.stackSettings) === null || _a === void 0 ? void 0 : _a.live_preview) && ((_b = this.stackSettings) === null || _b === void 0 ? void 0 : _b.live_preview['default-env']) !== undefined) {
|
|
51
51
|
const oldEnvUid = this.stackSettings.live_preview['default-env'];
|
|
52
52
|
const mappedEnvUid = this.envUidMapper[oldEnvUid];
|
|
53
53
|
if (mappedEnvUid) {
|
|
@@ -13,7 +13,7 @@ class ImportVariantEntries extends base_class_1.default {
|
|
|
13
13
|
this.config.context.module = utils_1.MODULE_CONTEXTS.VARIANT_ENTRIES;
|
|
14
14
|
this.currentModuleName = utils_1.MODULE_NAMES[utils_1.MODULE_CONTEXTS.VARIANT_ENTRIES];
|
|
15
15
|
this.personalize = importConfig.modules.personalize;
|
|
16
|
-
this.projectMapperFilePath = path_1.default.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
16
|
+
this.projectMapperFilePath = path_1.default.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', (0, cli_utilities_1.sanitizePath)(this.personalize.dirName), 'projects', 'projects.json');
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* @method start
|
|
@@ -89,7 +89,7 @@ class ImportVariantEntries extends base_class_1.default {
|
|
|
89
89
|
return [false, 0];
|
|
90
90
|
}
|
|
91
91
|
// Basic validation - check if data file exists
|
|
92
|
-
const dataFilePath = path_1.default.resolve((0, cli_utilities_1.sanitizePath)(this.config.
|
|
92
|
+
const dataFilePath = path_1.default.resolve((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'mapper', 'entries', 'data-for-variant-entry.json');
|
|
93
93
|
const hasVariantData = utils_1.fileHelper.fileExistsSync(dataFilePath);
|
|
94
94
|
cli_utilities_1.log.debug(`Found valid personalize project: ${project.uid} with variant data: ${hasVariantData}`, this.config.context);
|
|
95
95
|
// Return 0 count - let the variant module update it dynamically
|
|
@@ -142,7 +142,7 @@ class ImportWorkflows extends base_class_1.default {
|
|
|
142
142
|
else {
|
|
143
143
|
this.failedWebhooks.push(apiData);
|
|
144
144
|
(_d = this.progressManager) === null || _d === void 0 ? void 0 : _d.tick(false, `workflow: ${name || uid}`, (error === null || error === void 0 ? void 0 : error.message) || 'Failed to import workflow', utils_1.PROCESS_NAMES.WORKFLOWS_CREATE);
|
|
145
|
-
if (error.errors['workflow_stages.0.users']) {
|
|
145
|
+
if ((error === null || error === void 0 ? void 0 : error.errors) && error.errors['workflow_stages.0.users']) {
|
|
146
146
|
cli_utilities_1.log.error("Failed to import Workflows as you've specified certain roles in the Stage transition and access rules section. We currently don't import roles to the stack.", this.importConfig.context);
|
|
147
147
|
}
|
|
148
148
|
else {
|
|
@@ -156,6 +156,12 @@ export default interface DefaultConfig {
|
|
|
156
156
|
locale: string;
|
|
157
157
|
} & AnyProperty;
|
|
158
158
|
} & AnyProperty;
|
|
159
|
+
'composable-studio': {
|
|
160
|
+
dirName: string;
|
|
161
|
+
fileName: string;
|
|
162
|
+
apiBaseUrl: string;
|
|
163
|
+
apiVersion: string;
|
|
164
|
+
};
|
|
159
165
|
};
|
|
160
166
|
languagesCode: string[];
|
|
161
167
|
apis: {
|
|
@@ -48,7 +48,6 @@ export default interface ImportConfig extends DefaultConfig, ExternalConfig {
|
|
|
48
48
|
authtoken?: string;
|
|
49
49
|
destinationStackName?: string;
|
|
50
50
|
org_uid?: string;
|
|
51
|
-
contentVersion: number;
|
|
52
51
|
replaceExisting?: boolean;
|
|
53
52
|
skipExisting?: boolean;
|
|
54
53
|
skipAudit?: boolean;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export interface User {
|
|
|
26
26
|
email: string;
|
|
27
27
|
authtoken: string;
|
|
28
28
|
}
|
|
29
|
-
export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies' | 'personalize' | 'variant-entries';
|
|
29
|
+
export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies' | 'personalize' | 'variant-entries' | 'composable-studio';
|
|
30
30
|
export type ModuleClassParams = {
|
|
31
31
|
stackAPIClient: ReturnType<ContentstackClient['stack']>;
|
|
32
32
|
importConfig: ImportConfig;
|
|
@@ -71,23 +71,49 @@ export interface TaxonomiesConfig {
|
|
|
71
71
|
fileName: string;
|
|
72
72
|
dependencies?: Modules[];
|
|
73
73
|
}
|
|
74
|
-
export
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
export interface ComposableStudioConfig {
|
|
75
|
+
dirName: string;
|
|
76
|
+
fileName: string;
|
|
77
|
+
apiBaseUrl: string;
|
|
78
|
+
apiVersion: string;
|
|
79
|
+
}
|
|
80
|
+
export interface ComposableStudioProject {
|
|
81
|
+
name: string;
|
|
82
|
+
description: string;
|
|
83
|
+
canvasUrl: string;
|
|
84
|
+
connectedStackApiKey: string;
|
|
85
|
+
contentTypeUid: string;
|
|
86
|
+
organizationUid: string;
|
|
87
|
+
settings: {
|
|
88
|
+
configuration: {
|
|
89
|
+
environment: string;
|
|
90
|
+
locale: string;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
uid?: string;
|
|
94
|
+
createdBy?: string;
|
|
95
|
+
updatedBy?: string;
|
|
96
|
+
deletedAt?: boolean;
|
|
97
|
+
createdAt?: string;
|
|
98
|
+
updatedAt?: string;
|
|
99
|
+
}
|
|
83
100
|
export interface Context {
|
|
84
101
|
command: string;
|
|
85
102
|
module: string;
|
|
86
103
|
userId: string | undefined;
|
|
87
|
-
email
|
|
104
|
+
email: string | undefined;
|
|
88
105
|
sessionId: string | undefined;
|
|
89
106
|
clientId?: string | undefined;
|
|
90
107
|
apiKey: string;
|
|
91
108
|
orgId: string;
|
|
92
109
|
authenticationMethod?: string;
|
|
93
110
|
}
|
|
111
|
+
export { default as DefaultConfig } from './default-config';
|
|
112
|
+
export { default as ImportConfig } from './import-config';
|
|
113
|
+
export * from './entries';
|
|
114
|
+
export * from './marketplace-app';
|
|
115
|
+
export type ExtensionType = {
|
|
116
|
+
uid: string;
|
|
117
|
+
scope: Record<string, unknown>;
|
|
118
|
+
title: string;
|
|
119
|
+
};
|
|
@@ -34,7 +34,7 @@ const uploadAssetHelper = function (config, req, fsPath, RETRY) {
|
|
|
34
34
|
cli_utilities_1.log.debug(`Uploading asset (attempt ${RETRY}/${MAX_RETRY_LIMIT}): ${fsPath}`);
|
|
35
35
|
req.upload = fsPath;
|
|
36
36
|
const stackAPIClient = APIClient.stack({
|
|
37
|
-
api_key: config.
|
|
37
|
+
api_key: config.apiKey,
|
|
38
38
|
management_token: config.management_token,
|
|
39
39
|
});
|
|
40
40
|
stackAPIClient
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
3
|
/*!
|
|
4
4
|
* Contentstack Import
|
|
5
|
-
* Copyright (c)
|
|
5
|
+
* Copyright (c) 2026 Contentstack LLC
|
|
6
6
|
* MIT Licensed
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -25,14 +25,14 @@ const initialization = (configData) => {
|
|
|
25
25
|
exports.initialization = initialization;
|
|
26
26
|
const validateConfig = (importConfig) => {
|
|
27
27
|
cli_utilities_1.log.debug('Validating import configuration');
|
|
28
|
-
if (importConfig.email && importConfig.password && !importConfig.
|
|
28
|
+
if (importConfig.email && importConfig.password && !importConfig.apiKey) {
|
|
29
29
|
cli_utilities_1.log.debug('Target stack API token is required when using email/password authentication');
|
|
30
30
|
return 'error';
|
|
31
31
|
}
|
|
32
32
|
else if (!importConfig.email &&
|
|
33
33
|
!importConfig.password &&
|
|
34
34
|
!importConfig.management_token &&
|
|
35
|
-
importConfig.
|
|
35
|
+
importConfig.apiKey &&
|
|
36
36
|
!(0, cli_utilities_1.isAuthenticated)()) {
|
|
37
37
|
cli_utilities_1.log.debug('Authentication credentials missing - either management token or email/password required');
|
|
38
38
|
return 'error';
|
|
@@ -70,7 +70,7 @@ const sanitizeStack = (importConfig) => {
|
|
|
70
70
|
const newStackVersion = stackDetails.data.stack.settings.version;
|
|
71
71
|
const newStackDate = new Date(newStackVersion).toString();
|
|
72
72
|
cli_utilities_1.log.debug(`New stack version: ${newStackVersion} (${newStackDate})`);
|
|
73
|
-
const stackFilePath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.
|
|
73
|
+
const stackFilePath = path.join((0, cli_utilities_1.sanitizePath)(importConfig.contentDir), (0, cli_utilities_1.sanitizePath)(importConfig.modules.stack.dirName), (0, cli_utilities_1.sanitizePath)(importConfig.modules.stack.fileName));
|
|
74
74
|
cli_utilities_1.log.debug(`Reading stack file from: ${stackFilePath}`);
|
|
75
75
|
const oldStackDetails = (0, file_helper_1.readFileSync)(stackFilePath);
|
|
76
76
|
if (!oldStackDetails || !oldStackDetails.settings || !oldStackDetails.settings.hasOwnProperty('version')) {
|
|
@@ -137,7 +137,7 @@ const field_rules_update = (importConfig, ctPath) => {
|
|
|
137
137
|
for (let i = 0; i < fieldRuleConditionLength; i++) {
|
|
138
138
|
if (schema.field_rules[k].conditions[i].operand_field === 'reference') {
|
|
139
139
|
cli_utilities_1.log.debug(`Processing reference field rule condition`);
|
|
140
|
-
let entryMapperPath = path.resolve(importConfig.
|
|
140
|
+
let entryMapperPath = path.resolve(importConfig.contentDir, 'mapper', 'entries');
|
|
141
141
|
let entryUidMapperPath = path.join(entryMapperPath, 'uid-mapping.json');
|
|
142
142
|
let fieldRulesValue = schema.field_rules[k].conditions[i].value;
|
|
143
143
|
let fieldRulesArray = fieldRulesValue.split('.');
|
|
@@ -158,7 +158,7 @@ const field_rules_update = (importConfig, ctPath) => {
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
const stackAPIClient = client.stack({
|
|
161
|
-
api_key: importConfig.
|
|
161
|
+
api_key: importConfig.apiKey,
|
|
162
162
|
management_token: importConfig.management_token,
|
|
163
163
|
});
|
|
164
164
|
let ctObj = stackAPIClient.contentType(schema.uid);
|
|
@@ -42,7 +42,7 @@ export declare const schemaTemplate: {
|
|
|
42
42
|
};
|
|
43
43
|
/*!
|
|
44
44
|
* Contentstack Import
|
|
45
|
-
* Copyright (c)
|
|
45
|
+
* Copyright (c) 2026 Contentstack LLC
|
|
46
46
|
* MIT Licensed
|
|
47
47
|
*/
|
|
48
48
|
export declare const suppressSchemaReference: (schema: any, flag: any) => void;
|
|
@@ -48,7 +48,7 @@ exports.schemaTemplate = {
|
|
|
48
48
|
};
|
|
49
49
|
/*!
|
|
50
50
|
* Contentstack Import
|
|
51
|
-
* Copyright (c)
|
|
51
|
+
* Copyright (c) 2026 Contentstack LLC
|
|
52
52
|
* MIT Licensed
|
|
53
53
|
*/
|
|
54
54
|
const suppressSchemaReference = function (schema, flag) {
|
|
@@ -128,7 +128,7 @@ const removeReferenceFields = async function (schema, flag = { supressed: false
|
|
|
128
128
|
catch (error) {
|
|
129
129
|
// Else warn and modify the schema object.
|
|
130
130
|
isContentTypeError = true;
|
|
131
|
-
cli_utilities_1.log.warn(`Content
|
|
131
|
+
cli_utilities_1.log.warn(`Content type ${schema[i].reference_to[j]} does not exist. Removing the field from schema...`);
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
if (isContentTypeError) {
|
|
@@ -200,7 +200,7 @@ const updateFieldRules = function (contentType) {
|
|
|
200
200
|
const field = contentType.schema[i];
|
|
201
201
|
fieldDataTypeMap[field.uid] = field.data_type;
|
|
202
202
|
}
|
|
203
|
-
cli_utilities_1.log.debug(`Created field data type mapping for ${Object.keys(fieldDataTypeMap).length} fields
|
|
203
|
+
cli_utilities_1.log.debug(`Created field data type mapping for ${Object.keys(fieldDataTypeMap).length} fields.`);
|
|
204
204
|
const fieldRules = [...contentType.field_rules];
|
|
205
205
|
let len = fieldRules.length;
|
|
206
206
|
let removedRules = 0;
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.lookupExtension = void 0;
|
|
7
7
|
/*!
|
|
8
8
|
* Contentstack Import
|
|
9
|
-
* Copyright (c)
|
|
9
|
+
* Copyright (c) 2026 Contentstack LLC
|
|
10
10
|
* MIT Licensed
|
|
11
11
|
*/
|
|
12
12
|
const node_path_1 = require("node:path");
|
package/lib/utils/file-helper.js
CHANGED
|
@@ -11,6 +11,9 @@ const interactive_1 = require("./interactive");
|
|
|
11
11
|
const login_handler_1 = tslib_1.__importDefault(require("./login-handler"));
|
|
12
12
|
const setupConfig = async (importCmdFlags) => {
|
|
13
13
|
var _a;
|
|
14
|
+
// Set progress supported module FIRST, before any log calls
|
|
15
|
+
// This ensures the logger respects the showConsoleLogs setting correctly
|
|
16
|
+
cli_utilities_1.configHandler.set('log.progressSupportedModule', 'import');
|
|
14
17
|
let config = (0, merge_1.default)({}, config_1.default);
|
|
15
18
|
// Track authentication method
|
|
16
19
|
let authenticationMethod = 'unknown';
|
|
@@ -23,18 +26,16 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
23
26
|
}
|
|
24
27
|
config = merge_1.default.recursive(config, externalConfig);
|
|
25
28
|
}
|
|
26
|
-
config.contentDir = (0, cli_utilities_1.sanitizePath)(importCmdFlags['data'] || importCmdFlags['data-dir'] || config.
|
|
29
|
+
config.contentDir = (0, cli_utilities_1.sanitizePath)(importCmdFlags['data'] || importCmdFlags['data-dir'] || config.contentDir || (await (0, interactive_1.askContentDir)()));
|
|
27
30
|
const pattern = /[*$%#<>{}!&?]/g;
|
|
28
31
|
if (pattern.test(config.contentDir)) {
|
|
29
|
-
cli_utilities_1.cliux.print(`\nPlease
|
|
32
|
+
cli_utilities_1.cliux.print(`\nPlease enter a directory path without any special characters: (*,&,{,},[,],$,%,<,>,?,!)`, {
|
|
30
33
|
color: 'yellow',
|
|
31
34
|
});
|
|
32
35
|
config.contentDir = (0, cli_utilities_1.sanitizePath)(await (0, interactive_1.askContentDir)());
|
|
33
36
|
}
|
|
34
37
|
config.contentDir = config.contentDir.replace(/['"]/g, '');
|
|
35
38
|
config.contentDir = path.resolve(config.contentDir);
|
|
36
|
-
//Note to support the old key
|
|
37
|
-
config.data = config.contentDir;
|
|
38
39
|
const managementTokenAlias = importCmdFlags['management-token-alias'] || importCmdFlags['alias'];
|
|
39
40
|
if (managementTokenAlias) {
|
|
40
41
|
const { token, apiKey } = (_a = cli_utilities_1.configHandler.get(`tokens.${managementTokenAlias}`)) !== null && _a !== void 0 ? _a : {};
|
|
@@ -71,7 +72,7 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
71
72
|
cli_utilities_1.log.debug('User authenticated via auth token');
|
|
72
73
|
}
|
|
73
74
|
config.apiKey =
|
|
74
|
-
importCmdFlags['stack-uid'] || importCmdFlags['stack-api-key'] || config.
|
|
75
|
+
importCmdFlags['stack-uid'] || importCmdFlags['stack-api-key'] || config.apiKey || (await (0, interactive_1.askAPIKey)());
|
|
75
76
|
if (typeof config.apiKey !== 'string') {
|
|
76
77
|
throw new Error('Invalid API key received');
|
|
77
78
|
}
|
|
@@ -79,12 +80,9 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
79
80
|
}
|
|
80
81
|
config.isAuthenticated = (0, cli_utilities_1.isAuthenticated)();
|
|
81
82
|
config.auth_token = cli_utilities_1.configHandler.get('authtoken'); // TBD handle auth token in httpClient & sdk
|
|
82
|
-
//Note to support the old key
|
|
83
|
-
config.source_stack = config.apiKey;
|
|
84
83
|
config.skipAudit = importCmdFlags['skip-audit'];
|
|
85
84
|
config.forceStopMarketplaceAppsPrompt = importCmdFlags.yes;
|
|
86
85
|
config.importWebhookStatus = importCmdFlags['import-webhook-status'];
|
|
87
|
-
config.skipPrivateAppRecreationIfExist = !importCmdFlags['skip-app-recreation'];
|
|
88
86
|
if (importCmdFlags['branch-alias']) {
|
|
89
87
|
config.branchAlias = importCmdFlags['branch-alias'];
|
|
90
88
|
}
|
|
@@ -105,8 +103,6 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
105
103
|
if (importCmdFlags['skip-entries-publish']) {
|
|
106
104
|
config.skipEntriesPublish = importCmdFlags['skip-entries-publish'];
|
|
107
105
|
}
|
|
108
|
-
// Note to support old modules
|
|
109
|
-
config.target_stack = config.apiKey;
|
|
110
106
|
config.replaceExisting = importCmdFlags['replace-existing'];
|
|
111
107
|
config.skipExisting = importCmdFlags['skip-existing'];
|
|
112
108
|
config.personalizeProjectName = importCmdFlags['personalize-project-name'];
|
|
@@ -117,7 +113,7 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
117
113
|
cli_utilities_1.configHandler.set('log.progressSupportedModule', 'import');
|
|
118
114
|
// Add authentication details to config for context tracking
|
|
119
115
|
config.authenticationMethod = authenticationMethod;
|
|
120
|
-
cli_utilities_1.log.debug('Import configuration setup completed', Object.assign({}, config));
|
|
116
|
+
cli_utilities_1.log.debug('Import configuration setup completed.', Object.assign({}, config));
|
|
121
117
|
return config;
|
|
122
118
|
};
|
|
123
119
|
exports.default = setupConfig;
|