@contentstack/cli-variants 0.0.1-alpha → 1.0.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 (53) hide show
  1. package/lib/export/attributes.d.ts +2 -2
  2. package/lib/export/attributes.js +3 -3
  3. package/lib/export/audiences.d.ts +2 -2
  4. package/lib/export/audiences.js +3 -3
  5. package/lib/export/events.d.ts +2 -2
  6. package/lib/export/events.js +3 -3
  7. package/lib/export/experiences.d.ts +2 -2
  8. package/lib/export/experiences.js +17 -3
  9. package/lib/export/projects.d.ts +2 -2
  10. package/lib/export/projects.js +7 -5
  11. package/lib/import/attribute.d.ts +1 -1
  12. package/lib/import/attribute.js +20 -10
  13. package/lib/import/audiences.d.ts +2 -2
  14. package/lib/import/audiences.js +20 -14
  15. package/lib/import/events.d.ts +1 -1
  16. package/lib/import/events.js +14 -8
  17. package/lib/import/experiences.d.ts +12 -5
  18. package/lib/import/experiences.js +84 -20
  19. package/lib/import/project.js +10 -10
  20. package/lib/import/variant-entries.d.ts +1 -1
  21. package/lib/import/variant-entries.js +13 -13
  22. package/lib/messages/index.d.ts +1 -1
  23. package/lib/messages/index.js +3 -2
  24. package/lib/types/export-config.d.ts +3 -3
  25. package/lib/types/import-config.d.ts +1 -1
  26. package/lib/types/personalization-api-adapter.d.ts +13 -0
  27. package/lib/types/variant-entry.d.ts +2 -2
  28. package/lib/utils/audiences-helper.js +14 -3
  29. package/lib/utils/error-helper.js +1 -1
  30. package/lib/utils/personalization-api-adapter.d.ts +4 -1
  31. package/lib/utils/personalization-api-adapter.js +40 -1
  32. package/lib/utils/variant-api-adapter.js +1 -0
  33. package/package.json +1 -1
  34. package/src/export/attributes.ts +5 -5
  35. package/src/export/audiences.ts +5 -5
  36. package/src/export/events.ts +5 -5
  37. package/src/export/experiences.ts +21 -5
  38. package/src/export/projects.ts +9 -7
  39. package/src/import/attribute.ts +30 -12
  40. package/src/import/audiences.ts +36 -18
  41. package/src/import/events.ts +24 -10
  42. package/src/import/experiences.ts +118 -28
  43. package/src/import/project.ts +10 -10
  44. package/src/import/variant-entries.ts +48 -25
  45. package/src/messages/index.ts +3 -2
  46. package/src/types/export-config.ts +3 -3
  47. package/src/types/import-config.ts +1 -1
  48. package/src/types/personalization-api-adapter.ts +13 -0
  49. package/src/types/variant-entry.ts +2 -2
  50. package/src/utils/audiences-helper.ts +12 -2
  51. package/src/utils/error-helper.ts +1 -1
  52. package/src/utils/personalization-api-adapter.ts +32 -2
  53. package/src/utils/variant-api-adapter.ts +2 -2
