@contentstack/cli-variants 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/lib/export/attributes.js +27 -10
  2. package/lib/export/audiences.js +28 -10
  3. package/lib/export/events.js +28 -10
  4. package/lib/export/experiences.js +48 -13
  5. package/lib/export/projects.js +24 -6
  6. package/lib/export/variant-entries.js +25 -4
  7. package/lib/import/attribute.d.ts +2 -3
  8. package/lib/import/attribute.js +16 -8
  9. package/lib/import/audiences.d.ts +2 -3
  10. package/lib/import/audiences.js +21 -8
  11. package/lib/import/events.d.ts +3 -4
  12. package/lib/import/events.js +16 -9
  13. package/lib/import/experiences.d.ts +2 -3
  14. package/lib/import/experiences.js +60 -17
  15. package/lib/import/project.d.ts +2 -3
  16. package/lib/import/project.js +11 -6
  17. package/lib/import/variant-entries.js +62 -25
  18. package/lib/types/export-config.d.ts +2 -1
  19. package/lib/types/utils.d.ts +11 -0
  20. package/lib/utils/attributes-helper.js +17 -1
  21. package/lib/utils/audiences-helper.js +37 -6
  22. package/lib/utils/events-helper.js +17 -4
  23. package/lib/utils/personalization-api-adapter.d.ts +2 -1
  24. package/lib/utils/personalization-api-adapter.js +119 -27
  25. package/lib/utils/variant-api-adapter.d.ts +4 -1
  26. package/lib/utils/variant-api-adapter.js +91 -17
  27. package/package.json +8 -5
  28. package/src/export/attributes.ts +34 -10
  29. package/src/export/audiences.ts +35 -7
  30. package/src/export/events.ts +35 -7
  31. package/src/export/experiences.ts +74 -24
  32. package/src/export/projects.ts +31 -7
  33. package/src/export/variant-entries.ts +47 -12
  34. package/src/import/attribute.ts +22 -9
  35. package/src/import/audiences.ts +28 -10
  36. package/src/import/events.ts +21 -10
  37. package/src/import/experiences.ts +74 -20
  38. package/src/import/project.ts +22 -8
  39. package/src/import/variant-entries.ts +116 -40
  40. package/src/types/export-config.ts +2 -1
  41. package/src/types/utils.ts +12 -0
  42. package/src/utils/attributes-helper.ts +21 -2
  43. package/src/utils/audiences-helper.ts +41 -1
  44. package/src/utils/events-helper.ts +19 -1
  45. package/src/utils/personalization-api-adapter.ts +95 -19
  46. package/src/utils/variant-api-adapter.ts +79 -8
@@ -14,7 +14,7 @@ const fs_1 = require("fs");
14
14
  const cli_utilities_1 = require("@contentstack/cli-utilities");
15
15
  const utils_1 = require("../utils");
16
16
  class Audiences extends utils_1.PersonalizationAdapter {
17
- constructor(config, log = console.log) {
17
+ constructor(config) {
18
18
  const conf = {
19
19
  config,
20
20
  baseURL: config.modules.personalize.baseURL[config.region.name],
@@ -22,7 +22,6 @@ class Audiences extends utils_1.PersonalizationAdapter {
22
22
  };
23
23
  super(Object.assign(config, conf));
24
24
  this.config = config;
25
- this.log = log;
26
25
  this.personalizeConfig = this.config.modules.personalize;
27
26
  this.audienceConfig = this.personalizeConfig.audiences;
28
27
  this.attributeConfig = this.personalizeConfig.attributes;
@@ -31,6 +30,7 @@ class Audiences extends utils_1.PersonalizationAdapter {
31
30
  this.audiencesUidMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.audienceMapperDirPath), 'uid-mapping.json');
32
31
  this.attributesMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.mapperDirPath), (0, cli_utilities_1.sanitizePath)(this.attributeConfig.dirName), 'uid-mapping.json');
33
32
  this.audiencesUidMapper = {};
33
+ this.config.context.module = 'audiences';
34
34
  }
