@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.
Files changed (55) hide show
  1. package/lib/export/attributes.d.ts +2 -2
  2. package/lib/export/attributes.js +51 -23
  3. package/lib/export/audiences.d.ts +2 -2
  4. package/lib/export/audiences.js +50 -24
  5. package/lib/export/events.d.ts +2 -2
  6. package/lib/export/events.js +52 -24
  7. package/lib/export/experiences.js +87 -54
  8. package/lib/export/projects.d.ts +3 -2
  9. package/lib/export/projects.js +55 -63
  10. package/lib/export/variant-entries.d.ts +19 -0
  11. package/lib/export/variant-entries.js +76 -1
  12. package/lib/import/attribute.d.ts +2 -0
  13. package/lib/import/attribute.js +83 -37
  14. package/lib/import/audiences.d.ts +2 -0
  15. package/lib/import/audiences.js +85 -41
  16. package/lib/import/events.d.ts +3 -1
  17. package/lib/import/events.js +86 -30
  18. package/lib/import/experiences.d.ts +2 -0
  19. package/lib/import/experiences.js +93 -39
  20. package/lib/import/project.d.ts +2 -0
  21. package/lib/import/project.js +81 -22
  22. package/lib/import/variant-entries.d.ts +10 -0
  23. package/lib/import/variant-entries.js +139 -53
  24. package/lib/index.d.ts +1 -0
  25. package/lib/index.js +1 -0
  26. package/lib/types/export-config.d.ts +0 -2
  27. package/lib/types/import-config.d.ts +0 -1
  28. package/lib/types/utils.d.ts +1 -1
  29. package/lib/utils/constants.d.ts +91 -0
  30. package/lib/utils/constants.js +93 -0
  31. package/lib/utils/personalization-api-adapter.d.ts +34 -1
  32. package/lib/utils/personalization-api-adapter.js +180 -53
  33. package/lib/utils/variant-api-adapter.d.ts +28 -1
  34. package/lib/utils/variant-api-adapter.js +89 -32
  35. package/package.json +2 -2
  36. package/src/export/attributes.ts +84 -34
  37. package/src/export/audiences.ts +87 -41
  38. package/src/export/events.ts +84 -41
  39. package/src/export/experiences.ts +155 -83
  40. package/src/export/projects.ts +71 -39
  41. package/src/export/variant-entries.ts +136 -12
  42. package/src/import/attribute.ts +105 -49
  43. package/src/import/audiences.ts +110 -54
  44. package/src/import/events.ts +104 -41
  45. package/src/import/experiences.ts +140 -62
  46. package/src/import/project.ts +108 -38
  47. package/src/import/variant-entries.ts +188 -75
  48. package/src/index.ts +2 -1
  49. package/src/types/export-config.ts +0 -2
  50. package/src/types/import-config.ts +0 -1
  51. package/src/types/utils.ts +1 -1
  52. package/src/utils/constants.ts +98 -0
  53. package/src/utils/personalization-api-adapter.ts +212 -76
  54. package/src/utils/variant-api-adapter.ts +137 -50
  55. package/tsconfig.json +1 -1
