@contentstack/cli-variants 1.0.0 → 1.1.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 (45) hide show
  1. package/lib/export/attributes.js +2 -1
  2. package/lib/export/audiences.js +2 -1
  3. package/lib/export/events.js +2 -1
  4. package/lib/export/experiences.js +3 -2
  5. package/lib/export/projects.js +2 -1
  6. package/lib/export/variant-entries.js +1 -1
  7. package/lib/import/attribute.js +2 -1
  8. package/lib/import/audiences.js +2 -1
  9. package/lib/import/events.js +2 -1
  10. package/lib/import/experiences.js +3 -2
  11. package/lib/import/project.js +3 -2
  12. package/lib/import/variant-entries.js +15 -9
  13. package/lib/messages/index.js +1 -1
  14. package/lib/types/personalization-api-adapter.d.ts +1 -1
  15. package/lib/types/variant-api-adapter.d.ts +3 -2
  16. package/lib/types/variant-entry.d.ts +0 -1
  17. package/lib/utils/attributes-helper.js +2 -2
  18. package/lib/utils/error-helper.js +6 -6
  19. package/lib/utils/logger.js +5 -4
  20. package/lib/utils/personalization-api-adapter.d.ts +2 -1
  21. package/lib/utils/personalization-api-adapter.js +54 -26
  22. package/lib/utils/variant-api-adapter.d.ts +5 -4
  23. package/lib/utils/variant-api-adapter.js +28 -10
  24. package/package.json +2 -2
  25. package/src/export/attributes.ts +6 -2
  26. package/src/export/audiences.ts +2 -1
  27. package/src/export/events.ts +2 -1
  28. package/src/export/experiences.ts +3 -2
  29. package/src/export/projects.ts +2 -1
  30. package/src/export/variant-entries.ts +1 -2
  31. package/src/import/attribute.ts +2 -2
  32. package/src/import/audiences.ts +2 -2
  33. package/src/import/events.ts +2 -2
  34. package/src/import/experiences.ts +3 -3
  35. package/src/import/project.ts +4 -4
  36. package/src/import/variant-entries.ts +22 -12
  37. package/src/messages/index.ts +1 -1
  38. package/src/types/personalization-api-adapter.ts +1 -1
  39. package/src/types/variant-api-adapter.ts +3 -1
  40. package/src/types/variant-entry.ts +0 -1
  41. package/src/utils/attributes-helper.ts +2 -2
  42. package/src/utils/error-helper.ts +6 -6
  43. package/src/utils/logger.ts +5 -4
  44. package/src/utils/personalization-api-adapter.ts +45 -22
  45. package/src/utils/variant-api-adapter.ts +19 -5
@@ -5,6 +5,7 @@ import { AdapterHelper } from './adapter-helper';
5
5
  export declare class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implements VariantInterface<C, HttpClient> {
6
6
  baseURL: string;
7
7
  constructor(config: APIConfig, options?: HttpClientOptions);
8
+ init(): Promise<void>;
8
9
  variantEntry(options: VariantOptions): Promise<{
9
10
  entry: {};
10
11
  }>;
@@ -48,10 +49,10 @@ export declare class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> i
48
49
  * @returns The variant API response data.
49
50
  * @throws If the API response status is not within the success range, an error message is thrown.
50
51
  */
51
- handleVariantAPIRes(res: APIResponse): VariantEntryStruct | {
52
+ handleVariantAPIRes(res: APIResponse): Promise<VariantEntryStruct | {
52
53
  entries: VariantEntryStruct[];
53
54
  count: number;
54
- } | string | any;
55
+ } | string | any>;
55
56
  }
56
57
  export declare class VariantManagementSDK<T> extends AdapterHelper<T, ContentstackClient> implements VariantInterface<T, ContentstackClient> {
57
58
  apiClient: ContentstackClient;
@@ -63,10 +64,10 @@ export declare class VariantManagementSDK<T> extends AdapterHelper<T, Contentsta
63
64
  entries: {}[];
64
65
  }>;
