@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.
- package/lib/export/attributes.d.ts +2 -2
- package/lib/export/attributes.js +3 -3
- package/lib/export/audiences.d.ts +2 -2
- package/lib/export/audiences.js +3 -3
- package/lib/export/events.d.ts +2 -2
- package/lib/export/events.js +3 -3
- package/lib/export/experiences.d.ts +2 -2
- package/lib/export/experiences.js +17 -3
- package/lib/export/projects.d.ts +2 -2
- package/lib/export/projects.js +7 -5
- package/lib/import/attribute.d.ts +1 -1
- package/lib/import/attribute.js +20 -10
- package/lib/import/audiences.d.ts +2 -2
- package/lib/import/audiences.js +20 -14
- package/lib/import/events.d.ts +1 -1
- package/lib/import/events.js +14 -8
- package/lib/import/experiences.d.ts +12 -5
- package/lib/import/experiences.js +84 -20
- package/lib/import/project.js +10 -10
- package/lib/import/variant-entries.d.ts +1 -1
- package/lib/import/variant-entries.js +13 -13
- package/lib/messages/index.d.ts +1 -1
- package/lib/messages/index.js +3 -2
- package/lib/types/export-config.d.ts +3 -3
- package/lib/types/import-config.d.ts +1 -1
- package/lib/types/personalization-api-adapter.d.ts +13 -0
- package/lib/types/variant-entry.d.ts +2 -2
- package/lib/utils/audiences-helper.js +14 -3
- package/lib/utils/error-helper.js +1 -1
- package/lib/utils/personalization-api-adapter.d.ts +4 -1
- package/lib/utils/personalization-api-adapter.js +40 -1
- package/lib/utils/variant-api-adapter.js +1 -0
- package/package.json +1 -1
- package/src/export/attributes.ts +5 -5
- package/src/export/audiences.ts +5 -5
- package/src/export/events.ts +5 -5
- package/src/export/experiences.ts +21 -5
- package/src/export/projects.ts +9 -7
- package/src/import/attribute.ts +30 -12
- package/src/import/audiences.ts +36 -18
- package/src/import/events.ts +24 -10
- package/src/import/experiences.ts +118 -28
- package/src/import/project.ts +10 -10
- package/src/import/variant-entries.ts +48 -25
- package/src/messages/index.ts +3 -2
- package/src/types/export-config.ts +3 -3
- package/src/types/import-config.ts +1 -1
- package/src/types/personalization-api-adapter.ts +13 -0
- package/src/types/variant-entry.ts +2 -2
- package/src/utils/audiences-helper.ts +12 -2
- package/src/utils/error-helper.ts +1 -1
- package/src/utils/personalization-api-adapter.ts +32 -2
- package/src/utils/variant-api-adapter.ts +2 -2
package/lib/import/project.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
|
35
|
-
const { dirName, fileName } =
|
|
36
|
-
const projectPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.data), (0, cli_utilities_1.sanitizePath)(
|
|
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.
|
|
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.
|
|
61
|
-
this.config.modules.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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 (
|
|
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:
|
|
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
|
|
333
|
-
const oldVariantUid = variantEntry.
|
|
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
|
|
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(
|
|
340
|
-
(0, utils_1.log)(this.config, `${this.messages.VARIANT_UID_NOT_FOUND}. Skipping entry variant publish for ${
|
|
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
|
}
|
package/lib/messages/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
20
|
+
PERSONALIZE_JOB_FAILURE: string;
|
|
21
21
|
};
|
|
22
22
|
declare const messages: typeof errors & typeof commonMsg & typeof migrationMsg & typeof variantEntry & typeof expImportMsg;
|
|
23
23
|
/**
|
package/lib/messages/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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' | '
|
|
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
|
-
|
|
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
|
|
246
|
+
export interface PersonalizeConfig {
|
|
247
247
|
dirName: string;
|
|
248
248
|
baseURL: Record<string, string>;
|
|
249
249
|
}
|
|
@@ -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
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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 = {};
|
|
@@ -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
package/src/export/attributes.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
11
|
+
public personalizeConfig: PersonalizeConfig;
|
|
12
12
|
|
|
13
13
|
constructor(readonly exportConfig: ExportConfig) {
|
|
14
14
|
super({
|
|
15
15
|
config: exportConfig,
|
|
16
|
-
baseURL: exportConfig.modules.
|
|
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.
|
|
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.
|
|
24
|
+
sanitizePath(this.personalizeConfig.dirName),
|
|
25
25
|
sanitizePath(this.attributesConfig.dirName),
|
|
26
26
|
);
|
|
27
27
|
this.attributes = [];
|
package/src/export/audiences.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
11
|
+
public personalizeConfig: PersonalizeConfig;
|
|
12
12
|
|
|
13
13
|
constructor(readonly exportConfig: ExportConfig) {
|
|
14
14
|
super({
|
|
15
15
|
config: exportConfig,
|
|
16
|
-
baseURL: exportConfig.modules.
|
|
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.
|
|
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.
|
|
24
|
+
this.personalizeConfig.dirName,
|
|
25
25
|
this.audiencesConfig.dirName,
|
|
26
26
|
);
|
|
27
27
|
this.audiences = [];
|
package/src/export/events.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
11
|
+
public personalizeConfig: PersonalizeConfig;
|
|
12
12
|
|
|
13
13
|
constructor(readonly exportConfig: ExportConfig) {
|
|
14
14
|
super({
|
|
15
15
|
config: exportConfig,
|
|
16
|
-
baseURL: exportConfig.modules.
|
|
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.
|
|
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.
|
|
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 {
|
|
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
|
|
9
|
+
public personalizeConfig: PersonalizeConfig;
|
|
10
10
|
constructor(exportConfig: ExportConfig) {
|
|
11
11
|
super({
|
|
12
12
|
config: exportConfig,
|
|
13
|
-
baseURL: exportConfig.modules.
|
|
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.
|
|
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.
|
|
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] = [] } =
|
package/src/export/projects.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import { sanitizePath } from '@contentstack/cli-utilities';
|
|
3
|
-
import { ExportConfig,
|
|
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
|
|
9
|
+
public personalizeConfig: PersonalizeConfig;
|
|
10
10
|
constructor(exportConfig: ExportConfig) {
|
|
11
11
|
super({
|
|
12
12
|
config: exportConfig,
|
|
13
|
-
baseURL: exportConfig.modules.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
41
|
+
if (error !== 'Forbidden') {
|
|
42
|
+
log(this.exportConfig, `Failed to export projects!`, 'error');
|
|
43
|
+
}
|
|
42
44
|
throw error;
|
|
43
45
|
}
|
|
44
46
|
}
|