@@ -17,13 +17,13 @@ class Project extends utils_1.PersonalizationAdapter {
17
17
  constructor(config, log = console.log) {
18
18
  const conf = {
19
19
  config,
20
- baseURL: config.modules.personalization.baseURL[config.region.name],
20
+ baseURL: config.modules.personalize.baseURL[config.region.name],
21
21
  headers: { organization_uid: config.org_uid, authtoken: config.auth_token },
22
22
  };
23
23
  super(Object.assign(config, conf));
24
24
  this.config = config;
25
25
  this.log = log;
26
- this.projectMapperFolderPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', (0, cli_utilities_1.sanitizePath)(this.config.modules.personalization.dirName), 'projects');
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');
27
27
  }
28
28
  /**
29
29
  * The function asynchronously imports projects data from a file and creates projects based on the
@@ -31,13 +31,13 @@ class Project extends utils_1.PersonalizationAdapter {
31
31
  */
32
32
  import() {
33
33
  return __awaiter(this, void 0, void 0, function* () {
34
- const personalization = this.config.modules.personalization;
35
- const { dirName, fileName } = personalization.projects;
36
- const projectPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.data), (0, cli_utilities_1.sanitizePath)(personalization.dirName), (0, cli_utilities_1.sanitizePath)(dirName), (0, cli_utilities_1.sanitizePath)(fileName));
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
37
  if ((0, fs_1.existsSync)(projectPath)) {
38
38
  const projects = JSON.parse((0, fs_1.readFileSync)(projectPath, 'utf8'));
39
39
  if (!projects || projects.length < 1) {
40
- this.config.modules.personalization.importData = false; // Stop personalization import if stack not connected to any project
40
+ this.config.modules.personalize.importData = false; // Stop personalize import if stack not connected to any project
41
41
  this.log(this.config, 'No project found!', 'info');
42
42
  return;
43
43
  }
@@ -48,7 +48,7 @@ class Project extends utils_1.PersonalizationAdapter {
48
48
  description: project.description,
49
49
  connectedStackApiKey: this.config.apiKey,
50
50
  }).catch((error) => __awaiter(this, void 0, void 0, function* () {
51
- if (error === 'personalization.PROJECTS.DUPLICATE_NAME') {
51
+ if (error === 'personalization.PROJECTS.DUPLICATE_NAME' || error === 'personalize.PROJECTS.DUPLICATE_NAME') {
52
52
  const projectName = yield (0, utils_1.askProjectName)('Copy Of ' + (newName || project.name));
53
53
  return yield createProject(projectName);
54
54
  }
@@ -57,15 +57,15 @@ class Project extends utils_1.PersonalizationAdapter {
57
57
  }));
58
58
  });
59
59
  const projectRes = yield createProject(this.config.personalizeProjectName);
60
- this.config.modules.personalization.project_id = projectRes.uid;
61
- this.config.modules.personalization.importData = true;
60
+ this.config.modules.personalize.project_id = projectRes.uid;
61
+ this.config.modules.personalize.importData = true;
62
62
  yield utils_1.fsUtil.makeDirectory(this.projectMapperFolderPath);
63
63
  utils_1.fsUtil.writeFile((0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.projectMapperFolderPath), 'projects.json'), projectRes);
64
64
  this.log(this.config, `Project Created Successfully: ${projectRes.uid}`, 'info');
65
65
  }
66
66
  }
67
67
  else {
68
- this.config.modules.personalization.importData = false; // Stop personalization import if stack not connected to any project
68
+ this.config.modules.personalize.importData = false; // Stop personalize import if stack not connected to any project
69
69
  this.log(this.config, 'No project found!', 'info');
70
70
  }
71
71
  });
@@ -8,7 +8,7 @@ export default class VariantEntries extends VariantAdapter<VariantHttpClient<Imp
8
8
  entriesMapperPath: string;
9
9
  variantEntryBasePath: string;
10
10
  variantIdList: Record<string, unknown>;
11
- personalizationConfig: ImportConfig['modules']['personalization'];
11
+ personalizeConfig: ImportConfig['modules']['personalize'];
12
12
  taxonomies: Record<string, unknown>;
13
13
  assetUrlMapper: Record<string, any>;
14
14
  assetUidMapper: Record<string, any>;
@@ -58,13 +58,13 @@ class VariantEntries extends variant_api_adapter_1.default {
58
58
  branch: config.branchName,
59
59
  authtoken: config.auth_token,
60
60
  organization_uid: config.org_uid,
61
- 'X-Project-Uid': config.modules.personalization.project_id,
61
+ 'X-Project-Uid': config.modules.personalize.project_id,
62
62
  },
63
63
  };
64
64
  super(Object.assign((0, omit_1.default)(config, ['helpers']), conf));
65
65
  this.config = config;
66
66
  this.entriesMapperPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(config.backupDir), (0, cli_utilities_1.sanitizePath)(config.branchName || ''), 'mapper', 'entries');
67
- this.personalizationConfig = this.config.modules.personalization;
67
+ this.personalizeConfig = this.config.modules.personalize;
68
68
  this.entriesDirPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(config.backupDir), (0, cli_utilities_1.sanitizePath)(config.branchName || ''), (0, cli_utilities_1.sanitizePath)(config.modules.entries.dirName));
69
69
  this.failedVariantPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'failed-entry-variants.json');
70
70
  this.failedVariantEntries = new Map();