65
66
  createVariantEntry(input: CreateVariantEntryDto, options: CreateVariantEntryOptions, apiParams: Record<string, any>): Promise<VariantEntryStruct | string | void>;
66
- handleVariantAPIRes(res: APIResponse): VariantEntryStruct | {
67
+ handleVariantAPIRes(res: APIResponse): Promise<VariantEntryStruct | {
67
68
  entries: VariantEntryStruct[];
68
69
  count: number;
69
- } | string;
70
+ } | string>;
70
71
  constructQuery(query: Record<string, any>): string | void;
71
72
  delay(ms: number): Promise<void>;
72
73
  }
@@ -37,6 +37,18 @@ class VariantHttpClient extends adapter_helper_1.AdapterHelper {
37
37
  this.baseURL = ((_a = config.baseURL) === null || _a === void 0 ? void 0 : _a.includes('http')) ? `${config.baseURL}/v3` : `https://${config.baseURL}/v3`;
38
38
  this.apiClient.baseUrl(this.baseURL);
39
39
  }
40
+ init() {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ yield cli_utilities_1.authenticationHandler.getAuthDetails();
43
+ const token = cli_utilities_1.authenticationHandler.accessToken;
44
+ if (cli_utilities_1.authenticationHandler.isOauthEnabled) {
45
+ this.apiClient.headers({ authorization: token });
46
+ }
47
+ else {
48
+ this.apiClient.headers({ authtoken: token });
49
+ }
50
+ });
51
+ }
40
52
  variantEntry(options) {
41
53
  return __awaiter(this, void 0, void 0, function* () {
42
54
  // TODO single entry variant
@@ -99,7 +111,7 @@ class VariantHttpClient extends adapter_helper_1.AdapterHelper {
99
111
  endpoint = endpoint.concat(query);
100
112
  }
101
113
  const data = yield this.apiClient.get(endpoint);
102
- const response = this.handleVariantAPIRes(data);
114
+ const response = (yield this.handleVariantAPIRes(data));
103
115
  if (callback) {
104
116
  callback(response.entries);
105
117
  }
@@ -205,14 +217,18 @@ class VariantHttpClient extends adapter_helper_1.AdapterHelper {
205
217
  * @throws If the API response status is not within the success range, an error message is thrown.
206
218
  */
207
219
  handleVariantAPIRes(res) {
208
- const { status, data } = res;
209
- if (status >= 200 && status < 300) {
210
- return data;
211
- }
212
- const errorMsg = (data === null || data === void 0 ? void 0 : data.errors)
213
- ? (0, error_helper_1.formatErrors)(data.errors)
214
- : (data === null || data === void 0 ? void 0 : data.error_message) || (data === null || data === void 0 ? void 0 : data.message) || 'Something went wrong while processing entry variant request!';
215
- throw errorMsg;
220
+ return __awaiter(this, void 0, void 0, function* () {
221
+ const { status, data } = res;
222
+ if (status >= 200 && status < 300) {
223
+ return data;
224
+ }
225
+ // Refresh the access token if the response status is 401
226
+ yield cli_utilities_1.authenticationHandler.refreshAccessToken(res);
227
+ const errorMsg = (data === null || data === void 0 ? void 0 : data.errors)
228
+ ? (0, error_helper_1.formatErrors)(data.errors)
229
+ : (data === null || data === void 0 ? void 0 : data.error_message) || (data === null || data === void 0 ? void 0 : data.message) || 'Something went wrong while processing entry variant request!';
230
+ throw errorMsg;
231
+ });
216
232
  }
217
233
  }
218
234
  exports.VariantHttpClient = VariantHttpClient;
@@ -239,7 +255,9 @@ class VariantManagementSDK extends adapter_helper_1.AdapterHelper {
239
255
  return Promise.resolve({});
240
256
  }
241
257
  handleVariantAPIRes(res) {
242
- return res.data;
258
+ return __awaiter(this, void 0, void 0, function* () {
259
+ return res.data;
260
+ });
243
261
  }
244
262
  constructQuery(query) { }
245
263
  delay(ms) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentstack/cli-variants",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Variants plugin",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -30,7 +30,7 @@
30
30
  "typescript": "^5.4.2"
31
31
  },
32
32
  "dependencies": {
33
- "@contentstack/cli-utilities": "^1.5.12",
33
+ "@contentstack/cli-utilities": "^1.8.0",
34
34
  "lodash": "^4.17.21",
35
35
  "mkdirp": "^1.0.4",
36
36
  "winston": "^3.7.2"
@@ -14,7 +14,7 @@ export default class ExportAttributes extends PersonalizationAdapter<ExportConfi
14
14
  super({
15
15
  config: exportConfig,
16
16
  baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
17
- headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
17
+ headers: { 'X-Project-Uid': exportConfig.project_id },
18
18
  });
19
19
  this.personalizeConfig = exportConfig.modules.personalize;
20
20
  this.attributesConfig = exportConfig.modules.attributes;
@@ -30,6 +30,7 @@ export default class ExportAttributes extends PersonalizationAdapter<ExportConfi
30
30
  async start() {
31
31
  try {
32
32
  log(this.exportConfig, 'Starting attributes export', 'info');
33
+ await this.init();
33
34
  await fsUtil.makeDirectory(this.attributesFolderPath);
34
35
  this.attributes = (await this.getAttributes()) as AttributeStruct[];
35
36
 
@@ -37,7 +38,10 @@ export default class ExportAttributes extends PersonalizationAdapter<ExportConfi
37
38
  log(this.exportConfig, 'No Attributes found with the given project!', 'info');
38
39
  } else {
39
40
  this.sanitizeAttribs();
40
- fsUtil.writeFile(pResolve(sanitizePath(this.attributesFolderPath), sanitizePath(this.attributesConfig.fileName)), this.attributes);
41
+ fsUtil.writeFile(
42
+ pResolve(sanitizePath(this.attributesFolderPath), sanitizePath(this.attributesConfig.fileName)),
43
+ this.attributes,
44
+ );
41
45
  log(this.exportConfig, 'All the attributes have been exported successfully!', 'success');
42
46
  }
43
47
  } catch (error) {
@@ -14,7 +14,7 @@ export default class ExportAudiences extends PersonalizationAdapter<ExportConfig
14
14
  super({
15
15
  config: exportConfig,
16
16
  baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
17
- headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
17
+ headers: { 'X-Project-Uid': exportConfig.project_id },
18
18
  });
19
19
  this.personalizeConfig = exportConfig.modules.personalize;
20
20
  this.audiencesConfig = exportConfig.modules.audiences;
@@ -30,6 +30,7 @@ export default class ExportAudiences extends PersonalizationAdapter<ExportConfig
30
30
  async start() {
31
31
  try {
32
32
  log(this.exportConfig, 'Starting audiences export', 'info');
33
+ await this.init();
33
34
  await fsUtil.makeDirectory(this.audiencesFolderPath);
34
35
  this.audiences = (await this.getAudiences()) as AudienceStruct[];
35
36
 
@@ -14,7 +14,7 @@ export default class ExportEvents extends PersonalizationAdapter<ExportConfig> {
14
14
  super({
15
15
  config: exportConfig,
16
16
  baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
17
- headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
17
+ headers: { 'X-Project-Uid': exportConfig.project_id },
18
18
  });
19
19
  this.personalizeConfig = exportConfig.modules.personalize;
20
20
  this.eventsConfig = exportConfig.modules.events;
@@ -30,6 +30,7 @@ export default class ExportEvents extends PersonalizationAdapter<ExportConfig> {
30
30
  async start() {
31
31
  try {
32
32
  log(this.exportConfig, 'Starting events export', 'info');
33
+ await this.init();
33
34
  await fsUtil.makeDirectory(this.eventsFolderPath);
34
35
  this.events = (await this.getEvents()) as EventStruct[];
35
36
 
@@ -11,10 +11,10 @@ export default class ExportExperiences extends PersonalizationAdapter<ExportConf
11
11
  super({
12
12
  config: exportConfig,
13
13
  baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
14
- headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
14
+ headers: { 'X-Project-Uid': exportConfig.project_id },
15
15
  cmaConfig: {
16
16
  baseURL: exportConfig.region.cma + `/v3`,
17
- headers: { authtoken: exportConfig.auth_token, api_key: exportConfig.apiKey },
17
+ headers: { api_key: exportConfig.apiKey },
18
18
  },
19
19
  });
20
20
  this.exportConfig = exportConfig;
@@ -33,6 +33,7 @@ export default class ExportExperiences extends PersonalizationAdapter<ExportConf
33
33
  // loop through experiences and get content types attached to it
34
34
  // write experiences in to a file
35
35
  log(this.exportConfig, 'Starting experiences export', 'info');
36
+ await this.init();
36
37
  await fsUtil.makeDirectory(this.experiencesFolderPath);
37
38
  await fsUtil.makeDirectory(path.resolve(sanitizePath(this.experiencesFolderPath), 'versions'));
38
39
  const experiences: Array<ExperienceStruct> = (await this.getExperiences()) || [];
@@ -11,7 +11,7 @@ export default class ExportProjects extends PersonalizationAdapter<ExportConfig>
11
11
  super({
12
12
  config: exportConfig,
13
13
  baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
14
- headers: { authtoken: exportConfig.auth_token, organization_uid: exportConfig.org_uid },
14
+ headers: { organization_uid: exportConfig.org_uid },
15
15
  });
16
16
  this.exportConfig = exportConfig;
17
17
  this.personalizeConfig = exportConfig.modules.personalize;
@@ -26,6 +26,7 @@ export default class ExportProjects extends PersonalizationAdapter<ExportConfig>
26
26
  async start() {
27
27
  try {
28
28
  log(this.exportConfig, 'Starting projects export', 'info');
29
+ await this.init();
29
30
  await fsUtil.makeDirectory(this.projectFolderPath);
30
31
  const project = await this.projects({ connectedStackApiKey: this.exportConfig.apiKey });
31
32
  if (!project || project?.length < 1) {
@@ -19,7 +19,6 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Exp
19
19
  headers: {
20
20
  api_key: config.apiKey,
21
21
  branch: config.branchName,
22
- authtoken: config.auth_token,
23
22
  organization_uid: config.org_uid,
24
23
  'X-Project-Uid': config.project_id,
25
24
  },
@@ -36,7 +35,7 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Exp
36
35
  async exportVariantEntry(options: { locale: string; contentTypeUid: string; entries: Record<string, any>[] }) {
37
36
  const variantEntry = this.config.modules.variantEntry;
38
37
  const { entries, locale, contentTypeUid: content_type_uid } = options;
39
-
38
+ await this.variantInstance.init();
40
39
  for (let index = 0; index < entries.length; index++) {
41
40
  const entry = entries[index];
42
41
  const variantEntryBasePath = join(sanitizePath(this.entriesDirPath), sanitizePath(content_type_uid), sanitizePath(locale), sanitizePath(variantEntry.dirName), sanitizePath(entry.uid));
@@ -16,7 +16,7 @@ export default class Attribute extends PersonalizationAdapter<ImportConfig> {
16
16
  const conf: APIConfig = {
17
17
  config,
18
18
  baseURL: config.modules.personalize.baseURL[config.region.name],
19
- headers: { 'X-Project-Uid': config.modules.personalize.project_id, authtoken: config.auth_token },
19
+ headers: { 'X-Project-Uid': config.modules.personalize.project_id },
20
20
  };
21
21
  super(Object.assign(config, conf));
22
22
  this.personalizeConfig = this.config.modules.personalize;
@@ -36,7 +36,7 @@ export default class Attribute extends PersonalizationAdapter<ImportConfig> {
36
36
  */
37
37
  async import() {
38
38
  this.log(this.config, this.$t(this.messages.IMPORT_MSG, { module: 'Attributes' }), 'info');
39
-
39
+ await this.init();
40
40
  await fsUtil.makeDirectory(this.attrMapperDirPath);
41
41
  const { dirName, fileName } = this.attributeConfig;
42
42
  const attributesPath = resolve(
@@ -18,7 +18,7 @@ export default class Audiences extends PersonalizationAdapter<ImportConfig> {
18
18
  const conf: APIConfig = {
19
19
  config,
20
20
  baseURL: config.modules.personalize.baseURL[config.region.name],
21
- headers: { 'X-Project-Uid': config.modules.personalize.project_id, authtoken: config.auth_token },
21
+ headers: { 'X-Project-Uid': config.modules.personalize.project_id },
22
22
  };
23
23
  super(Object.assign(config, conf));
24
24
  this.personalizeConfig = this.config.modules.personalize;
@@ -44,7 +44,7 @@ export default class Audiences extends PersonalizationAdapter<ImportConfig> {
44
44
  */
45
45
  async import() {
46
46
  this.log(this.config, this.$t(this.messages.IMPORT_MSG, { module: 'Audiences' }), 'info');
47
-
47
+ await this.init();
48
48
  await fsUtil.makeDirectory(this.audienceMapperDirPath);
49
49
  const { dirName, fileName } = this.audienceConfig;
50
50
  const audiencesPath = resolve(
@@ -16,7 +16,7 @@ export default class Events extends PersonalizationAdapter<ImportConfig> {
16
16
  const conf: APIConfig = {
17
17
  config,
18
18
  baseURL: config.modules.personalize.baseURL[config.region.name],
19
- headers: { 'X-Project-Uid': config.modules.personalize.project_id, authtoken: config.auth_token },
19
+ headers: { 'X-Project-Uid': config.modules.personalize.project_id },
20
20
  };
21
21
  super(Object.assign(config, conf));
22
22
  this.personalizeConfig = this.config.modules.personalize;
@@ -36,7 +36,7 @@ export default class Events extends PersonalizationAdapter<ImportConfig> {
36
36
  */
37
37
  async import() {
38
38
  this.log(this.config, this.$t(this.messages.IMPORT_MSG, { module: 'Events' }), 'info');
39
-
39
+ await this.init();
40
40
  await fsUtil.makeDirectory(this.eventMapperDirPath);
41
41
  const { dirName, fileName } = this.eventsConfig;
42
42
  const eventsPath = resolve(
@@ -45,10 +45,10 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> {
45
45
  const conf: APIConfig = {
46
46
  config,
47
47
  baseURL: config.modules.personalize.baseURL[config.region.name],
48
- headers: { 'X-Project-Uid': config.modules.personalize.project_id, authtoken: config.auth_token },
48
+ headers: { 'X-Project-Uid': config.modules.personalize.project_id},
49
49
  cmaConfig: {
50
50
  baseURL: config.region.cma + `/v3`,
51
- headers: { authtoken: config.auth_token, api_key: config.apiKey },
51
+ headers: { api_key: config.apiKey },
52
52
  },
53
53
  };
54
54
  super(Object.assign(config, conf));
@@ -107,7 +107,7 @@ export default class Experiences extends PersonalizationAdapter<ImportConfig> {
107
107
  */
108
108
  async import() {
109
109
  this.log(this.config, this.$t(this.messages.IMPORT_MSG, { module: 'Experiences' }), 'info');
110
-
110
+ await this.init();
111
111
  await fsUtil.makeDirectory(this.expMapperDirPath);
112
112
 
113
113
  if (existsSync(this.experiencesPath)) {
@@ -10,7 +10,7 @@ export default class Project extends PersonalizationAdapter<ImportConfig> {
10
10
  const conf: APIConfig = {
11
11
  config,
12
12
  baseURL: config.modules.personalize.baseURL[config.region.name],
13
- headers: { organization_uid: config.org_uid, authtoken: config.auth_token },
13
+ headers: { organization_uid: config.org_uid },
14
14
  };
15
15
  super(Object.assign(config, conf));
16
16
  this.projectMapperFolderPath = pResolve(
@@ -29,7 +29,7 @@ export default class Project extends PersonalizationAdapter<ImportConfig> {
29
29
  const personalize = this.config.modules.personalize;
30
30
  const { dirName, fileName } = personalize.projects;
31
31
  const projectPath = join(sanitizePath(this.config.data), sanitizePath(personalize.dirName), sanitizePath(dirName), sanitizePath(fileName));
32
-
32
+
33
33
  if (existsSync(projectPath)) {
34
34
  const projects = JSON.parse(readFileSync(projectPath, 'utf8')) as CreateProjectInput[];
35
35
 
@@ -38,7 +38,7 @@ export default class Project extends PersonalizationAdapter<ImportConfig> {
38
38
  this.log(this.config, 'No project found!', 'info');
39
39
  return;
40
40
  }
41
-
41
+ await this.init();
42
42
  for (const project of projects) {
43
43
  const createProject = async (newName: void | string): Promise<ProjectStruct> => {
44
44
  return await this.createProject({
@@ -46,7 +46,7 @@ export default class Project extends PersonalizationAdapter<ImportConfig> {
46
46
  description: project.description,
47
47
  connectedStackApiKey: this.config.apiKey,
48
48
  }).catch(async (error) => {
49
- if (error === 'personalization.PROJECTS.DUPLICATE_NAME' || error === 'personalize.PROJECTS.DUPLICATE_NAME') {
49
+ if (error.includes('personalization.PROJECTS.DUPLICATE_NAME') || error.includes('personalize.PROJECTS.DUPLICATE_NAME')) {
50
50
  const projectName = await askProjectName('Copy Of ' + (newName || project.name));
51
51
  return await createProject(projectName);
52
52
  }
@@ -49,7 +49,6 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
49
49
  headers: {
50
50
  api_key: config.apiKey,
51
51
  branch: config.branchName,
52
- authtoken: config.auth_token,
53
52
  organization_uid: config.org_uid,
54
53
  'X-Project-Uid': config.modules.personalize.project_id,
55
54
  },
@@ -138,7 +137,8 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
138
137
  this.assetUidMapper = (fsUtil.readFile(assetUidMapperPath, true) || {}) as Record<string, any>;
139
138
  this.assetUrlMapper = (fsUtil.readFile(assetUrlMapperPath, true) || {}) as Record<string, any>;
140
139
  this.environments = (fsUtil.readFile(envPath, true) || {}) as Record<string, any>;
141
-
140
+ // set the token
141
+ await this.variantInstance.init();
142
142
  for (const entriesForVariant of entriesForVariants) {
143
143
  await this.importVariantEntries(entriesForVariant);
144
144
  }
@@ -368,7 +368,7 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
368
368
  * @param variantEntry - The entry variant to update.
369
369
  */
370
370
  updateFileFields(variantEntry: VariantEntryStruct) {
371
- const setValue = (currentObj: VariantEntryStruct, keys: Array<string>) => {
371
+ const setValue = (currentObj: VariantEntryStruct, keys: string[]) => {
372
372
  if (!currentObj || keys.length === 0) return;
373
373
 
374
374
  const [firstKey, ...restKeys] = keys;
@@ -380,7 +380,14 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
380
380
  } else if (currentObj && typeof currentObj === 'object') {
381
381
  if (firstKey in currentObj) {
382
382
  if (keys.length === 1) {
383
- currentObj[firstKey] = { uid: currentObj[firstKey], filename: 'dummy.jpeg' };
383
+ // Check if the current property is already an object with uid and filename
384
+ const existingValue = currentObj[firstKey];
385
+
386
+ if (existingValue && typeof existingValue === 'object' && existingValue.uid) {
387
+ currentObj[firstKey] = { uid: existingValue.uid, filename: 'dummy.jpeg' };
388
+ } else {
389
+ currentObj[firstKey] = { uid: currentObj[firstKey], filename: 'dummy.jpeg' };
390
+ }
384
391
  } else {
385
392
  setValue(currentObj[firstKey], restKeys);
386
393
  }
@@ -388,13 +395,12 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
388
395
  }
389
396
  };
390
397
 
391
- const pathsToUpdate = variantEntry?._metadata?.references
392
- .filter((ref: any) => ref._content_type_uid === 'sys_assets')
393
- .map((ref: any) => ref.path);
398
+ const pathsToUpdate =
399
+ variantEntry?._metadata?.references
400
+ ?.filter((ref: any) => ref._content_type_uid === 'sys_assets')
401
+ .map((ref: any) => ref.path) || [];
394
402
 
395
- if (pathsToUpdate) {
396
- pathsToUpdate.forEach((path: string) => setValue(variantEntry, path.split('.')));
397
- }
403
+ pathsToUpdate.forEach((path: string) => setValue(variantEntry, path.split('.')));
398
404
  }
399
405
 
400
406
  /**
@@ -406,6 +412,11 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
406
412
  */
407
413
  async publishVariantEntries(batch: VariantEntryStruct[], entryUid: string, content_type: string) {
408
414
  const allPromise = [];
415
+ log(
416
+ this.config,
417
+ `Publishing variant entries for entry uid '${entryUid}' of Content Type '${content_type}'`,
418
+ 'info',
419
+ );
409
420
  for (let [, variantEntry] of entries(batch)) {
410
421
  const variantEntryUID = variantEntry.uid;
411
422
  const oldVariantUid = variantEntry._variant._uid || '';
@@ -446,11 +457,9 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
446
457
  entry: {
447
458
  environments,
448
459
  locales,
449
- publish_with_base_entry: false,
450
460
  variants: [{ uid: newVariantUid, version: 1 }],
451
461
  },
452
462
  locale: variantEntry.locale,
453
- version: 1,
454
463
  };
455
464
 
456
465
  const promise = this.variantInstance.publishVariantEntry(
@@ -470,6 +479,7 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
470
479
  allPromise.push(promise);
471
480
  }
472
481
  await Promise.allSettled(allPromise);
482
+ log(this.config, `Published variant entries for entry uid '${entryUid}' of Content Type '${content_type}'`, 'info');
473
483
  }
474
484
 
475
485
  /**
@@ -23,7 +23,7 @@ const expImportMsg = {
23
23
  UPDATING_CT_IN_EXP: 'Updating content types in experiences...',
24
24
  UPDATED_CT_IN_EXP: 'Successfully updated content types in experiences!',
25
25
  VALIDATE_VARIANT_AND_VARIANT_GRP: 'Validating variant group and variants creation...',
26
- PERSONALIZE_JOB_FAILURE: 'Something went wrong with personalize background job! Failed to fetch some variant & variant groups',
26
+ PERSONALIZE_JOB_FAILURE: 'Something went wrong! Failed to fetch some variant and variant groups.',
27
27
  };
28
28
 
29
29
  const messages: typeof errors & typeof commonMsg & typeof migrationMsg & typeof variantEntry & typeof expImportMsg = {
@@ -206,5 +206,5 @@ export interface Personalization<T> extends AdapterHelperInterface<T, HttpClient
206
206
 
207
207
  updateCTsInExperience(experience: UpdateExperienceInput, experienceUid: string): Promise<CMSExperienceStruct | void>;
208
208
 
209
- handleVariantAPIRes(res: any): VariantAPIRes;
209
+ handleVariantAPIRes(res: any): Promise<VariantAPIRes>;
210
210
  }
@@ -42,6 +42,8 @@ export type VariantOptions = VariantsOption & {
42
42
  };
43
43
 
44
44
  export interface VariantInterface<T, ApiClient> extends AdapterHelperInterface<T, ApiClient> {
45
+ init(): Promise<void>;
46
+
45
47
  variantEntry(options: VariantOptions): Promise<{ entry: Record<string, any> }>;
46
48
 
47
49
  variantEntries(options: VariantsOption): Promise<{ entries?: Record<string, any>[] | unknown[] } | void>;
@@ -52,5 +54,5 @@ export interface VariantInterface<T, ApiClient> extends AdapterHelperInterface<T
52
54
  apiParams: Record<string, any>,
53
55
  ): Promise<VariantEntryStruct | string | void>;
54
56
 
55
- handleVariantAPIRes(res: APIResponse): VariantEntryStruct | { entries: VariantEntryStruct[]; count: number } | string;
57
+ handleVariantAPIRes(res: APIResponse): Promise<VariantEntryStruct | { entries: VariantEntryStruct[]; count: number } | string>;
56
58
  }
@@ -50,7 +50,6 @@ export type PublishVariantEntryDto = {
50
50
  entry: {
51
51
  environments: string[];
52
52
  locales: string[];
53
- publish_with_base_entry: boolean;
54
53
  variants: {
55
54
  uid: string;
56
55
  version?: number;
@@ -12,8 +12,8 @@ export const lookUpAttributes = (attributeRules: Record<string, any>[], attribut
12
12
  // Check if attribute reference exists in attributesUid
13
13
  const attributeRef = rule.attribute?.ref;
14
14
  const attributeType = rule.attribute['__type'];
15
- // check if type is UserAttributeReference
16
- if (attributeType === 'UserAttributeReference') {
15
+ // check if type is CustomAttributeReference
16
+ if (attributeType === 'CustomAttributeReference') {
17
17
  if (attributeRef && attributesUid.hasOwnProperty(attributeRef) && attributesUid[attributeRef]) {
18
18
  rule.attribute.ref = attributesUid[attributeRef];
19
19
  } else {
@@ -9,18 +9,18 @@ export function formatErrors(errors: any): string {
9
9
  for (const errorKey in errors) {
10
10
  const errorValue = errors[errorKey];
11
11
  if (Array.isArray(errorValue)) {
12
- errorMessages.push(...errorValue.map((error: any) => formatError(error)));
12
+ errorMessages.push(...errorValue.map((error: any) => formatError(errorKey, error)));
13
13
  } else {
14
- errorMessages.push(formatError(errorValue));
14
+ errorMessages.push(formatError(errorKey, errorValue));
15
15
  }
16
16
  }
17
17
 
18
18
  return errorMessages.join(' ');
19
19
  }
20
20
 
21
- function formatError(error: any): string {
22
- if (typeof error === 'object') {
23
- return Object.values(error).join(' ');
21
+ function formatError(errorKey: string, error: any): string {
22
+ if (typeof error === 'object' && error !== null) {
23
+ return `${errorKey}: ${Object.values(error).join(' ')}`;
24
24
  }
25
- return error;
25
+ return `${errorKey}: ${error}`;
26
26
  }
@@ -51,9 +51,9 @@ let errorLogger: winston.Logger;
51
51
  let successTransport;
52
52
  let errorTransport;
53
53
 
54
- function init(_logPath: string) {
54
+ function init(_logPath: string, module: string) {
55
55
  if (!logger || !errorLogger) {
56
- const logsDir = path.resolve(sanitizePath(_logPath), 'logs', 'export');
56
+ const logsDir = path.resolve(sanitizePath(_logPath), 'logs', sanitizePath(module));
57
57
  // Create dir if doesn't already exist
58
58
  mkdirp.sync(logsDir);
59
59
 
@@ -131,11 +131,12 @@ function init(_logPath: string) {
131
131
  export const log = (config: ExportConfig | ImportConfig, message: any, type: 'info' | 'error' | 'success') => {
132
132
  const logsPath = config.data;
133
133
  // ignoring the type argument, as we are not using it to create a logfile anymore
134
+ const module = (config as ImportConfig)['backupDir'] ? 'import' : 'export';
134
135
  if (type !== 'error') {
135
136
  // removed type argument from init method
136
- init(logsPath).log(message);
137
+ init(logsPath, module).log(message);
137
138
  } else {
138
- init(logsPath).error(message);
139
+ init(logsPath, module).error(message);
139
140
  }
140
141
  };
141
142