35
35
  /**
36
36
  * The function asynchronously imports audiences from a JSON file and creates them in the system.
@@ -38,40 +38,53 @@ class Audiences extends utils_1.PersonalizationAdapter {
38
38
  import() {
39
39
  return __awaiter(this, void 0, void 0, function* () {
40
40
  var _a, _b;
41
- this.log(this.config, this.$t(this.messages.IMPORT_MSG, { module: 'Audiences' }), 'info');
42
41
  yield this.init();
43
42
  yield utils_1.fsUtil.makeDirectory(this.audienceMapperDirPath);
43
+ cli_utilities_1.log.debug(`Created mapper directory: ${this.audienceMapperDirPath}`, this.config.context);
44
44
  const { dirName, fileName } = this.audienceConfig;
45
45
  const audiencesPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.data), (0, cli_utilities_1.sanitizePath)(this.personalizeConfig.dirName), (0, cli_utilities_1.sanitizePath)(dirName), (0, cli_utilities_1.sanitizePath)(fileName));
46
+ cli_utilities_1.log.debug(`Checking for audiences file: ${audiencesPath}`, this.config.context);
46
47
  if ((0, fs_1.existsSync)(audiencesPath)) {
47
48
  try {
48
49
  const audiences = utils_1.fsUtil.readFile(audiencesPath, true);
50
+ cli_utilities_1.log.info(`Found ${audiences.length} audiences to import`, this.config.context);
49
51
  const attributesUid = utils_1.fsUtil.readFile(this.attributesMapperPath, true) || {};
52
+ cli_utilities_1.log.debug(`Loaded ${Object.keys(attributesUid).length} attribute mappings for audience processing`, this.config.context);
50
53
  for (const audience of audiences) {
51
54
  let { name, definition, description, uid } = audience;
55
+ cli_utilities_1.log.debug(`Processing audience: ${name} (${uid})`, this.config.context);
52
56
  try {
53
57
  //check whether reference attributes exists or not
54
58
  if ((_a = definition.rules) === null || _a === void 0 ? void 0 : _a.length) {
59
+ cli_utilities_1.log.debug(`Processing ${definition.rules.length} definition rules for audience: ${name}`, this.config.context);
55
60
  definition.rules = (0, utils_1.lookUpAttributes)(definition.rules, attributesUid);
61
+ cli_utilities_1.log.debug(`Processed definition rules, remaining rules: ${definition.rules.length}`, this.config.context);
56
62
  }
63
+ else {
64
+ cli_utilities_1.log.debug(`No definition rules found for audience: ${name}`, this.config.context);
65
+ }
66
+ cli_utilities_1.log.debug(`Creating audience: ${name}`, this.config.context);
57
67
  const audienceRes = yield this.createAudience({ definition, name, description });
58
68
  //map old audience uid to new audience uid
59
69
  //mapper file is used to check whether audience created or not before creating experience
60
70
  this.audiencesUidMapper[uid] = (_b = audienceRes === null || audienceRes === void 0 ? void 0 : audienceRes.uid) !== null && _b !== void 0 ? _b : '';
71
+ cli_utilities_1.log.debug(`Created audience: ${uid} -> ${audienceRes === null || audienceRes === void 0 ? void 0 : audienceRes.uid}`, this.config.context);
61
72
  }
62
73
  catch (error) {
63
- this.log(this.config, `Failed to create audience uid: ${uid}, name: ${name}`, 'error');
64
- this.log(this.config, error, 'error');
74
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context, `Failed to create audience: ${name} (${uid})`);
65
75
  }
66
76
  }
67
77
  utils_1.fsUtil.writeFile(this.audiencesUidMapperPath, this.audiencesUidMapper);
68
- this.log(this.config, this.$t(this.messages.CREATE_SUCCESS, { module: 'Audiences' }), 'info');
78
+ cli_utilities_1.log.debug(`Saved ${Object.keys(this.audiencesUidMapper).length} audience mappings to: ${this.audiencesUidMapperPath}`, this.config.context);
79
+ cli_utilities_1.log.success('Audiences imported successfully', this.config.context);
69
80
  }
70
81
  catch (error) {
71
- this.log(this.config, this.$t(this.messages.CREATE_FAILURE, { module: 'Audiences' }), 'error');
72
- this.log(this.config, error, 'error');
82
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context);
73
83
  }
74
84
  }
85
+ else {
86
+ cli_utilities_1.log.warn(`Audiences file not found: ${audiencesPath}`, this.config.context);
87
+ }
75
88
  });
76
89
  }
77
90
  }
@@ -1,17 +1,16 @@
1
1
  import { PersonalizationAdapter } from '../utils';
2
- import { ImportConfig, LogType } from '../types';
2
+ import { ImportConfig } from '../types';
3
3
  export default class Events extends PersonalizationAdapter<ImportConfig> {
4
4
  readonly config: ImportConfig;
5
- private readonly log;
6
5
  private mapperDirPath;
7
6
  private eventMapperDirPath;
8
7
  private eventsUidMapperPath;
9
8
  private eventsUidMapper;
10
9
  private personalizeConfig;
11
10
  private eventsConfig;
12
- constructor(config: ImportConfig, log?: LogType);
11
+ constructor(config: ImportConfig);
13
12
  /**
14
- * The function asynchronously imports attributes from a JSON file and creates them in the system.
13
+ * The function asynchronously imports events from a JSON file and creates them in the system.
15
14
  */
16
15
  import(): Promise<void>;
17
16
  }
@@ -14,7 +14,7 @@ const fs_1 = require("fs");
14
14
  const cli_utilities_1 = require("@contentstack/cli-utilities");