@@ -80,7 +80,7 @@ class VariantEntries extends variant_api_adapter_1.default {
80
80
  import() {
81
81
  return __awaiter(this, void 0, void 0, function* () {
82
82
  const filePath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.entriesMapperPath), 'data-for-variant-entry.json');
83
- const variantIdPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', (0, cli_utilities_1.sanitizePath)(this.personalizationConfig.dirName), (0, cli_utilities_1.sanitizePath)(this.personalizationConfig.experiences.dirName), 'variants-uid-mapping.json');
83
+ 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');
84
84
  if (!(0, fs_1.existsSync)(filePath)) {
85
85
  (0, utils_1.log)(this.config, this.messages.IMPORT_ENTRY_NOT_FOUND, 'info');
86
86
  return;
@@ -184,21 +184,21 @@ class VariantEntries extends variant_api_adapter_1.default {
184
184
  log(this.config, error, 'error');
185
185
  };
186
186
  // NOTE Find new variant Id by old Id
187
- const variant_id = this.variantIdList[variantEntry.variant_id];
187
+ const variantId = this.variantIdList[variantEntry._variant._uid];
188
188
  // NOTE Replace all the relation data UID's
189
189
  variantEntry = this.handleVariantEntryRelationalData(contentType, variantEntry);
190
190
  const changeSet = this.serializeChangeSet(variantEntry);
191
191
  const createVariantReq = Object.assign({ _variant: variantEntry._variant }, changeSet);
192
- if (variant_id) {
192
+ if (variantId) {
193
193
  const promise = this.variantInstance.createVariantEntry(createVariantReq, {
194
194
  locale,
195
195
  entry_uid: entryUid,
196
- variant_id,
196
+ variant_id: variantId,
197
197
  content_type_uid: content_type,
198
198
  }, {
199
199
  reject: onReject.bind(this),
200
200
  resolve: onSuccess.bind(this),
201
- variantUid: variantEntry.uid,
201
+ variantUid: variantId,
202
202
  log: utils_1.log,
203
203
  });
204
204
  allPromise.push(promise);
@@ -329,15 +329,15 @@ class VariantEntries extends variant_api_adapter_1.default {
329
329
  var _a;
330
330
  const allPromise = [];
331
331
  for (let [, variantEntry] of (0, entries_1.default)(batch)) {
332
- const variantUid = variantEntry.uid;
333
- const oldVariantUid = variantEntry.variant_id || '';
332
+ const variantEntryUID = variantEntry.uid;
333
+ const oldVariantUid = variantEntry._variant._uid || '';
334
334
  const newVariantUid = this.variantIdList[oldVariantUid];
335
335
  if (!newVariantUid) {
336
- (0, utils_1.log)(this.config, `${this.messages.VARIANT_ID_NOT_FOUND}. Skipping entry variant publish for ${variantUid}`, 'info');
336
+ (0, utils_1.log)(this.config, `${this.messages.VARIANT_ID_NOT_FOUND}. Skipping entry variant publish`, 'info');
337
337
  continue;
338
338
  }
339
- if (this.failedVariantEntries.has(variantUid)) {
340
- (0, utils_1.log)(this.config, `${this.messages.VARIANT_UID_NOT_FOUND}. Skipping entry variant publish for ${variantUid}`, 'info');
339
+ if (this.failedVariantEntries.has(variantEntryUID)) {
340
+ (0, utils_1.log)(this.config, `${this.messages.VARIANT_UID_NOT_FOUND}. Skipping entry variant publish for ${variantEntryUID}`, 'info');
341
341
  continue;
342
342
  }
343
343
  if ((_a = this.environments) === null || _a === void 0 ? void 0 : _a.length) {
@@ -372,7 +372,7 @@ class VariantEntries extends variant_api_adapter_1.default {
372
372
  reject: onReject.bind(this),
373
373
  resolve: onSuccess.bind(this),
374
374
  log: utils_1.log,
375
- variantUid,
375
+ variantUid: newVariantUid,
376
376
  });
377
377
  allPromise.push(promise);
378
378
  }
@@ -17,7 +17,7 @@ declare const expImportMsg: {
17
17
  UPDATING_CT_IN_EXP: string;
18
18
  UPDATED_CT_IN_EXP: string;
19
19
  VALIDATE_VARIANT_AND_VARIANT_GRP: string;
20
- PERSONALIZATION_JOB_FAILURE: string;
20
+ PERSONALIZE_JOB_FAILURE: string;
21
21
  };
22
22
  declare const messages: typeof errors & typeof commonMsg & typeof migrationMsg & typeof variantEntry & typeof expImportMsg;
23
23
  /**
@@ -27,7 +27,7 @@ const expImportMsg = {
27
27
  UPDATING_CT_IN_EXP: 'Updating content types in experiences...',
28
28
  UPDATED_CT_IN_EXP: 'Successfully updated content types in experiences!',
29
29
  VALIDATE_VARIANT_AND_VARIANT_GRP: 'Validating variant group and variants creation...',
30
- PERSONALIZATION_JOB_FAILURE: 'Something went wrong with personalization background job! Failed to fetch some variant & variant groups',
30
+ PERSONALIZE_JOB_FAILURE: 'Something went wrong with personalize background job! Failed to fetch some variant & variant groups',
31
31
  };
32
32
  const messages = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, errors), commonMsg), migrationMsg), variantEntry), expImportMsg);
33
33
  /**
@@ -46,7 +46,8 @@ function $t(msg, args) {
46
46
  return '';
47
47
  for (const key of Object.keys(args)) {
48
48
  const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
49
- msg = msg.replace(new RegExp(`{${escapedKey}}`, 'g'), args[key] || escapedKey);
49
+ const placeholder = `{${escapedKey}}`;
50
+ msg = msg.split(placeholder).join(args[key]);
50
51
  }
51
52
  return msg;
52
53
  });
@@ -4,7 +4,7 @@
4
4
  * Therefore, we are duplicating the following types from the export.
5
5
  */
6
6
  import { AnyProperty } from './utils';
7
- export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies' | 'personalization';
7
+ export type Modules = 'stack' | 'assets' | 'locales' | 'environments' | 'extensions' | 'webhooks' | 'global-fields' | 'entries' | 'content-types' | 'custom-roles' | 'workflows' | 'labels' | 'marketplace-apps' | 'taxonomies' | 'personalize';
8
8
  export type branch = {
9
9
  uid: string;
10
10
  source: string;
@@ -131,7 +131,7 @@ export interface DefaultConfig {
131
131
  include_publish_details: boolean;
132
132
  } & AnyProperty;
133
133
  } & AnyProperty;
134
- personalization: {
134
+ personalize: {
135
135
  dirName: string;
136
136
  baseURL: Record<string, string>;
137
137
  } & AnyProperty;
@@ -243,7 +243,7 @@ export interface ExportConfig extends DefaultConfig {
243
243
  personalizationHost?: string;
244
244
  region: any;
245
245
  }
246
- export interface PersonalizationConfig {
246
+ export interface PersonalizeConfig {
247
247
  dirName: string;
248
248
  baseURL: Record<string, string>;
249
249
  }
@@ -11,7 +11,7 @@ export interface ImportDefaultConfig extends AnyProperty {
11
11
  dirName: string;
12
12
  fileName: string;
13
13
  };
14
- personalization: {
14
+ personalize: {
15
15
  baseURL: Record<string, string>;
16
16
  dirName: string;
17
17
  importData: boolean;
@@ -112,6 +112,18 @@ export type ExperienceStruct = {
112
112
  };
113
113
  content_types?: string[];
114
114
  } & AnyProperty;
115
+ export interface CreateExperienceVersionInput {
116
+ name: string;
117
+ __type: string;
118
+ description: string;
119
+ targeting?: ExpTargeting;
120
+ variations: ExpVariations[];
121
+ variationSplit?: string;
122
+ metrics?: ExpMetric[];
123
+ status: string;
124
+ metadata?: object;
125
+ variants: Array<ExpVariations>;
126
+ }
115
127
  export interface CreateExperienceInput {
116
128
  name: string;
117
129
  __type: string;
@@ -122,6 +134,7 @@ export interface CreateExperienceInput {
122
134
  metrics?: ExpMetric[];
123
135
  status: string;
124
136
  metadata?: object;
137
+ variants?: Array<ExpVariations>;
125
138
  }
126
139
  export interface UpdateExperienceInput {
127
140
  contentTypes: string[];
@@ -2,11 +2,11 @@ import { AnyProperty } from './utils';
2
2
  export type VariantEntryStruct = {
3
3
  uid: string;
4
4
  title: string;
5
- variant_id: string;
6
5
  locale: string;
7
6
  _version: number;
8
7
  _variant: {
9
- uid: string;
8
+ _uid: string;
9
+ _instance_uid: string;
10
10
  _change_set: string[];
11
11
  _base_entry_version: number;
12
12
  };
@@ -24,7 +24,7 @@ function updateAudiences(audiences, audiencesUid) {
24
24
  * @returns
25
25
  */
26
26
  const lookUpAudiences = (experience, audiencesUid) => {
27
- var _a, _b, _c, _d, _e, _f;
27
+ var _a, _b, _c, _d, _e, _f, _g;
28
28
  // Update experience variations
29
29
  if ((_a = experience === null || experience === void 0 ? void 0 : experience.variations) === null || _a === void 0 ? void 0 : _a.length) {
30
30
  for (let index = experience.variations.length - 1; index >= 0; index--) {
@@ -37,8 +37,19 @@ const lookUpAudiences = (experience, audiencesUid) => {
37
37
  }
38
38
  }
39
39
  }
40
- // Update targeting audiences
41
- if (((_c = experience === null || experience === void 0 ? void 0 : experience.targeting) === null || _c === void 0 ? void 0 : _c.hasOwnProperty('audience')) && ((_f = (_e = (_d = experience === null || experience === void 0 ? void 0 : experience.targeting) === null || _d === void 0 ? void 0 : _d.audience) === null || _e === void 0 ? void 0 : _e.audiences) === null || _f === void 0 ? void 0 : _f.length)) {
40
+ else if (experience.variants) {
41
+ for (let index = experience.variants.length - 1; index >= 0; index--) {
42
+ const expVariations = experience.variants[index];
43
+ if (expVariations['__type'] === 'SegmentedVariant' && ((_c = expVariations === null || expVariations === void 0 ? void 0 : expVariations.audiences) === null || _c === void 0 ? void 0 : _c.length)) {
44
+ updateAudiences(expVariations.audiences, audiencesUid);
45
+ if (!expVariations.audiences.length) {
46
+ experience.variants.splice(index, 1);
47
+ }
48
+ }
49
+ }
50
+ }
51
+ if (((_d = experience === null || experience === void 0 ? void 0 : experience.targeting) === null || _d === void 0 ? void 0 : _d.hasOwnProperty('audience')) && ((_g = (_f = (_e = experience === null || experience === void 0 ? void 0 : experience.targeting) === null || _e === void 0 ? void 0 : _e.audience) === null || _f === void 0 ? void 0 : _f.audiences) === null || _g === void 0 ? void 0 : _g.length)) {
52
+ // Update targeting audiences
42
53
  updateAudiences(experience.targeting.audience.audiences, audiencesUid);
43
54
  if (!experience.targeting.audience.audiences.length) {
44
55
  experience.targeting = {};
@@ -23,5 +23,5 @@ function formatError(error) {
23
23
  if (typeof error === 'object') {
24
24
  return Object.values(error).join(' ');
25
25
  }
26
- return String(error);
26
+ return error;
27
27
  }
@@ -1,6 +1,6 @@
1
1
  import { AdapterHelper } from './adapter-helper';
2
2
  import { HttpClient } from '@contentstack/cli-utilities';
3
- import { ProjectStruct, Personalization, GetProjectsParams, CreateProjectInput, CreateAttributeInput, APIConfig, GetVariantGroupInput, EventStruct, AudienceStruct, AttributeStruct, CreateAudienceInput, CreateEventInput, CreateExperienceInput, ExperienceStruct, UpdateExperienceInput, CMSExperienceStruct, VariantAPIRes, APIResponse, VariantGroupStruct, VariantGroup } from '../types';
3
+ import { ProjectStruct, Personalization, GetProjectsParams, CreateProjectInput, CreateAttributeInput, APIConfig, GetVariantGroupInput, EventStruct, AudienceStruct, AttributeStruct, CreateAudienceInput, CreateEventInput, CreateExperienceInput, ExperienceStruct, UpdateExperienceInput, CMSExperienceStruct, VariantAPIRes, APIResponse, VariantGroupStruct, VariantGroup, CreateExperienceVersionInput } from '../types';
4
4
  export declare class PersonalizationAdapter<T> extends AdapterHelper<T, HttpClient> implements Personalization<T> {
5
5
  constructor(options: APIConfig);
6
6
  projects(options: GetProjectsParams): Promise<ProjectStruct[]>;
@@ -27,6 +27,9 @@ export declare class PersonalizationAdapter<T> extends AdapterHelper<T, HttpClie
27
27
  createAttribute(attribute: CreateAttributeInput): Promise<AttributeStruct>;
28
28
  getExperiences(): Promise<ExperienceStruct[]>;
29
29
  getExperience(experienceUid: string): Promise<ExperienceStruct | void>;
30
+ getExperienceVersions(experienceUid: string): Promise<ExperienceStruct | void>;
31
+ createExperienceVersion(experienceUid: string, input: CreateExperienceVersionInput): Promise<ExperienceStruct | void>;
32
+ updateExperienceVersion(experienceUid: string, versionId: string, input: CreateExperienceVersionInput): Promise<ExperienceStruct | void>;
30
33
  getVariantGroup(input: GetVariantGroupInput): Promise<VariantGroupStruct | void>;
31
34
  updateVariantGroup(input: VariantGroup): Promise<VariantGroup | void>;
32
35
  getEvents(): Promise<EventStruct[] | void>;
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
11
22
  Object.defineProperty(exports, "__esModule", { value: true });
12
23
  exports.PersonalizationAdapter = void 0;
13
24
  const adapter_helper_1 = require("./adapter-helper");
@@ -68,6 +79,34 @@ class PersonalizationAdapter extends adapter_helper_1.AdapterHelper {
68
79
  return this.handleVariantAPIRes(data);
69
80
  });
70
81
  }
82
+ getExperienceVersions(experienceUid) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ const getExperiencesVersionsEndPoint = `/experiences/${experienceUid}/versions`;
85
+ const data = yield this.apiClient.get(getExperiencesVersionsEndPoint);
86
+ return this.handleVariantAPIRes(data);
87
+ });
88
+ }
89
+ createExperienceVersion(experienceUid, input) {
90
+ return __awaiter(this, void 0, void 0, function* () {
91
+ const createExperiencesVersionsEndPoint = `/experiences/${experienceUid}/versions`;
92
+ const data = yield this.apiClient.post(createExperiencesVersionsEndPoint, input);
93
+ return this.handleVariantAPIRes(data);
94
+ });
95
+ }
96
+ updateExperienceVersion(experienceUid, versionId, input) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ // loop through input and remove shortId from variant
99
+ if (input === null || input === void 0 ? void 0 : input.variants) {
100
+ input.variants = input.variants.map((_a) => {
101
+ var { shortUid } = _a, rest = __rest(_a, ["shortUid"]);
102
+ return rest;
103
+ });
104
+ }
105
+ const updateExperiencesVersionsEndPoint = `/experiences/${experienceUid}/versions/${versionId}`;
106
+ const data = yield this.apiClient.put(updateExperiencesVersionsEndPoint, input);
107
+ return this.handleVariantAPIRes(data);
108
+ });
109
+ }
71
110
  getVariantGroup(input) {
72
111
  return __awaiter(this, void 0, void 0, function* () {
73
112
  if (this.cmaAPIClient) {
@@ -177,7 +216,7 @@ class PersonalizationAdapter extends adapter_helper_1.AdapterHelper {
177
216
  }
178
217
  const errorMsg = (data === null || data === void 0 ? void 0 : data.errors)
179
218
  ? (0, error_helper_1.formatErrors)(data.errors)
180
- : (data === null || data === void 0 ? void 0 : data.error_message) || (data === null || data === void 0 ? void 0 : data.message) || 'Something went wrong while processing variant entries request!';
219
+ : (data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.error_message) || (data === null || data === void 0 ? void 0 : data.message) || 'Something went wrong while processing variant entries request!';
181
220
  throw errorMsg;
182
221
  }
183
222
  }
@@ -148,6 +148,7 @@ class VariantHttpClient extends adapter_helper_1.AdapterHelper {
148
148
  log,
149
149
  });
150
150
  try {
151
+ this.apiClient.headers({ api_version: undefined });
151
152
  const res = yield this.apiClient.put(endpoint, { entry: input });
152
153
  const data = this.handleVariantAPIRes(res);
153
154
  if (res.status >= 200 && res.status < 300) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentstack/cli-variants",
3
- "version": "0.0.1-alpha",
3
+ "version": "1.0.0",
4
4
  "description": "Variants plugin",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -2,26 +2,26 @@ import omit from 'lodash/omit';
2
2
  import { resolve as pResolve } from 'node:path';
3
3
  import { sanitizePath } from '@contentstack/cli-utilities';
4
4
  import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils';
5
- import { PersonalizationConfig, ExportConfig, AttributesConfig, AttributeStruct } from '../types';
5
+ import { PersonalizeConfig, ExportConfig, AttributesConfig, AttributeStruct } from '../types';
6
6
 
7
7
  export default class ExportAttributes extends PersonalizationAdapter<ExportConfig> {
8
8
  private attributesConfig: AttributesConfig;
9
9
  private attributesFolderPath: string;
10
10
  private attributes: Record<string, unknown>[];
11
- public personalizationConfig: PersonalizationConfig;
11
+ public personalizeConfig: PersonalizeConfig;
12
12
 
13
13
  constructor(readonly exportConfig: ExportConfig) {
14
14
  super({
15
15
  config: exportConfig,
16
- baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name],
16
+ baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
17
17
  headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
18
18
  });
19
- this.personalizationConfig = exportConfig.modules.personalization;
19
+ this.personalizeConfig = exportConfig.modules.personalize;
20
20
  this.attributesConfig = exportConfig.modules.attributes;
21
21
  this.attributesFolderPath = pResolve(
22
22
  sanitizePath(exportConfig.data),
23
23
  sanitizePath(exportConfig.branchName || ''),
24
- sanitizePath(this.personalizationConfig.dirName),
24
+ sanitizePath(this.personalizeConfig.dirName),
25
25
  sanitizePath(this.attributesConfig.dirName),
26
26
  );
27
27
  this.attributes = [];
@@ -2,26 +2,26 @@ import omit from 'lodash/omit';
2
2
  import { resolve as pResolve } from 'node:path';
3
3
 
4
4
  import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils';
5
- import { PersonalizationConfig, ExportConfig, AudienceStruct, AudiencesConfig } from '../types';
5
+ import { PersonalizeConfig, ExportConfig, AudienceStruct, AudiencesConfig } from '../types';
6
6
 
7
7
  export default class ExportAudiences extends PersonalizationAdapter<ExportConfig> {
8
8
  private audiencesConfig: AudiencesConfig;
9
9
  private audiencesFolderPath: string;
10
10
  private audiences: Record<string, unknown>[];
11
- public personalizationConfig: PersonalizationConfig;
11
+ public personalizeConfig: PersonalizeConfig;
12
12
 
13
13
  constructor(readonly exportConfig: ExportConfig) {
14
14
  super({
15
15
  config: exportConfig,
16
- baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name],
16
+ baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
17
17
  headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
18
18
  });
19
- this.personalizationConfig = exportConfig.modules.personalization;
19
+ this.personalizeConfig = exportConfig.modules.personalize;
20
20
  this.audiencesConfig = exportConfig.modules.audiences;
21
21
  this.audiencesFolderPath = pResolve(
22
22
  exportConfig.data,
23
23
  exportConfig.branchName || '',
24
- this.personalizationConfig.dirName,
24
+ this.personalizeConfig.dirName,
25
25
  this.audiencesConfig.dirName,
26
26
  );
27
27
  this.audiences = [];
@@ -2,26 +2,26 @@ import omit from 'lodash/omit';
2
2
  import { resolve as pResolve } from 'node:path';
3
3
 
4
4
  import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils';
5
- import { PersonalizationConfig, ExportConfig, EventStruct, EventsConfig } from '../types';
5
+ import { PersonalizeConfig, ExportConfig, EventStruct, EventsConfig } from '../types';
6
6
 
7
7
  export default class ExportEvents extends PersonalizationAdapter<ExportConfig> {
8
8
  private eventsConfig: EventsConfig;
9
9
  private eventsFolderPath: string;
10
10
  private events: Record<string, unknown>[];
11
- public personalizationConfig: PersonalizationConfig;
11
+ public personalizeConfig: PersonalizeConfig;
12
12
 
13
13
  constructor(readonly exportConfig: ExportConfig) {
14
14
  super({
15
15
  config: exportConfig,
16
- baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name],
16
+ baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
17
17
  headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
18
18
  });
19
- this.personalizationConfig = exportConfig.modules.personalization;
19
+ this.personalizeConfig = exportConfig.modules.personalize;
20
20
  this.eventsConfig = exportConfig.modules.events;
21
21
  this.eventsFolderPath = pResolve(
22
22
  exportConfig.data,
23
23
  exportConfig.branchName || '',
24
- this.personalizationConfig.dirName,
24
+ this.personalizeConfig.dirName,
25
25
  this.eventsConfig.dirName,
26
26
  );
27
27
  this.events = [];
@@ -1,16 +1,16 @@
1
1
  import * as path from 'path';
2
2
  import { sanitizePath } from '@contentstack/cli-utilities';
3
- import { PersonalizationConfig, ExportConfig, ExperienceStruct } from '../types';
3
+ import { PersonalizeConfig, ExportConfig, ExperienceStruct } from '../types';
4
4
  import { formatError, fsUtil, log, PersonalizationAdapter } from '../utils';
5
5
 
6
6
  export default class ExportExperiences extends PersonalizationAdapter<ExportConfig> {
7
7
  private experiencesFolderPath: string;
8
8
  public exportConfig: ExportConfig;
9
- public personalizationConfig: PersonalizationConfig;
9
+ public personalizeConfig: PersonalizeConfig;
10
10
  constructor(exportConfig: ExportConfig) {
11
11
  super({
12
12
  config: exportConfig,
13
- baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name],
13
+ baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
14
14
  headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
15
15
  cmaConfig: {
16
16
  baseURL: exportConfig.region.cma + `/v3`,
@@ -18,11 +18,11 @@ export default class ExportExperiences extends PersonalizationAdapter<ExportConf
18
18
  },
19
19
  });
20
20
  this.exportConfig = exportConfig;
21
- this.personalizationConfig = exportConfig.modules.personalization;
21
+ this.personalizeConfig = exportConfig.modules.personalize;
22
22
  this.experiencesFolderPath = path.resolve(
23
23
  sanitizePath(exportConfig.data),
24
24
  sanitizePath(exportConfig.branchName || ''),
25
- sanitizePath(this.personalizationConfig.dirName),
25
+ sanitizePath(this.personalizeConfig.dirName),
26
26
  'experiences',
27
27
  );
28
28
  }
@@ -34,6 +34,7 @@ export default class ExportExperiences extends PersonalizationAdapter<ExportConf
34
34
  // write experiences in to a file
35
35
  log(this.exportConfig, 'Starting experiences export', 'info');
36
36
  await fsUtil.makeDirectory(this.experiencesFolderPath);
37
+ await fsUtil.makeDirectory(path.resolve(sanitizePath(this.experiencesFolderPath), 'versions'));
37
38
  const experiences: Array<ExperienceStruct> = (await this.getExperiences()) || [];
38
39
  if (!experiences || experiences?.length < 1) {
39
40
  log(this.exportConfig, 'No Experiences found with the give project', 'info');
@@ -51,6 +52,21 @@ export default class ExportExperiences extends PersonalizationAdapter<ExportConf
51
52
  experienceToVariantsStrList.push(experienceToVariantsStr);
52
53
  });
53
54
 
55
+ try {
56
+ // fetch versions of experience
57
+ const experienceVersions = (await this.getExperienceVersions(experience.uid)) || [];
58
+ if (experienceVersions.length > 0) {
59
+ fsUtil.writeFile(
60
+ path.resolve(sanitizePath(this.experiencesFolderPath), 'versions', `${experience.uid}.json`),
61
+ experienceVersions,
62
+ );
63
+ } else {
64
+ log(this.exportConfig, `No versions found for experience ${experience.name}`, 'info');
65
+ }
66
+ } catch (error) {
67
+ log(this.exportConfig, `Failed to fetch versions of experience ${experience.name}`, 'error');
68
+ }
69
+
54
70
  try {
55
71
  // fetch content of experience
56
72
  const { variant_groups: [variantGroup] = [] } =
@@ -1,24 +1,24 @@
1
1
  import * as path from 'path';
2
2
  import { sanitizePath } from '@contentstack/cli-utilities';
3
- import { ExportConfig, PersonalizationConfig } from '../types';
3
+ import { ExportConfig, PersonalizeConfig } from '../types';
4
4
  import { PersonalizationAdapter, log, fsUtil, formatError } from '../utils';
5
5
 
6
6
  export default class ExportProjects extends PersonalizationAdapter<ExportConfig> {
7
7
  private projectFolderPath: string;
8
8
  public exportConfig: ExportConfig;
9
- public personalizationConfig: PersonalizationConfig;
9
+ public personalizeConfig: PersonalizeConfig;
10
10
  constructor(exportConfig: ExportConfig) {
11
11
  super({
12
12
  config: exportConfig,
13
- baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name],
13
+ baseURL: exportConfig.modules.personalize.baseURL[exportConfig.region.name],
14
14
  headers: { authtoken: exportConfig.auth_token, organization_uid: exportConfig.org_uid },
15
15
  });
16
16
  this.exportConfig = exportConfig;
17
- this.personalizationConfig = exportConfig.modules.personalization;
17
+ this.personalizeConfig = exportConfig.modules.personalize;
18
18
  this.projectFolderPath = path.resolve(
19
19
  sanitizePath(exportConfig.data),
20
20
  sanitizePath(exportConfig.branchName || ''),
21
- sanitizePath(this.personalizationConfig.dirName),
21
+ sanitizePath(this.personalizeConfig.dirName),
22
22
  'projects',
23
23
  );
24
24
  }
@@ -29,7 +29,7 @@ export default class ExportProjects extends PersonalizationAdapter<ExportConfig>
29
29
  await fsUtil.makeDirectory(this.projectFolderPath);
30
30
  const project = await this.projects({ connectedStackApiKey: this.exportConfig.apiKey });
31
31
  if (!project || project?.length < 1) {
32
- log(this.exportConfig, 'No Personalization Project connected with the given stack', 'info');
32
+ log(this.exportConfig, 'No Personalize Project connected with the given stack', 'info');
33
33
  this.exportConfig.personalizationEnabled = false;
34
34
  return;
35
35
  }
@@ -38,7 +38,9 @@ export default class ExportProjects extends PersonalizationAdapter<ExportConfig>
38
38
  fsUtil.writeFile(path.resolve(sanitizePath(this.projectFolderPath), 'projects.json'), project);
39
39
  log(this.exportConfig, 'Project exported successfully!', 'success');
40
40
  } catch (error) {
41
- log(this.exportConfig, `Failed to export projects!`, 'error');
41
+ if (error !== 'Forbidden') {
42
+ log(this.exportConfig, `Failed to export projects!`, 'error');
43
+ }
42
44
  throw error;
43
45
  }
44
46
  }