@@ -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 = 'project';
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
- const personalize = this.config.modules.personalize;
35
- const { dirName, fileName } = personalize.projects;
36
- 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));
37
- cli_utilities_1.log.debug(`Checking for project file: ${projectPath}`, this.config.context);
38
- if ((0, fs_1.existsSync)(projectPath)) {
39
- const projects = JSON.parse((0, fs_1.readFileSync)(projectPath, 'utf8'));
40
- cli_utilities_1.log.debug(`Loaded ${(projects === null || projects === void 0 ? void 0 : projects.length) || 0} projects from file`, this.config.context);
41
- if (!projects || projects.length < 1) {
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 projects) {
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
- const projectRes = yield createProject(this.config.personalizeProjectName);
66
- this.config.modules.personalize.project_id = projectRes.uid;
67
- this.config.modules.personalize.importData = true;
68
- yield utils_1.fsUtil.makeDirectory(this.projectMapperFolderPath);
69
- utils_1.fsUtil.writeFile((0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.projectMapperFolderPath), 'projects.json'), projectRes);
70
- cli_utilities_1.log.success(`Project created successfully: ${projectRes.uid}`, this.config.context);
71
- cli_utilities_1.log.debug(`Project data saved to: ${this.projectMapperFolderPath}/projects.json`, this.config.context);
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
- else {
75
- this.config.modules.personalize.importData = false; // Stop personalize import if stack not connected to any project
76
- cli_utilities_1.log.warn(`Project file not found: ${projectPath}`, this.config.context);
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 = 'variant-entries';
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
- const filePath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'data-for-variant-entry.json');
95
- 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');
96
- cli_utilities_1.log.debug(`Checking for variant entry data file: ${filePath}`, this.config.context);
97
- if (!(0, fs_1.existsSync)(filePath)) {
98
- cli_utilities_1.log.warn(`Variant entry data file not found at path: ${filePath}, skipping import`, this.config.context);
99
- return;
100
- }
101
- cli_utilities_1.log.debug(`Checking for variant ID mapping file: ${variantIdPath}`, this.config.context);
102
- if (!(0, fs_1.existsSync)(variantIdPath)) {
103
- cli_utilities_1.log.error('Variant UID mapping file not found', this.config.context);
104
- return;
105
- }
106
- const entriesForVariants = utils_1.fsUtil.readFile(filePath, true);
107
- cli_utilities_1.log.debug(`Loaded ${(entriesForVariants === null || entriesForVariants === void 0 ? void 0 : entriesForVariants.length) || 0} entries for variant processing`, this.config.context);
108
- if ((0, isEmpty_1.default)(entriesForVariants)) {
109
- cli_utilities_1.log.warn('No entries found for variant import', this.config.context);
110
- return;
111
- }
112
- const entriesUidMapperPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'uid-mapping.json');
113
- const assetUidMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'assets', 'uid-mapping.json');
114
- const assetUrlMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'assets', 'url-mapping.json');
115
- 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');
116
- const marketplaceAppMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'marketplace_apps', 'uid-mapping.json');
117
- const envPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'environments', 'environments.json');
118
- cli_utilities_1.log.debug('Loading variant ID mapping and dependency data', this.config.context);
119
- // NOTE Read and store list of variant IDs
120
- this.variantIdList = (utils_1.fsUtil.readFile(variantIdPath, true) || {});
121
- if ((0, isEmpty_1.default)(this.variantIdList)) {
122
- cli_utilities_1.log.warn('Empty variant UID data found', this.config.context);
123
- return;
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
- // NOTE entry relational data lookup dependencies.
126
- this.entriesUidMapper = (utils_1.fsUtil.readFile(entriesUidMapperPath, true) || {});
127
- this.installedExtensions = (utils_1.fsUtil.readFile(marketplaceAppMapperPath) || { extension_uid: {} })
128
- .extension_uid;
129
- this.taxonomies = (utils_1.fsUtil.readFile(taxonomiesPath, true) || {});
130
- this.assetUidMapper = (utils_1.fsUtil.readFile(assetUidMapperPath, true) || {});
131
- this.assetUrlMapper = (utils_1.fsUtil.readFile(assetUrlMapperPath, true) || {});
132
- this.environments = (utils_1.fsUtil.readFile(envPath, true) || {});
133
- cli_utilities_1.log.debug(`Loaded dependency data - Entries: ${Object.keys(this.entriesUidMapper).length}, Assets: ${Object.keys(this.assetUidMapper).length}, Taxonomies: ${Object.keys(this.taxonomies).length}`, this.config.context);
134
- // set the token
135
- yield this.variantInstance.init();
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.debug(`Importing variant entries for: ${content_type}/${locale}/${entry_uid}`, this.config.context);
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.debug(`Variant UID not found. Skipping entry variant publish for ${variantEntryUID}`, this.config.context);
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.debug('No environment found! Skipping entry variant publishing...', this.config.context);
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.debug(`Skipping publish for variant ${newVariantUid} - no environments or locales`, this.config.context);
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
@@ -3,3 +3,4 @@ export * from './utils';
3
3
  export * from './export';
4
4
  export * from './import';
5
5
  export * from './messages';
6
+ export * from './utils/constants';
package/lib/index.js CHANGED
@@ -19,3 +19,4 @@ __exportStar(require("./utils"), exports);
19
19
  __exportStar(require("./export"), exports);
20
20
  __exportStar(require("./import"), exports);
21
21
  __exportStar(require("./messages"), exports);
22
+ __exportStar(require("./utils/constants"), exports);
@@ -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;
@@ -77,7 +77,6 @@ export interface ImportConfig extends ImportDefaultConfig, AnyProperty {
77
77
  authtoken?: string;
78
78
  destinationStackName?: string;
79
79
  org_uid?: string;
80
- contentVersion: number;
81
80
  replaceExisting?: boolean;
82
81
  skipExisting?: boolean;
83
82
  stackName?: string;
@@ -9,7 +9,7 @@ export interface Context {
9
9
  command: string;
10
10
  module: string;
11
11
  userId: string | undefined;
12
- email: string | undefined;
12
+ email?: string | undefined;
13
13
  sessionId: string | undefined;
14
14
  clientId?: string | undefined;
15
15
  apiKey: string;
@@ -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];