@contentstack/cli-variants 1.3.2 → 2.0.0-beta
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/lib/export/attributes.d.ts +2 -2
- package/lib/export/attributes.js +51 -23
- package/lib/export/audiences.d.ts +2 -2
- package/lib/export/audiences.js +50 -24
- package/lib/export/events.d.ts +2 -2
- package/lib/export/events.js +52 -24
- package/lib/export/experiences.js +87 -54
- package/lib/export/projects.d.ts +3 -2
- package/lib/export/projects.js +55 -63
- package/lib/export/variant-entries.d.ts +19 -0
- package/lib/export/variant-entries.js +76 -1
- package/lib/import/attribute.d.ts +2 -0
- package/lib/import/attribute.js +83 -37
- package/lib/import/audiences.d.ts +2 -0
- package/lib/import/audiences.js +85 -41
- package/lib/import/events.d.ts +3 -1
- package/lib/import/events.js +86 -30
- package/lib/import/experiences.d.ts +2 -0
- package/lib/import/experiences.js +93 -39
- package/lib/import/project.d.ts +2 -0
- package/lib/import/project.js +81 -22
- package/lib/import/variant-entries.d.ts +10 -0
- package/lib/import/variant-entries.js +139 -53
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/types/export-config.d.ts +0 -2
- package/lib/types/import-config.d.ts +0 -1
- package/lib/types/utils.d.ts +1 -1
- package/lib/utils/constants.d.ts +91 -0
- package/lib/utils/constants.js +93 -0
- package/lib/utils/personalization-api-adapter.d.ts +34 -1
- package/lib/utils/personalization-api-adapter.js +180 -53
- package/lib/utils/variant-api-adapter.d.ts +28 -1
- package/lib/utils/variant-api-adapter.js +89 -32
- package/package.json +2 -2
- package/src/export/attributes.ts +84 -34
- package/src/export/audiences.ts +87 -41
- package/src/export/events.ts +84 -41
- package/src/export/experiences.ts +155 -83
- package/src/export/projects.ts +71 -39
- package/src/export/variant-entries.ts +136 -12
- package/src/import/attribute.ts +105 -49
- package/src/import/audiences.ts +110 -54
- package/src/import/events.ts +104 -41
- package/src/import/experiences.ts +140 -62
- package/src/import/project.ts +108 -38
- package/src/import/variant-entries.ts +188 -75
- package/src/index.ts +2 -1
- package/src/types/export-config.ts +0 -2
- package/src/types/import-config.ts +0 -1
- package/src/types/utils.ts +1 -1
- package/src/utils/constants.ts +98 -0
- package/src/utils/personalization-api-adapter.ts +212 -76
- package/src/utils/variant-api-adapter.ts +137 -50
- package/tsconfig.json +1 -1
package/lib/import/project.js
CHANGED
|
@@ -13,6 +13,7 @@ const path_1 = require("path");
|
|
|
13
13
|
const fs_1 = require("fs");
|
|
14
14
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
15
15
|
const utils_1 = require("../utils");
|
|
16
|
+
const constants_1 = require("../utils/constants");
|
|
16
17
|
class Project extends utils_1.PersonalizationAdapter {
|
|
17
18
|
constructor(config) {
|
|
18
19
|
const conf = {
|
|
@@ -23,7 +24,8 @@ class Project extends utils_1.PersonalizationAdapter {
|
|
|
23
24
|
super(Object.assign(config, conf));
|
|
24
25
|
this.config = config;
|
|
25
26
|
this.projectMapperFolderPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', (0, cli_utilities_1.sanitizePath)(this.config.modules.personalize.dirName), 'projects');
|
|
26
|
-
this.config.context.module =
|
|
27
|
+
this.config.context.module = constants_1.MODULE_CONTEXTS.PROJECTS;
|
|
28
|
+
this.projectsData = [];
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
31
|
* The function asynchronously imports projects data from a file and creates projects based on the
|
|
@@ -31,20 +33,32 @@ class Project extends utils_1.PersonalizationAdapter {
|
|
|
31
33
|
*/
|
|
32
34
|
import() {
|
|
33
35
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
this.config.modules.personalize.importData = false; // Stop personalize import if stack not connected to any project
|
|
43
|
-
cli_utilities_1.log.warn('No projects found in file', this.config.context);
|
|
36
|
+
try {
|
|
37
|
+
cli_utilities_1.log.debug('Starting personalize project import...', this.config.context);
|
|
38
|
+
const [canImport, projectsCount] = yield this.analyzeProjects();
|
|
39
|
+
if (!canImport) {
|
|
40
|
+
cli_utilities_1.log.info('No projects found to import', this.config.context);
|
|
41
|
+
if (this.parentProgressManager) {
|
|
42
|
+
this.parentProgressManager.tick(true, 'projects module (no data)', null, constants_1.PROCESS_NAMES.PROJECTS);
|
|
43
|
+
}
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
+
// Fix 1: Always use parent progress manager when available
|
|
47
|
+
let progress;
|
|
48
|
+
if (this.parentProgressManager) {
|
|
49
|
+
progress = this.parentProgressManager;
|
|
50
|
+
cli_utilities_1.log.debug('Using parent progress manager for projects import', this.config.context);
|
|
51
|
+
// Don't create our own progress - use parent's
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
progress = this.createSimpleProgress(constants_1.PROCESS_NAMES.PROJECTS, projectsCount);
|
|
55
|
+
cli_utilities_1.log.debug('Created standalone progress manager for projects import', this.config.context);
|
|
56
|
+
}
|
|
46
57
|
yield this.init();
|
|
47
|
-
for (const project of
|
|
58
|
+
for (const project of this.projectsData) {
|
|
59
|
+
if (!this.parentProgressManager) {
|
|
60
|
+
progress.updateStatus(constants_1.IMPORT_PROCESS_STATUS[constants_1.PROCESS_NAMES.PROJECTS].CREATING);
|
|
61
|
+
}
|
|
48
62
|
cli_utilities_1.log.debug(`Processing project: ${project.name}`, this.config.context);
|
|
49
63
|
const createProject = (newName) => __awaiter(this, void 0, void 0, function* () {
|
|
50
64
|
cli_utilities_1.log.debug(`Creating project with name: ${newName || project.name}`, this.config.context);
|
|
@@ -56,26 +70,71 @@ class Project extends utils_1.PersonalizationAdapter {
|
|
|
56
70
|
if (error.includes('personalization.PROJECTS.DUPLICATE_NAME') ||
|
|
57
71
|
error.includes('personalize.PROJECTS.DUPLICATE_NAME')) {
|
|
58
72
|
cli_utilities_1.log.warn(`Project name already exists, generating new name`, this.config.context);
|
|
73
|
+
// Prevent progress bar corruption with clean newlines
|
|
74
|
+
cli_utilities_1.cliux.print('\n');
|
|
59
75
|
const projectName = yield (0, utils_1.askProjectName)('Copy Of ' + (newName || project.name));
|
|
76
|
+
cli_utilities_1.cliux.print('\n');
|
|
77
|
+
if (this.parentProgressManager) {
|
|
78
|
+
this.parentProgressManager.updateStatus(constants_1.IMPORT_PROCESS_STATUS[constants_1.PROCESS_NAMES.PROJECTS].CREATING, constants_1.PROCESS_NAMES.PROJECTS);
|
|
79
|
+
}
|
|
60
80
|
return yield createProject(projectName);
|
|
61
81
|
}
|
|
62
82
|
throw error;
|
|
63
83
|
}));
|
|
64
84
|
});
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
85
|
+
try {
|
|
86
|
+
const projectRes = yield createProject(this.config.personalizeProjectName);
|
|
87
|
+
this.config.modules.personalize.project_id = projectRes.uid;
|
|
88
|
+
this.config.modules.personalize.importData = true;
|
|
89
|
+
yield utils_1.fsUtil.makeDirectory(this.projectMapperFolderPath);
|
|
90
|
+
utils_1.fsUtil.writeFile((0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.projectMapperFolderPath), 'projects.json'), projectRes);
|
|
91
|
+
this.updateProgress(true, `project: ${project.name}`, undefined, constants_1.PROCESS_NAMES.PROJECTS);
|
|
92
|
+
cli_utilities_1.log.success(`Project created successfully: ${projectRes.uid}`, this.config.context);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.updateProgress(false, `project: ${project.name}`, error === null || error === void 0 ? void 0 : error.message, constants_1.PROCESS_NAMES.PROJECTS);
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
72
98
|
}
|
|
99
|
+
// Only complete progress if we own the progress manager (no parent)
|
|
100
|
+
if (!this.parentProgressManager) {
|
|
101
|
+
this.completeProgress(true);
|
|
102
|
+
}
|
|
103
|
+
cli_utilities_1.log.success(`Projects imported successfully! Total projects: ${projectsCount} - personalization enabled`, this.config.context);
|
|
73
104
|
}
|
|
74
|
-
|
|
75
|
-
this.config.modules.personalize.importData = false;
|
|
76
|
-
|
|
105
|
+
catch (error) {
|
|
106
|
+
this.config.modules.personalize.importData = false;
|
|
107
|
+
if (!this.parentProgressManager) {
|
|
108
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Project import failed');
|
|
109
|
+
}
|
|
110
|
+
throw error;
|
|
77
111
|
}
|
|
78
112
|
});
|
|
79
113
|
}
|
|
114
|
+
analyzeProjects() {
|
|
115
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
116
|
+
return this.withLoadingSpinner('PROJECT: Analyzing import data...', () => __awaiter(this, void 0, void 0, function* () {
|
|
117
|
+
var _a;
|
|
118
|
+
const personalize = this.config.modules.personalize;
|
|
119
|
+
const { dirName, fileName } = personalize.projects;
|
|
120
|
+
const projectPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.data), (0, cli_utilities_1.sanitizePath)(personalize.dirName), (0, cli_utilities_1.sanitizePath)(dirName), (0, cli_utilities_1.sanitizePath)(fileName));
|
|
121
|
+
cli_utilities_1.log.debug(`Checking for project file: ${projectPath}`, this.config.context);
|
|
122
|
+
if (!(0, fs_1.existsSync)(projectPath)) {
|
|
123
|
+
this.config.modules.personalize.importData = false;
|
|
124
|
+
cli_utilities_1.log.warn(`Project file not found: ${projectPath}`, this.config.context);
|
|
125
|
+
return [false, 0];
|
|
126
|
+
}
|
|
127
|
+
this.projectsData = JSON.parse((0, fs_1.readFileSync)(projectPath, 'utf8'));
|
|
128
|
+
const projectsCount = ((_a = this.projectsData) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
129
|
+
if (projectsCount < 1) {
|
|
130
|
+
this.config.modules.personalize.importData = false;
|
|
131
|
+
cli_utilities_1.log.warn('No projects found in file', this.config.context);
|
|
132
|
+
return [false, 0];
|
|
133
|
+
}
|
|
134
|
+
cli_utilities_1.log.debug(`Found ${projectsCount} projects to import`, this.config.context);
|
|
135
|
+
return [true, projectsCount];
|
|
136
|
+
}));
|
|
137
|
+
});
|
|
138
|
+
}
|
|
80
139
|
}
|
|
81
140
|
exports.default = Project;
|
|
@@ -17,9 +17,19 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
|
|
|
17
17
|
private failedVariantPath;
|
|
18
18
|
private failedVariantEntries;
|
|
19
19
|
private environments;
|
|
20
|
+
progress: any;
|
|
21
|
+
private processInitialized;
|
|
20
22
|
constructor(config: ImportConfig & {
|
|
21
23
|
helpers?: ImportHelperMethodsConfig;
|
|
22
24
|
});
|
|
25
|
+
/**
|
|
26
|
+
* Set parent progress manager for integration with entries module
|
|
27
|
+
*/
|
|
28
|
+
setParentProgressManager(parentProgress: any): void;
|
|
29
|
+
/**
|
|
30
|
+
* Update progress for a specific item
|
|
31
|
+
*/
|
|
32
|
+
protected updateProgress(success: boolean, itemName: string, error?: string, processName?: string): void;
|
|
23
33
|
/**
|
|
24
34
|
* This TypeScript function asynchronously imports backupDir from a JSON file and processes the entries
|
|
25
35
|
* for variant entries.
|
|
@@ -56,6 +56,7 @@ const fs_1 = require("fs");
|
|
|
56
56
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
57
57
|
const variant_api_adapter_1 = __importStar(require("../utils/variant-api-adapter"));
|
|
58
58
|
const utils_1 = require("../utils");
|
|
59
|
+
const constants_1 = require("../utils/constants");
|
|
59
60
|
class VariantEntries extends variant_api_adapter_1.default {
|
|
60
61
|
constructor(config) {
|
|
61
62
|
const conf = {
|
|
@@ -72,13 +73,29 @@ class VariantEntries extends variant_api_adapter_1.default {
|
|
|
72
73
|
};
|
|
73
74
|
super(Object.assign((0, omit_1.default)(config, ['helpers']), conf));
|
|
74
75
|
this.config = config;
|
|
76
|
+
this.processInitialized = false;
|
|
75
77
|
this.entriesMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(config.backupDir), 'mapper', 'entries');
|
|
76
78
|
this.personalizeConfig = this.config.modules.personalize;
|
|
77
79
|
this.entriesDirPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(config.backupDir), (0, cli_utilities_1.sanitizePath)(config.modules.entries.dirName));
|
|
78
80
|
this.failedVariantPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'failed-entry-variants.json');
|
|
79
81
|
this.failedVariantEntries = new Map();
|
|
80
82
|
if (this.config && this.config.context) {
|
|
81
|
-
this.config.context.module =
|
|
83
|
+
this.config.context.module = constants_1.MODULE_CONTEXTS.VARIANT_ENTRIES;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Set parent progress manager for integration with entries module
|
|
88
|
+
*/
|
|
89
|
+
setParentProgressManager(parentProgress) {
|
|
90
|
+
this.parentProgressManager = parentProgress;
|
|
91
|
+
this.progress = parentProgress;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Update progress for a specific item
|
|
95
|
+
*/
|
|
96
|
+
updateProgress(success, itemName, error, processName) {
|
|
97
|
+
if (this.progress) {
|
|
98
|
+
this.progress.tick(success, itemName, error, processName);
|
|
82
99
|
}
|
|
83
100
|
}
|
|
84
101
|
/**
|
|
@@ -91,53 +108,96 @@ class VariantEntries extends variant_api_adapter_1.default {
|
|
|
91
108
|
*/
|
|
92
109
|
import() {
|
|
93
110
|
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
cli_utilities_1.log.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
cli_utilities_1.log.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
cli_utilities_1.log.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
111
|
+
var _a, _b, _c;
|
|
112
|
+
try {
|
|
113
|
+
const filePath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'data-for-variant-entry.json');
|
|
114
|
+
const variantIdPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', (0, cli_utilities_1.sanitizePath)(this.personalizeConfig.dirName), (0, cli_utilities_1.sanitizePath)(this.personalizeConfig.experiences.dirName), 'variants-uid-mapping.json');
|
|
115
|
+
cli_utilities_1.log.debug(`Checking for variant entry data file: ${filePath}`, this.config.context);
|
|
116
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
117
|
+
cli_utilities_1.log.warn(`Variant entry data file not found at path: ${filePath}, skipping import`, this.config.context);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
cli_utilities_1.log.debug(`Checking for variant ID mapping file: ${variantIdPath}`, this.config.context);
|
|
121
|
+
if (!(0, fs_1.existsSync)(variantIdPath)) {
|
|
122
|
+
cli_utilities_1.log.error('Variant UID mapping file not found', this.config.context);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const entriesForVariants = utils_1.fsUtil.readFile(filePath, true);
|
|
126
|
+
cli_utilities_1.log.debug(`Loaded ${(entriesForVariants === null || entriesForVariants === void 0 ? void 0 : entriesForVariants.length) || 0} entries for variant processing`, this.config.context);
|
|
127
|
+
if ((0, isEmpty_1.default)(entriesForVariants)) {
|
|
128
|
+
cli_utilities_1.log.warn('No entries found for variant import', this.config.context);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const entriesUidMapperPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'uid-mapping.json');
|
|
132
|
+
const assetUidMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'assets', 'uid-mapping.json');
|
|
133
|
+
const assetUrlMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'assets', 'url-mapping.json');
|
|
134
|
+
const taxonomiesPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', (0, cli_utilities_1.sanitizePath)(this.config.modules.taxonomies.dirName), 'terms', 'success.json');
|
|
135
|
+
const marketplaceAppMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'marketplace_apps', 'uid-mapping.json');
|
|
136
|
+
const envPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'environments', 'environments.json');
|
|
137
|
+
cli_utilities_1.log.debug('Loading variant ID mapping and dependency data', this.config.context);
|
|
138
|
+
// NOTE Read and store list of variant IDs
|
|
139
|
+
this.variantIdList = (utils_1.fsUtil.readFile(variantIdPath, true) || {});
|
|
140
|
+
if ((0, isEmpty_1.default)(this.variantIdList)) {
|
|
141
|
+
cli_utilities_1.log.warn('Empty variant UID data found', this.config.context);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// NOTE entry relational data lookup dependencies.
|
|
145
|
+
this.entriesUidMapper = (utils_1.fsUtil.readFile(entriesUidMapperPath, true) || {});
|
|
146
|
+
this.installedExtensions = (utils_1.fsUtil.readFile(marketplaceAppMapperPath) || { extension_uid: {} })
|
|
147
|
+
.extension_uid;
|
|
148
|
+
this.taxonomies = (utils_1.fsUtil.readFile(taxonomiesPath, true) || {});
|
|
149
|
+
this.assetUidMapper = (utils_1.fsUtil.readFile(assetUidMapperPath, true) || {});
|
|
150
|
+
this.assetUrlMapper = (utils_1.fsUtil.readFile(assetUrlMapperPath, true) || {});
|
|
151
|
+
this.environments = (utils_1.fsUtil.readFile(envPath, true) || {});
|
|
152
|
+
cli_utilities_1.log.debug(`Loaded dependency data - Entries: ${(_a = Object.keys(this.entriesUidMapper)) === null || _a === void 0 ? void 0 : _a.length}, Assets: ${(_b = Object.keys(this.assetUidMapper)) === null || _b === void 0 ? void 0 : _b.length}, Taxonomies: ${(_c = Object.keys(this.taxonomies)) === null || _c === void 0 ? void 0 : _c.length}`, this.config.context);
|
|
153
|
+
// Initialize progress manager - will be set up lazily when first variants are found
|
|
154
|
+
if (this.parentProgressManager) {
|
|
155
|
+
this.progress = this.parentProgressManager;
|
|
156
|
+
cli_utilities_1.log.debug('Using parent progress manager for variant entries import', this.config.context);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
this.progress = this.createSimpleProgress(constants_1.PROCESS_NAMES.VARIANT_ENTRIES);
|
|
160
|
+
cli_utilities_1.log.debug('Created standalone progress manager for variant entries import', this.config.context);
|
|
161
|
+
}
|
|
162
|
+
// set the token
|
|
163
|
+
yield this.variantInstance.init();
|
|
164
|
+
cli_utilities_1.log.info(`Processing ${entriesForVariants === null || entriesForVariants === void 0 ? void 0 : entriesForVariants.length} entries for variant import`, this.config.context);
|
|
165
|
+
for (const entriesForVariant of entriesForVariants) {
|
|
166
|
+
try {
|
|
167
|
+
yield this.importVariantEntries(entriesForVariant);
|
|
168
|
+
cli_utilities_1.log.debug(`Successfully processed variant entry: ${entriesForVariant.content_type}/${entriesForVariant.locale}/${entriesForVariant.entry_uid}`, this.config.context);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
(0, cli_utilities_1.handleAndLogError)(error, this.config.context, `Failed to import variant entry: ${entriesForVariant.content_type}/${entriesForVariant.locale}/${entriesForVariant.entry_uid}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Complete progress if we initialized it and own the progress manager
|
|
175
|
+
if (this.processInitialized && this.progress) {
|
|
176
|
+
const processName = this.parentProgressManager ? 'Variant Entries' : constants_1.PROCESS_NAMES.VARIANT_ENTRIES;
|
|
177
|
+
this.progress.completeProcess(processName, true);
|
|
178
|
+
cli_utilities_1.log.success(`Completed import of variant entries across ${entriesForVariants.length} entries`, this.config.context);
|
|
179
|
+
}
|
|
180
|
+
else if (entriesForVariants.length === 0) {
|
|
181
|
+
cli_utilities_1.log.info(`No variant entries found for import`, this.config.context);
|
|
182
|
+
}
|
|
183
|
+
// Only complete overall progress if we own the progress manager (no parent)
|
|
184
|
+
if (!this.parentProgressManager) {
|
|
185
|
+
this.completeProgress(true);
|
|
186
|
+
}
|
|
187
|
+
cli_utilities_1.log.success(`Variant entries imported successfully! Total entries: ${entriesForVariants.length} - processing completed`, this.config.context);
|
|
124
188
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
cli_utilities_1.log.info(`Processing ${entriesForVariants.length} entries for variant import`, this.config.context);
|
|
137
|
-
for (const entriesForVariant of entriesForVariants) {
|
|
138
|
-
yield this.importVariantEntries(entriesForVariant);
|
|
189
|
+
catch (error) {
|
|
190
|
+
// Complete progress with error if we initialized it
|
|
191
|
+
if (this.processInitialized && this.progress) {
|
|
192
|
+
const processName = this.parentProgressManager ? 'Variant Entries' : constants_1.PROCESS_NAMES.VARIANT_ENTRIES;
|
|
193
|
+
this.progress.completeProcess(processName, false);
|
|
194
|
+
}
|
|
195
|
+
if (!this.parentProgressManager) {
|
|
196
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Variant entries import failed');
|
|
197
|
+
}
|
|
198
|
+
(0, cli_utilities_1.handleAndLogError)(error, this.config.context, 'Variant entries import failed');
|
|
199
|
+
throw error;
|
|
139
200
|
}
|
|
140
|
-
cli_utilities_1.log.success('All variant entries have been imported and published successfully', this.config.context);
|
|
141
201
|
});
|
|
142
202
|
}
|
|
143
203
|
/**
|
|
@@ -147,9 +207,10 @@ class VariantEntries extends variant_api_adapter_1.default {
|
|
|
147
207
|
*/
|
|
148
208
|
importVariantEntries(entriesForVariant) {
|
|
149
209
|
return __awaiter(this, void 0, void 0, function* () {
|
|
210
|
+
let totalVariantEntries = 0;
|
|
150
211
|
const variantEntry = this.config.modules.variantEntry;
|
|
151
212
|
const { content_type, locale, entry_uid } = entriesForVariant;
|
|
152
|
-
cli_utilities_1.log.
|
|
213
|
+
cli_utilities_1.log.info(`Importing variant entries for: ${content_type}/${locale}/${entry_uid}`, this.config.context);
|
|
153
214
|
const ctConfig = this.config.modules['content-types'];
|
|
154
215
|
const contentType = JSON.parse((0, fs_1.readFileSync)((0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), (0, cli_utilities_1.sanitizePath)(ctConfig.dirName), `${(0, cli_utilities_1.sanitizePath)(content_type)}.json`), 'utf8'));
|
|
155
216
|
const variantEntryBasePath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.entriesDirPath), (0, cli_utilities_1.sanitizePath)(content_type), (0, cli_utilities_1.sanitizePath)(locale), (0, cli_utilities_1.sanitizePath)(variantEntry.dirName), (0, cli_utilities_1.sanitizePath)(entry_uid));
|
|
@@ -159,6 +220,26 @@ class VariantEntries extends variant_api_adapter_1.default {
|
|
|
159
220
|
try {
|
|
160
221
|
const variantEntries = (yield fs.readChunkFiles.next());
|
|
161
222
|
if (variantEntries === null || variantEntries === void 0 ? void 0 : variantEntries.length) {
|
|
223
|
+
totalVariantEntries = totalVariantEntries + variantEntries.length;
|
|
224
|
+
// Initialize progress ONLY when we find the first variants (lazy initialization)
|
|
225
|
+
if (!this.processInitialized && this.progress) {
|
|
226
|
+
const processName = this.parentProgressManager ? 'Variant Entries' : constants_1.PROCESS_NAMES.VARIANT_ENTRIES;
|
|
227
|
+
if (this.parentProgressManager) {
|
|
228
|
+
// Update the existing process total instead of creating a new one
|
|
229
|
+
this.progress.updateProcessTotal(processName, variantEntries.length);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
this.progress.addProcess(constants_1.PROCESS_NAMES.VARIANT_ENTRIES, variantEntries.length);
|
|
233
|
+
this.progress.startProcess(constants_1.PROCESS_NAMES.VARIANT_ENTRIES);
|
|
234
|
+
}
|
|
235
|
+
this.processInitialized = true;
|
|
236
|
+
cli_utilities_1.log.debug(`Initialized variant entries progress with first batch of ${variantEntries.length} variants`, this.config.context);
|
|
237
|
+
}
|
|
238
|
+
if (this.processInitialized && this.progress) {
|
|
239
|
+
const processName = this.parentProgressManager ? 'Variant Entries' : constants_1.PROCESS_NAMES.VARIANT_ENTRIES;
|
|
240
|
+
this.progress.updateProcessTotal(processName, totalVariantEntries);
|
|
241
|
+
cli_utilities_1.log.debug(`Updated progress total to: ${totalVariantEntries}`, this.config.context);
|
|
242
|
+
}
|
|
162
243
|
cli_utilities_1.log.debug(`Processing batch of ${variantEntries.length} variant entries`, this.config.context);
|
|
163
244
|
yield this.handleConcurrency(contentType, variantEntries, entriesForVariant);
|
|
164
245
|
}
|
|
@@ -192,20 +273,25 @@ class VariantEntries extends variant_api_adapter_1.default {
|
|
|
192
273
|
const batches = (0, chunk_1.default)(variantEntries, variantEntryConfig.apiConcurrency || 5);
|
|
193
274
|
if ((0, isEmpty_1.default)(batches))
|
|
194
275
|
return;
|
|
195
|
-
cli_utilities_1.log.debug(`Starting concurrent processing for ${variantEntries.length} variant entries`, this.config.context);
|
|
276
|
+
cli_utilities_1.log.debug(`Starting concurrent processing for ${variantEntries === null || variantEntries === void 0 ? void 0 : variantEntries.length} variant entries`, this.config.context);
|
|
196
277
|
for (const [, batch] of (0, entries_1.default)(batches)) {
|
|
197
278
|
batchNo += 1;
|
|
198
279
|
const allPromise = [];
|
|
199
280
|
const start = Date.now();
|
|
200
|
-
cli_utilities_1.log.debug(`Processing batch ${batchNo}/${batches.length} with ${batch.length} variant entries`, this.config.context);
|
|
281
|
+
cli_utilities_1.log.debug(`Processing batch ${batchNo}/${batches === null || batches === void 0 ? void 0 : batches.length} with ${batch === null || batch === void 0 ? void 0 : batch.length} variant entries`, this.config.context);
|
|
201
282
|
for (let [, variantEntry] of (0, entries_1.default)(batch)) {
|
|
202
283
|
const onSuccess = ({ response, apiData: { entryUid, variantUid } }) => {
|
|
203
284
|
cli_utilities_1.log.info(`Created entry variant: '${variantUid}' of entry uid ${entryUid} locale '${locale}'`, this.config.context);
|
|
285
|
+
const processName = this.parentProgressManager ? 'Variant Entries' : constants_1.PROCESS_NAMES.VARIANT_ENTRIES;
|
|
286
|
+
this.updateProgress(true, `variant entry: '${variantUid}' of entry uid ${entryUid} locale '${locale}'`, undefined, processName);
|
|
204
287
|
};
|
|
205
288
|
const onReject = ({ error, apiData }) => {
|
|
206
289
|
const { entryUid, variantUid } = apiData;
|
|
207
290
|
this.failedVariantEntries.set(variantUid, apiData);
|
|
208
291
|
(0, cli_utilities_1.handleAndLogError)(error, this.config.context, `Failed to create entry variant: '${variantUid}' of entry uid ${entryUid} locale '${locale}'`);
|
|
292
|
+
const processName = this.parentProgressManager ? 'Variant Entries' : constants_1.PROCESS_NAMES.VARIANT_ENTRIES;
|
|
293
|
+
this.updateProgress(false, `'${variantUid}' of entry uid ${entryUid} locale '${locale}'`, (error === null || error === void 0 ? void 0 : error.message) ||
|
|
294
|
+
`Failed to create entry variant: '${variantUid}' of entry uid ${entryUid} locale '${locale}'`, processName);
|
|
209
295
|
};
|
|
210
296
|
// NOTE Find new variant Id by old Id
|
|
211
297
|
const variantId = this.variantIdList[variantEntry._variant._uid];
|
|
@@ -357,7 +443,7 @@ class VariantEntries extends variant_api_adapter_1.default {
|
|
|
357
443
|
}
|
|
358
444
|
};
|
|
359
445
|
const pathsToUpdate = ((_b = (_a = variantEntry === null || variantEntry === void 0 ? void 0 : variantEntry._metadata) === null || _a === void 0 ? void 0 : _a.references) === null || _b === void 0 ? void 0 : _b.filter((ref) => ref._content_type_uid === 'sys_assets').map((ref) => ref.path)) || [];
|
|
360
|
-
cli_utilities_1.log.debug(`Found ${pathsToUpdate.length} file field paths to update`, this.config.context);
|
|
446
|
+
cli_utilities_1.log.debug(`Found ${pathsToUpdate === null || pathsToUpdate === void 0 ? void 0 : pathsToUpdate.length} file field paths to update`, this.config.context);
|
|
361
447
|
pathsToUpdate.forEach((path) => setValue(variantEntry, path.split('.')));
|
|
362
448
|
}
|
|
363
449
|
/**
|
|
@@ -382,11 +468,11 @@ class VariantEntries extends variant_api_adapter_1.default {
|
|
|
382
468
|
continue;
|
|
383
469
|
}
|
|
384
470
|
if (this.failedVariantEntries.has(variantEntryUID)) {
|
|
385
|
-
cli_utilities_1.log.
|
|
471
|
+
cli_utilities_1.log.info(`Variant UID not found. Skipping entry variant publish for ${variantEntryUID}`, this.config.context);
|
|
386
472
|
continue;
|
|
387
473
|
}
|
|
388
474
|
if ((_a = this.environments) === null || _a === void 0 ? void 0 : _a.length) {
|
|
389
|
-
cli_utilities_1.log.
|
|
475
|
+
cli_utilities_1.log.info('No environment found! Skipping entry variant publishing...', this.config.context);
|
|
390
476
|
return;
|
|
391
477
|
}
|
|
392
478
|
const onSuccess = ({ response, apiData: { entryUid, variantUid } }) => {
|
|
@@ -397,7 +483,7 @@ class VariantEntries extends variant_api_adapter_1.default {
|
|
|
397
483
|
};
|
|
398
484
|
const { environments, locales } = this.serializePublishEntries(variantEntry);
|
|
399
485
|
if ((environments === null || environments === void 0 ? void 0 : environments.length) === 0 || (locales === null || locales === void 0 ? void 0 : locales.length) === 0) {
|
|
400
|
-
cli_utilities_1.log.
|
|
486
|
+
cli_utilities_1.log.info(`Skipping publish for variant ${newVariantUid} - no environments or locales`, this.config.context);
|
|
401
487
|
continue;
|
|
402
488
|
}
|
|
403
489
|
cli_utilities_1.log.debug(`Publishing variant ${newVariantUid} to environments: ${environments.join(', ')}, locales: ${locales.join(', ')}`, this.config.context);
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -14,7 +14,6 @@ export type masterLocale = {
|
|
|
14
14
|
};
|
|
15
15
|
export interface DefaultConfig {
|
|
16
16
|
context: Context;
|
|
17
|
-
contentVersion: number;
|
|
18
17
|
versioning: boolean;
|
|
19
18
|
host: string;
|
|
20
19
|
cdn?: string;
|
|
@@ -209,7 +208,6 @@ export interface DefaultConfig {
|
|
|
209
208
|
writeConcurrency: number;
|
|
210
209
|
developerHubBaseUrl: string;
|
|
211
210
|
marketplaceAppEncryptionKey: string;
|
|
212
|
-
onlyTSModules: string[];
|
|
213
211
|
}
|
|
214
212
|
export interface ExportConfig extends DefaultConfig {
|
|
215
213
|
exportDir: string;
|
package/lib/types/utils.d.ts
CHANGED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export declare const PROCESS_NAMES: {
|
|
2
|
+
readonly PROJECTS: "Projects";
|
|
3
|
+
readonly ATTRIBUTES: "Attributes";
|
|
4
|
+
readonly AUDIENCES: "Audiences";
|
|
5
|
+
readonly EVENTS: "Events";
|
|
6
|
+
readonly EXPERIENCES: "Experiences";
|
|
7
|
+
readonly VARIANT_ENTRIES: "Variant Entries";
|
|
8
|
+
};
|
|
9
|
+
export declare const MODULE_DISPLAY_MAPPER: {
|
|
10
|
+
readonly events: "Events";
|
|
11
|
+
readonly attributes: "Attributes";
|
|
12
|
+
readonly audiences: "Audiences";
|
|
13
|
+
readonly experiences: "Experiences";
|
|
14
|
+
readonly projects: "Projects";
|
|
15
|
+
readonly 'variant-entries': "Variant Entries";
|
|
16
|
+
};
|
|
17
|
+
export declare const MODULE_CONTEXTS: {
|
|
18
|
+
readonly PROJECTS: "projects";
|
|
19
|
+
readonly ATTRIBUTES: "attributes";
|
|
20
|
+
readonly AUDIENCES: "audiences";
|
|
21
|
+
readonly EVENTS: "events";
|
|
22
|
+
readonly EXPERIENCES: "experiences";
|
|
23
|
+
readonly VARIANT_ENTRIES: "variant-entries";
|
|
24
|
+
};
|
|
25
|
+
export declare const EXPORT_PROCESS_STATUS: {
|
|
26
|
+
readonly Projects: {
|
|
27
|
+
readonly FETCHING: "Fetching projects...";
|
|
28
|
+
readonly EXPORTING: "Exporting projects...";
|
|
29
|
+
readonly FAILED: "Failed to export projects.";
|
|
30
|
+
};
|
|
31
|
+
readonly Attributes: {
|
|
32
|
+
readonly FETCHING: "Fetching attributes...";
|
|
33
|
+
readonly EXPORTING: "Exporting attributes...";
|
|
34
|
+
readonly FAILED: "Failed to export attributes.";
|
|
35
|
+
};
|
|
36
|
+
readonly Audiences: {
|
|
37
|
+
readonly FETCHING: "Fetching audiences...";
|
|
38
|
+
readonly EXPORTING: "Exporting audiences...";
|
|
39
|
+
readonly FAILED: "Failed to export audiences.";
|
|
40
|
+
};
|
|
41
|
+
readonly Events: {
|
|
42
|
+
readonly FETCHING: "Fetching events...";
|
|
43
|
+
readonly EXPORTING: "Exporting events...";
|
|
44
|
+
readonly FAILED: "Failed to export events.";
|
|
45
|
+
};
|
|
46
|
+
readonly Experiences: {
|
|
47
|
+
readonly FETCHING: "Fetching experiences...";
|
|
48
|
+
readonly EXPORTING: "Exporting experiences...";
|
|
49
|
+
readonly FAILED: "Failed to export experiences.";
|
|
50
|
+
};
|
|
51
|
+
readonly "Variant Entries": {
|
|
52
|
+
readonly PROCESSING: "Processing variant entries...";
|
|
53
|
+
readonly EXPORTING: "Exporting variant entries...";
|
|
54
|
+
readonly FAILED: "Failed to export variant entries.";
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export declare const IMPORT_PROCESS_STATUS: {
|
|
58
|
+
readonly Projects: {
|
|
59
|
+
readonly CREATING: "Creating projects...";
|
|
60
|
+
readonly IMPORTING: "Importing projects...";
|
|
61
|
+
readonly FAILED: "Failed to import projects.";
|
|
62
|
+
};
|
|
63
|
+
readonly Attributes: {
|
|
64
|
+
readonly CREATING: "Creating attributes...";
|
|
65
|
+
readonly IMPORTING: "Importing attributes...";
|
|
66
|
+
readonly FAILED: "Failed to import attributes.";
|
|
67
|
+
};
|
|
68
|
+
readonly Audiences: {
|
|
69
|
+
readonly CREATING: "Creating audiences...";
|
|
70
|
+
readonly IMPORTING: "Importing audiences...";
|
|
71
|
+
readonly FAILED: "Failed to import audiences.";
|
|
72
|
+
};
|
|
73
|
+
readonly Events: {
|
|
74
|
+
readonly CREATING: "Creating events...";
|
|
75
|
+
readonly IMPORTING: "Importing events...";
|
|
76
|
+
readonly FAILED: "Failed to import events.";
|
|
77
|
+
};
|
|
78
|
+
readonly Experiences: {
|
|
79
|
+
readonly CREATING: "Creating experiences...";
|
|
80
|
+
readonly IMPORTING: "Importing experiences...";
|
|
81
|
+
readonly FAILED: "Failed to import experiences.";
|
|
82
|
+
};
|
|
83
|
+
readonly "Variant Entries": {
|
|
84
|
+
readonly PROCESSING: "Processing variant entries...";
|
|
85
|
+
readonly IMPORTING: "Importing variant entries...";
|
|
86
|
+
readonly FAILED: "Failed to import variant entries.";
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
export type ProcessName = typeof PROCESS_NAMES[keyof typeof PROCESS_NAMES];
|
|
90
|
+
export type ModuleKey = keyof typeof MODULE_DISPLAY_MAPPER;
|
|
91
|
+
export type ModuleContext = typeof MODULE_CONTEXTS[keyof typeof MODULE_CONTEXTS];
|