15
15
  const utils_1 = require("../utils");
16
16
  class Events extends utils_1.PersonalizationAdapter {
17
- constructor(config, log = console.log) {
17
+ constructor(config) {
18
18
  const conf = {
19
19
  config,
20
20
  baseURL: config.modules.personalize.baseURL[config.region.name],
@@ -22,47 +22,54 @@ class Events extends utils_1.PersonalizationAdapter {
22
22
  };
23
23
  super(Object.assign(config, conf));
24
24
  this.config = config;
25
- this.log = log;
26
25
  this.personalizeConfig = this.config.modules.personalize;
27
26
  this.eventsConfig = this.personalizeConfig.events;
28
27
  this.mapperDirPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', (0, cli_utilities_1.sanitizePath)(this.personalizeConfig.dirName));
29
28
  this.eventMapperDirPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.mapperDirPath), (0, cli_utilities_1.sanitizePath)(this.eventsConfig.dirName));
30
29
  this.eventsUidMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.eventMapperDirPath), 'uid-mapping.json');
31
30
  this.eventsUidMapper = {};
31
+ this.config.context.module = 'events';
32
32
  }
33
33
  /**
34
- * The function asynchronously imports attributes from a JSON file and creates them in the system.
34
+ * The function asynchronously imports events from a JSON file and creates them in the system.
35
35
  */
36
36
  import() {
37
37
  return __awaiter(this, void 0, void 0, function* () {
38
38
  var _a;
39
- this.log(this.config, this.$t(this.messages.IMPORT_MSG, { module: 'Events' }), 'info');
40
39
  yield this.init();
41
40
  yield utils_1.fsUtil.makeDirectory(this.eventMapperDirPath);
41
+ cli_utilities_1.log.debug(`Created mapper directory: ${this.eventMapperDirPath}`, this.config.context);
42
42
  const { dirName, fileName } = this.eventsConfig;
43
43
  const eventsPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.data), (0, cli_utilities_1.sanitizePath)(this.personalizeConfig.dirName), (0, cli_utilities_1.sanitizePath)(dirName), (0, cli_utilities_1.sanitizePath)(fileName));
44
+ cli_utilities_1.log.debug(`Checking for events file: ${eventsPath}`, this.config.context);
44
45
  if ((0, fs_1.existsSync)(eventsPath)) {
45
46
  try {
46
47
  const events = utils_1.fsUtil.readFile(eventsPath, true);
48
+ cli_utilities_1.log.info(`Found ${events.length} events to import`, this.config.context);
47
49
  for (const event of events) {
48
50
  const { key, description, uid } = event;
51
+ cli_utilities_1.log.debug(`Processing event: ${key} (${uid})`, this.config.context);
49
52
  try {
53
+ cli_utilities_1.log.debug(`Creating event: ${key}`, this.config.context);
50
54
  const eventsResponse = yield this.createEvents({ key, description });
51
55
  this.eventsUidMapper[uid] = (_a = eventsResponse === null || eventsResponse === void 0 ? void 0 : eventsResponse.uid) !== null && _a !== void 0 ? _a : '';
56
+ cli_utilities_1.log.debug(`Created event: ${uid} -> ${eventsResponse === null || eventsResponse === void 0 ? void 0 : eventsResponse.uid}`, this.config.context);
52
57
  }
53
58
  catch (error) {
54
- this.log(this.config, `failed to create event uid: ${uid}`, 'error');
55
- this.log(this.config, error, 'error');
59
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context, `Failed to create event: ${key} (${uid})`);
56
60
  }
57
61
  }
58
62
  utils_1.fsUtil.writeFile(this.eventsUidMapperPath, this.eventsUidMapper);
59
- this.log(this.config, this.$t(this.messages.CREATE_SUCCESS, { module: 'Events' }), 'info');
63
+ cli_utilities_1.log.debug(`Saved ${Object.keys(this.eventsUidMapper).length} event mappings to: ${this.eventsUidMapperPath}`, this.config.context);
64
+ cli_utilities_1.log.success('Events imported successfully', this.config.context);
60
65
  }
61
66
  catch (error) {
62
- this.log(this.config, this.$t(this.messages.CREATE_FAILURE, { module: 'Events' }), 'error');
63
- this.log(this.config, error, 'error');
67
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context);
64
68
  }
65
69
  }
70
+ else {
71
+ cli_utilities_1.log.warn(`Events file not found: ${eventsPath}`, this.config.context);
72
+ }
66
73
  });
67
74
  }
68
75
  }
@@ -1,8 +1,7 @@
1
1
  import { PersonalizationAdapter } from '../utils';
2
- import { ImportConfig, ExperienceStruct, LogType } from '../types';
2
+ import { ImportConfig, ExperienceStruct } from '../types';
3
3
  export default class Experiences extends PersonalizationAdapter<ImportConfig> {
4
4
  readonly config: ImportConfig;
5
- private readonly log;
6
5
  private createdCTs;
7
6
  private mapperDirPath;
8
7
  private cmsVariantPath;
@@ -30,7 +29,7 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> {
30
29
  private personalizeConfig;
31
30
  private audienceConfig;
32
31
  private experienceConfig;
33
- constructor(config: ImportConfig, log?: LogType);
32
+ constructor(config: ImportConfig);
34
33
  /**
35
34
  * The function asynchronously imports experiences from a JSON file and creates them in the system.
36
35
  */
@@ -30,7 +30,7 @@ const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
30
30
  const cli_utilities_1 = require("@contentstack/cli-utilities");
31
31
  const utils_1 = require("../utils");
32
32
  class Experiences extends utils_1.PersonalizationAdapter {
33
- constructor(config, log = console.log) {
33
+ constructor(config) {
34
34
  var _a, _b, _c, _d;
35
35
  const conf = {
36
36
  config,
@@ -43,7 +43,6 @@ class Experiences extends utils_1.PersonalizationAdapter {
43
43
  };
44
44
  super(Object.assign(config, conf));
45
45
  this.config = config;
46
- this.log = log;
47
46
  this.personalizeConfig = this.config.modules.personalize;
48
47
  this.experiencesDirPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.data), (0, cli_utilities_1.sanitizePath)(this.personalizeConfig.dirName), (0, cli_utilities_1.sanitizePath)(this.personalizeConfig.experiences.dirName));
49
48
  this.experiencesPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.experiencesDirPath), (0, cli_utilities_1.sanitizePath)(this.personalizeConfig.experiences.fileName));
@@ -72,6 +71,7 @@ class Experiences extends utils_1.PersonalizationAdapter {
72
71
  this.createdCTs = [];
73
72
  this.audiencesUid = utils_1.fsUtil.readFile(this.audiencesMapperPath, true) || {};
74
73
  this.eventsUid = utils_1.fsUtil.readFile(this.eventsMapperPath, true) || {};
74
+ this.config.context.module = 'experiences';
75
75
  }
76
76
  /**
77
77
  * The function asynchronously imports experiences from a JSON file and creates them in the system.
@@ -79,14 +79,17 @@ class Experiences extends utils_1.PersonalizationAdapter {
79
79
  import() {
80
80
  return __awaiter(this, void 0, void 0, function* () {
81
81
  var _a;
82
- this.log(this.config, this.$t(this.messages.IMPORT_MSG, { module: 'Experiences' }), 'info');
83
82
  yield this.init();
84
83
  yield utils_1.fsUtil.makeDirectory(this.expMapperDirPath);
84
+ cli_utilities_1.log.debug(`Created mapper directory: ${this.expMapperDirPath}`, this.config.context);
85
85
  if ((0, fs_1.existsSync)(this.experiencesPath)) {
86
+ cli_utilities_1.log.debug(`Loading experiences from: ${this.experiencesPath}`, this.config.context);
86
87
  try {
87
88
  const experiences = utils_1.fsUtil.readFile(this.experiencesPath, true);
89
+ cli_utilities_1.log.info(`Found ${experiences.length} experiences to import`, this.config.context);
88
90
  for (const experience of experiences) {
89
91
  const { uid } = experience, restExperienceData = __rest(experience, ["uid"]);
92
+ cli_utilities_1.log.debug(`Processing experience: ${uid}`, this.config.context);
90
93
  //check whether reference audience exists or not that referenced in variations having __type equal to AudienceBasedVariation & targeting
91
94
  let experienceReqObj = (0, utils_1.lookUpAudiences)(restExperienceData, this.audiencesUid);
92
95
  //check whether events exists or not that referenced in metrics
@@ -94,40 +97,43 @@ class Experiences extends utils_1.PersonalizationAdapter {
94
97
  const expRes = (yield this.createExperience(experienceReqObj));
95
98
  //map old experience uid to new experience uid
96
99
  this.experiencesUidMapper[uid] = (_a = expRes === null || expRes === void 0 ? void 0 : expRes.uid) !== null && _a !== void 0 ? _a : '';
100
+ cli_utilities_1.log.debug(`Created experience: ${uid} -> ${expRes === null || expRes === void 0 ? void 0 : expRes.uid}`, this.config.context);
97
101
  try {
98
102
  // import versions of experience
99
103
  yield this.importExperienceVersions(expRes, uid);
100
104
  }
101
105
  catch (error) {
102
- this.log(this.config, `Error while importing experience versions of ${expRes.uid}`, 'error');
103
- this.log(this.config, error, 'error');
106
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context, `Failed to import experience versions for ${expRes.uid}`);
104
107
  }
105
108
  }
106
109
  utils_1.fsUtil.writeFile(this.experiencesUidMapperPath, this.experiencesUidMapper);
107
- this.log(this.config, this.$t(this.messages.CREATE_SUCCESS, { module: 'Experiences' }), 'info');
108
- this.log(this.config, this.messages.VALIDATE_VARIANT_AND_VARIANT_GRP, 'info');
110
+ cli_utilities_1.log.success('Experiences created successfully', this.config.context);
111
+ cli_utilities_1.log.info('Validating variant and variant group creation', this.config.context);
109
112
  this.pendingVariantAndVariantGrpForExperience = (0, values_1.default)((0, cloneDeep_1.default)(this.experiencesUidMapper));
110
113
  const jobRes = yield this.validateVariantGroupAndVariantsCreated();
111
114
  utils_1.fsUtil.writeFile(this.cmsVariantPath, this.cmsVariants);
112
115
  utils_1.fsUtil.writeFile(this.cmsVariantGroupPath, this.cmsVariantGroups);
113
116
  if (jobRes) {
114
- this.log(this.config, this.$t(this.messages.CREATE_SUCCESS, { module: 'Variant & Variant groups' }), 'info');
117
+ cli_utilities_1.log.success('Variant and variant groups created successfully', this.config.context);
115
118
  }
116
119
  else {
120
+ cli_utilities_1.log.error('Failed to create variants and variant groups', this.config.context);
117
121
  this.personalizeConfig.importData = false;
118
122
  }
119
123
  if (this.personalizeConfig.importData) {
120
- this.log(this.config, this.messages.UPDATING_CT_IN_EXP, 'info');
124
+ cli_utilities_1.log.info('Attaching content types to experiences', this.config.context);
121
125
  yield this.attachCTsInExperience();
122
- this.log(this.config, this.messages.UPDATED_CT_IN_EXP, 'info');
126
+ cli_utilities_1.log.success('Content types attached to experiences successfully', this.config.context);
123
127
  }
124
128
  yield this.createVariantIdMapper();
125
129
  }
126
130
  catch (error) {
127
- this.log(this.config, this.$t(this.messages.CREATE_FAILURE, { module: 'Experiences' }), 'error');
128
- this.log(this.config, error, 'error');
131
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context);
129
132
  }
130
133
  }
134
+ else {
135
+ cli_utilities_1.log.warn(`Experiences file not found: ${this.experiencesPath}`, this.config.context);
136
+ }
131
137
  });
132
138
  }
133
139
  /**
@@ -135,11 +141,14 @@ class Experiences extends utils_1.PersonalizationAdapter {
135
141
  */
136
142
  importExperienceVersions(experience, oldExperienceUid) {
137
143
  return __awaiter(this, void 0, void 0, function* () {
144
+ cli_utilities_1.log.debug(`Importing versions for experience: ${oldExperienceUid}`, this.config.context);
138
145
  const versionsPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.experiencesDirPath), 'versions', `${(0, cli_utilities_1.sanitizePath)(oldExperienceUid)}.json`);
139
146
  if (!(0, fs_1.existsSync)(versionsPath)) {
147
+ cli_utilities_1.log.debug(`No versions file found for experience: ${oldExperienceUid}`, this.config.context);
140
148
  return;
141
149
  }
142
150
  const versions = utils_1.fsUtil.readFile(versionsPath, true);
151
+ cli_utilities_1.log.debug(`Found ${versions.length} versions for experience: ${oldExperienceUid}`, this.config.context);
143
152
  const versionMap = {
144
153
  ACTIVE: undefined,
145
154
  DRAFT: undefined,
@@ -151,6 +160,7 @@ class Experiences extends utils_1.PersonalizationAdapter {
151
160
  versionReqObj = (0, utils_1.lookUpEvents)(version, this.eventsUid);
152
161
  if (versionReqObj && versionReqObj.status) {
153
162
  versionMap[versionReqObj.status] = versionReqObj;
163
+ cli_utilities_1.log.debug(`Mapped version with status: ${versionReqObj.status}`, this.config.context);
154
164
  }
155
165
  });
156
166
  // Prioritize updating or creating versions based on the order: ACTIVE -> DRAFT -> PAUSE
@@ -160,26 +170,32 @@ class Experiences extends utils_1.PersonalizationAdapter {
160
170
  // Helper method to handle version update or creation logic
161
171
  handleVersionUpdateOrCreate(experience, versionMap) {
162
172
  return __awaiter(this, void 0, void 0, function* () {
173
+ cli_utilities_1.log.debug(`Handling version update/create for experience: ${experience.uid}`, this.config.context);
163
174
  const { ACTIVE, DRAFT, PAUSE } = versionMap;
164
175
  let latestVersionUsed = false;
165
176
  if (ACTIVE) {
177
+ cli_utilities_1.log.debug(`Updating experience version to ACTIVE for: ${experience.uid}`, this.config.context);
166
178
  yield this.updateExperienceVersion(experience.uid, experience.latestVersion, ACTIVE);
167
179
  latestVersionUsed = true;
168
180
  }
169
181
  if (DRAFT) {
170
182
  if (latestVersionUsed) {
183
+ cli_utilities_1.log.debug(`Creating new DRAFT version for: ${experience.uid}`, this.config.context);
171
184
  yield this.createExperienceVersion(experience.uid, DRAFT);
172
185
  }
173
186
  else {
187
+ cli_utilities_1.log.debug(`Updating experience version to DRAFT for: ${experience.uid}`, this.config.context);
174
188
  yield this.updateExperienceVersion(experience.uid, experience.latestVersion, DRAFT);
175
189
  latestVersionUsed = true;
176
190
  }
177
191
  }
178
192
  if (PAUSE) {
179
193
  if (latestVersionUsed) {
194
+ cli_utilities_1.log.debug(`Creating new PAUSE version for: ${experience.uid}`, this.config.context);
180
195
  yield this.createExperienceVersion(experience.uid, PAUSE);
181
196
  }
182
197
  else {
198
+ cli_utilities_1.log.debug(`Updating experience version to PAUSE for: ${experience.uid}`, this.config.context);
183
199
  yield this.updateExperienceVersion(experience.uid, experience.latestVersion, PAUSE);
184
200
  }
185
201
  }
@@ -195,88 +211,115 @@ class Experiences extends utils_1.PersonalizationAdapter {
195
211
  validateVariantGroupAndVariantsCreated() {
196
212
  return __awaiter(this, arguments, void 0, function* (retryCount = 0) {
197
213
  var _a;
214
+ cli_utilities_1.log.debug(`Validating variant groups and variants creation - attempt ${retryCount + 1}/${this.maxValidateRetry}`, this.config.context);
198
215
  try {
199
216
  const promises = this.pendingVariantAndVariantGrpForExperience.map((expUid) => __awaiter(this, void 0, void 0, function* () {
200
217
  var _a, _b, _c, _d, _e, _f, _g;
218
+ cli_utilities_1.log.debug(`Checking experience: ${expUid}`, this.config.context);
201
219
  const expRes = yield this.getExperience(expUid);
202
220
  const variants = (_b = (_a = expRes === null || expRes === void 0 ? void 0 : expRes._cms) === null || _a === void 0 ? void 0 : _a.variants) !== null && _b !== void 0 ? _b : {};
203
221
  if ((expRes === null || expRes === void 0 ? void 0 : expRes._cms) && ((_c = expRes === null || expRes === void 0 ? void 0 : expRes._cms) === null || _c === void 0 ? void 0 : _c.variantGroup) && Object.keys(variants).length > 0) {
222
+ cli_utilities_1.log.debug(`Found variants and variant group for experience: ${expUid}`, this.config.context);
204
223
  this.cmsVariants[expUid] = (_e = (_d = expRes._cms) === null || _d === void 0 ? void 0 : _d.variants) !== null && _e !== void 0 ? _e : {};
205
224
  this.cmsVariantGroups[expUid] = (_g = (_f = expRes._cms) === null || _f === void 0 ? void 0 : _f.variantGroup) !== null && _g !== void 0 ? _g : {};
206
225
  return expUid; // Return the expUid for filtering later
207
226
  }
227
+ else {
228
+ cli_utilities_1.log.debug(`Variants/variant group not ready for experience: ${expUid}`, this.config.context);
229
+ }
208
230
  }));
209
231
  yield Promise.all(promises);
210
232
  retryCount++;
211
233
  if ((_a = this.pendingVariantAndVariantGrpForExperience) === null || _a === void 0 ? void 0 : _a.length) {
212
234
  if (retryCount !== this.maxValidateRetry) {
235
+ cli_utilities_1.log.debug(`Waiting ${this.expCheckIntervalDuration}ms before retry`, this.config.context);
213
236
  yield this.delay(this.expCheckIntervalDuration);
214
237
  // Filter out the processed elements
215
238
  this.pendingVariantAndVariantGrpForExperience = this.pendingVariantAndVariantGrpForExperience.filter((uid) => !this.cmsVariants[uid]);
216
239
  return this.validateVariantGroupAndVariantsCreated(retryCount);
217
240
  }
218
241
  else {
219
- this.log(this.config, this.messages.PERSONALIZE_JOB_FAILURE, 'error');
242
+ cli_utilities_1.log.error('Personalize job failed to create variants and variant groups', this.config.context);
243
+ cli_utilities_1.log.error(`Failed experiences: ${this.pendingVariantAndVariantGrpForExperience.join(', ')}`, this.config.context);
220
244
  utils_1.fsUtil.writeFile(this.failedCmsExpPath, this.pendingVariantAndVariantGrpForExperience);
221
245
  return false;
222
246
  }
223
247
  }
224
248
  else {
249
+ cli_utilities_1.log.debug('All variant groups and variants created successfully', this.config.context);
225
250
  return true;
226
251
  }
227
252
  }
228
253
  catch (error) {
229
- this.log(this.config, `Error while validating variant group and variants creation:`, 'error');
254
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context);
230
255
  throw error;
231
256
  }
232
257
  });
233
258
  }
234
259
  attachCTsInExperience() {
235
260
  return __awaiter(this, void 0, void 0, function* () {
261
+ cli_utilities_1.log.debug('Attaching content types to experiences', this.config.context);
236
262
  try {
237
263
  // Read the created content types from the file
238
264
  this.createdCTs = utils_1.fsUtil.readFile(this.cTsSuccessPath, true);
239
265
  if (!this.createdCTs) {
240
- this.log(this.config, 'No Content types created, skipping following process', 'error');
266
+ cli_utilities_1.log.debug('No Content types created, skipping following process', this.config.context);
241
267
  return;
242
268
  }
269
+ cli_utilities_1.log.debug(`Found ${this.createdCTs.length} created content types`, this.config.context);
243
270
  const experienceCTsMap = utils_1.fsUtil.readFile(this.experienceCTsPath, true);
244
271
  return yield Promise.allSettled(Object.entries(this.experiencesUidMapper).map((_a) => __awaiter(this, [_a], void 0, function* ([oldExpUid, newExpUid]) {
245
272
  var _b;
246
273
  if ((_b = experienceCTsMap[oldExpUid]) === null || _b === void 0 ? void 0 : _b.length) {
274
+ cli_utilities_1.log.debug(`Processing content types for experience: ${oldExpUid} -> ${newExpUid}`, this.config.context);
247
275
  // Filter content types that were created
248
276
  const updatedContentTypes = experienceCTsMap[oldExpUid].filter((ct) => this.createdCTs.includes(ct === null || ct === void 0 ? void 0 : ct.uid) && ct.status === 'linked');
249
277
  if (updatedContentTypes === null || updatedContentTypes === void 0 ? void 0 : updatedContentTypes.length) {
278
+ cli_utilities_1.log.debug(`Attaching ${updatedContentTypes.length} content types to experience: ${newExpUid}`, this.config.context);
250
279
  const { variant_groups: [variantGroup] = [] } = (yield this.getVariantGroup({ experienceUid: newExpUid })) || {};
251
280
  variantGroup.content_types = updatedContentTypes;
252
281
  // Update content types detail in the new experience asynchronously
253
282
  return yield this.updateVariantGroup(variantGroup);
254
283
  }
284
+ else {
285
+ cli_utilities_1.log.debug(`No valid content types found for experience: ${newExpUid}`, this.config.context);
286
+ }
287
+ }
288
+ else {
289
+ cli_utilities_1.log.debug(`No content types mapped for experience: ${oldExpUid}`, this.config.context);
255
290
  }
256
291
  })));
257
292
  }
258
293
  catch (error) {
259
- this.log(this.config, `Error while attaching content type with experience`, 'error');
260
- this.log(this.config, error, 'error');
294
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context, 'Failed to attach content type with experience');
261
295
  }
262
296
  });
263
297
  }
264
298
  createVariantIdMapper() {
265
299
  return __awaiter(this, void 0, void 0, function* () {
266
300
  var _a;
301
+ cli_utilities_1.log.debug('Creating variant ID mapper', this.config.context);
267
302
  try {
268
303
  const experienceVariantIds = utils_1.fsUtil.readFile(this.experienceVariantsIdsPath, true) || [];
304
+ cli_utilities_1.log.debug(`Found ${experienceVariantIds.length} experience variant IDs to process`, this.config.context);
269
305
  const variantUIDMapper = {};
270
306
  for (let experienceVariantId of experienceVariantIds) {
271
307
  const [experienceId, variantShortId, oldVariantId] = experienceVariantId.split('-');
272
308
  const latestVariantId = (_a = this.cmsVariants[this.experiencesUidMapper[experienceId]]) === null || _a === void 0 ? void 0 : _a[variantShortId];
273
309
  if (latestVariantId) {
274
310
  variantUIDMapper[oldVariantId] = latestVariantId;
311
+ cli_utilities_1.log.debug(`Mapped variant ID: ${oldVariantId} -> ${latestVariantId}`, this.config.context);
312
+ }
313
+ else {
314
+ cli_utilities_1.log.warn(`Could not find variant ID mapping for: ${experienceVariantId}`, this.config.context);
275
315
  }
276
316
  }
317
+ cli_utilities_1.log.debug(`Created ${Object.keys(variantUIDMapper).length} variant ID mappings`, this.config.context);
277
318
  utils_1.fsUtil.writeFile(this.variantUidMapperFilePath, variantUIDMapper);
319
+ cli_utilities_1.log.debug(`Variant ID mapper saved to: ${this.variantUidMapperFilePath}`, this.config.context);
278
320
  }
279
321
  catch (error) {
322
+ (0, cli_utilities_1.handleAndLogError)(error, this.config.context, 'Failed to create variant ID mapper');
280
323
  throw error;
281
324
  }
282
325
  });
@@ -1,10 +1,9 @@
1
1
  import { PersonalizationAdapter } from '../utils';
2
- import { ImportConfig, LogType } from '../types';
2
+ import { ImportConfig } from '../types';
3
3
  export default class Project extends PersonalizationAdapter<ImportConfig> {
4
4
  readonly config: ImportConfig;
5
- private readonly log;
6
5
  private projectMapperFolderPath;
7
- constructor(config: ImportConfig, log?: LogType);
6
+ constructor(config: ImportConfig);
8
7
  /**
9
8
  * The function asynchronously imports projects data from a file and creates projects based on the
10
9
  * data.
@@ -14,7 +14,7 @@ const fs_1 = require("fs");
14
14
  const cli_utilities_1 = require("@contentstack/cli-utilities");
15
15
  const utils_1 = require("../utils");
16
16
  class Project extends utils_1.PersonalizationAdapter {
17
- constructor(config, log = console.log) {
17
+ constructor(config) {
18
18
  const conf = {
19
19
  config,
20
20
  baseURL: config.modules.personalize.baseURL[config.region.name],
@@ -22,8 +22,8 @@ class Project extends utils_1.PersonalizationAdapter {
22
22
  };
23
23
  super(Object.assign(config, conf));
24
24
  this.config = config;
25
- this.log = log;
26
25
  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
27
  }
28
28
  /**
29
29
  * The function asynchronously imports projects data from a file and creates projects based on the
@@ -34,16 +34,20 @@ class Project extends utils_1.PersonalizationAdapter {
34
34
  const personalize = this.config.modules.personalize;
35
35
  const { dirName, fileName } = personalize.projects;
36
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);
37
38
  if ((0, fs_1.existsSync)(projectPath)) {
38
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);
39
41
  if (!projects || projects.length < 1) {
40
42
  this.config.modules.personalize.importData = false; // Stop personalize import if stack not connected to any project
41
- this.log(this.config, 'No project found!', 'info');
43
+ cli_utilities_1.log.warn('No projects found in file', this.config.context);
42
44
  return;
43
45
  }
44
46
  yield this.init();
45
47
  for (const project of projects) {
48
+ cli_utilities_1.log.debug(`Processing project: ${project.name}`, this.config.context);
46
49
  const createProject = (newName) => __awaiter(this, void 0, void 0, function* () {
50
+ cli_utilities_1.log.debug(`Creating project with name: ${newName || project.name}`, this.config.context);
47
51
  return yield this.createProject({
48
52
  name: newName || project.name,
49
53
  description: project.description,
@@ -51,10 +55,10 @@ class Project extends utils_1.PersonalizationAdapter {
51
55
  }).catch((error) => __awaiter(this, void 0, void 0, function* () {
52
56
  if (error.includes('personalization.PROJECTS.DUPLICATE_NAME') ||
53
57
  error.includes('personalize.PROJECTS.DUPLICATE_NAME')) {
58
+ cli_utilities_1.log.warn(`Project name already exists, generating new name`, this.config.context);
54
59
  const projectName = yield (0, utils_1.askProjectName)('Copy Of ' + (newName || project.name));
55
60
  return yield createProject(projectName);
56
61
  }
57
- this.log(this.config, this.$t(this.messages.CREATE_FAILURE, { module: 'Projects' }), 'error');
58
62
  throw error;
59
63
  }));
60
64
  });
@@ -63,12 +67,13 @@ class Project extends utils_1.PersonalizationAdapter {
63
67
  this.config.modules.personalize.importData = true;
64
68
  yield utils_1.fsUtil.makeDirectory(this.projectMapperFolderPath);
65
69
  utils_1.fsUtil.writeFile((0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.projectMapperFolderPath), 'projects.json'), projectRes);
66
- this.log(this.config, `Project Created Successfully: ${projectRes.uid}`, 'info');
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);
67
72
  }
68
73
  }
69
74
  else {
70
75
  this.config.modules.personalize.importData = false; // Stop personalize import if stack not connected to any project
71
- this.log(this.config, 'No project found!', 'info');
76
+ cli_utilities_1.log.warn(`Project file not found: ${projectPath}`, this.config.context);
72
77
  }
73
78
  });
74
79
  }