@contentstack/cli-variants 0.0.1-alpha
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 +15 -0
- package/lib/export/attributes.js +62 -0
- package/lib/export/audiences.d.ts +15 -0
- package/lib/export/audiences.js +63 -0
- package/lib/export/events.d.ts +15 -0
- package/lib/export/events.js +63 -0
- package/lib/export/experiences.d.ts +9 -0
- package/lib/export/experiences.js +99 -0
- package/lib/export/index.d.ts +9 -0
- package/lib/export/index.js +21 -0
- package/lib/export/projects.d.ts +9 -0
- package/lib/export/projects.js +73 -0
- package/lib/export/variant-entries.d.ts +18 -0
- package/lib/export/variant-entries.js +109 -0
- package/lib/import/attribute.d.ts +17 -0
- package/lib/import/attribute.js +64 -0
- package/lib/import/audiences.d.ts +19 -0
- package/lib/import/audiences.js +71 -0
- package/lib/import/events.d.ts +17 -0
- package/lib/import/events.js +62 -0
- package/lib/import/experiences.d.ts +46 -0
- package/lib/import/experiences.js +214 -0
- package/lib/import/index.d.ts +14 -0
- package/lib/import/index.js +21 -0
- package/lib/import/project.d.ts +13 -0
- package/lib/import/project.js +74 -0
- package/lib/import/variant-entries.d.ts +98 -0
- package/lib/import/variant-entries.js +407 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +21 -0
- package/lib/messages/index.d.ts +35 -0
- package/lib/messages/index.js +55 -0
- package/lib/types/adapter-helper.d.ts +8 -0
- package/lib/types/adapter-helper.js +2 -0
- package/lib/types/content-types.d.ts +19 -0
- package/lib/types/content-types.js +2 -0
- package/lib/types/export-config.d.ts +264 -0
- package/lib/types/export-config.js +2 -0
- package/lib/types/import-config.d.ts +92 -0
- package/lib/types/import-config.js +2 -0
- package/lib/types/index.d.ts +8 -0
- package/lib/types/index.js +24 -0
- package/lib/types/personalization-api-adapter.d.ts +152 -0
- package/lib/types/personalization-api-adapter.js +2 -0
- package/lib/types/utils.d.ts +7 -0
- package/lib/types/utils.js +2 -0
- package/lib/types/variant-api-adapter.d.ts +49 -0
- package/lib/types/variant-api-adapter.js +2 -0
- package/lib/types/variant-entry.d.ts +47 -0
- package/lib/types/variant-entry.js +2 -0
- package/lib/utils/adapter-helper.d.ts +30 -0
- package/lib/utils/adapter-helper.js +95 -0
- package/lib/utils/attributes-helper.d.ts +7 -0
- package/lib/utils/attributes-helper.js +37 -0
- package/lib/utils/audiences-helper.d.ts +8 -0
- package/lib/utils/audiences-helper.js +49 -0
- package/lib/utils/error-helper.d.ts +6 -0
- package/lib/utils/error-helper.js +27 -0
- package/lib/utils/events-helper.d.ts +8 -0
- package/lib/utils/events-helper.js +27 -0
- package/lib/utils/helper.d.ts +4 -0
- package/lib/utils/helper.js +51 -0
- package/lib/utils/index.d.ts +9 -0
- package/lib/utils/index.js +25 -0
- package/lib/utils/logger.d.ts +3 -0
- package/lib/utils/logger.js +175 -0
- package/lib/utils/personalization-api-adapter.d.ts +73 -0
- package/lib/utils/personalization-api-adapter.js +184 -0
- package/lib/utils/variant-api-adapter.d.ts +79 -0
- package/lib/utils/variant-api-adapter.js +263 -0
- package/package.json +38 -0
- package/src/export/attributes.ts +55 -0
- package/src/export/audiences.ts +57 -0
- package/src/export/events.ts +57 -0
- package/src/export/experiences.ts +80 -0
- package/src/export/index.ts +11 -0
- package/src/export/projects.ts +45 -0
- package/src/export/variant-entries.ts +88 -0
- package/src/import/attribute.ts +60 -0
- package/src/import/audiences.ts +69 -0
- package/src/import/events.ts +58 -0
- package/src/import/experiences.ts +224 -0
- package/src/import/index.ts +16 -0
- package/src/import/project.ts +71 -0
- package/src/import/variant-entries.ts +483 -0
- package/src/index.ts +5 -0
- package/src/messages/index.ts +63 -0
- package/src/types/adapter-helper.ts +10 -0
- package/src/types/content-types.ts +41 -0
- package/src/types/export-config.ts +292 -0
- package/src/types/import-config.ts +95 -0
- package/src/types/index.ts +8 -0
- package/src/types/personalization-api-adapter.ts +197 -0
- package/src/types/utils.ts +8 -0
- package/src/types/variant-api-adapter.ts +56 -0
- package/src/types/variant-entry.ts +61 -0
- package/src/utils/adapter-helper.ts +79 -0
- package/src/utils/attributes-helper.ts +31 -0
- package/src/utils/audiences-helper.ts +50 -0
- package/src/utils/error-helper.ts +26 -0
- package/src/utils/events-helper.ts +26 -0
- package/src/utils/helper.ts +34 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/logger.ts +160 -0
- package/src/utils/personalization-api-adapter.ts +188 -0
- package/src/utils/variant-api-adapter.ts +326 -0
- package/test/unit/export/variant-entries.test.ts +80 -0
- package/test/unit/import/variant-entries.test.ts +200 -0
- package/test/unit/mock/contents/content_types/CT-1.json +7 -0
- package/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/9b0da6xd7et72y-6gv7he23.json +12 -0
- package/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/index.json +3 -0
- package/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/9b0da6xd7et72y-6gv7he23.json +12 -0
- package/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/index.json +3 -0
- package/test/unit/mock/contents/mapper/assets/uid-mapping.json +6 -0
- package/test/unit/mock/contents/mapper/assets/url-mapping.json +6 -0
- package/test/unit/mock/contents/mapper/entries/data-for-variant-entry.json +6 -0
- package/test/unit/mock/contents/mapper/entries/empty-data/data-for-variant-entry.json +1 -0
- package/test/unit/mock/contents/mapper/entries/uid-mapping.json +6 -0
- package/test/unit/mock/contents/mapper/marketplace_apps/uid-mapping.json +3 -0
- package/test/unit/mock/contents/mapper/personalization/experiences/variants-uid-mapping.json +5 -0
- package/test/unit/mock/contents/mapper/taxonomies/terms/success.json +1 -0
- package/test/unit/mock/export-config.json +48 -0
- package/test/unit/mock/import-config.json +63 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PersonalizationAdapter = void 0;
|
|
13
|
+
const adapter_helper_1 = require("./adapter-helper");
|
|
14
|
+
const error_helper_1 = require("./error-helper");
|
|
15
|
+
class PersonalizationAdapter extends adapter_helper_1.AdapterHelper {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
super(options);
|
|
18
|
+
}
|
|
19
|
+
projects(options) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
const getProjectEndPoint = `/projects?connectedStackApiKey=${options.connectedStackApiKey}`;
|
|
22
|
+
const data = yield this.apiClient.get(getProjectEndPoint);
|
|
23
|
+
return this.handleVariantAPIRes(data);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* This TypeScript function creates a project by making an asynchronous API call to retrieve project
|
|
28
|
+
* data.
|
|
29
|
+
* @param {CreateProjectInput} input - The `input` parameter in the `createProject` function likely
|
|
30
|
+
* represents the data needed to create a new project. It could include details such as the project
|
|
31
|
+
* name, description, owner, deadline, or any other relevant information required to set up a new
|
|
32
|
+
* project.
|
|
33
|
+
* @returns The `createProject` function is returning a Promise that resolves to either a
|
|
34
|
+
* `ProjectStruct` object or `void`.
|
|
35
|
+
*/
|
|
36
|
+
createProject(project) {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
const data = yield this.apiClient.post('/projects', project);
|
|
39
|
+
return this.handleVariantAPIRes(data);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The function `createAttribute` asynchronously retrieves attribute data from an API endpoint.
|
|
44
|
+
* @param {CreateAttributeInput} input - The `input` parameter in the `createAttribute` function is
|
|
45
|
+
* of type `CreateAttributeInput`. This parameter likely contains the necessary data or information
|
|
46
|
+
* needed to create a new attribute.
|
|
47
|
+
* @returns The `createAttribute` function is returning the data obtained from a GET request to the
|
|
48
|
+
* `/attributes` endpoint using the `apiClient` with the input provided. The data returned is of type
|
|
49
|
+
* `ProjectStruct`.
|
|
50
|
+
*/
|
|
51
|
+
createAttribute(attribute) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
const data = yield this.apiClient.post('/attributes', attribute);
|
|
54
|
+
return this.handleVariantAPIRes(data);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
getExperiences() {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
const getExperiencesEndPoint = `/experiences`;
|
|
60
|
+
const data = yield this.apiClient.get(getExperiencesEndPoint);
|
|
61
|
+
return this.handleVariantAPIRes(data);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
getExperience(experienceUid) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const getExperiencesEndPoint = `/experiences/${experienceUid}`;
|
|
67
|
+
const data = yield this.apiClient.get(getExperiencesEndPoint);
|
|
68
|
+
return this.handleVariantAPIRes(data);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
getVariantGroup(input) {
|
|
72
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
if (this.cmaAPIClient) {
|
|
74
|
+
const getVariantGroupEndPoint = `/variant_groups`;
|
|
75
|
+
const data = yield this.cmaAPIClient
|
|
76
|
+
.queryParams({ experience_uid: input.experienceUid })
|
|
77
|
+
.get(getVariantGroupEndPoint);
|
|
78
|
+
return this.handleVariantAPIRes(data);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
updateVariantGroup(input) {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
if (this.cmaAPIClient) {
|
|
85
|
+
const updateVariantGroupEndPoint = `/variant_groups/${input.uid}`;
|
|
86
|
+
const data = yield this.cmaAPIClient.put(updateVariantGroupEndPoint, input);
|
|
87
|
+
return this.handleVariantAPIRes(data);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
getEvents() {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
const data = yield this.apiClient.get('/events');
|
|
94
|
+
return this.handleVariantAPIRes(data);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
createEvents(event) {
|
|
98
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
+
const data = yield this.apiClient.post('/events', event);
|
|
100
|
+
return this.handleVariantAPIRes(data);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
getAudiences() {
|
|
104
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
const data = yield this.apiClient.get('/audiences');
|
|
106
|
+
return this.handleVariantAPIRes(data);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
getAttributes() {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
const data = yield this.apiClient.get('/attributes');
|
|
112
|
+
return this.handleVariantAPIRes(data);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* @param {CreateAudienceInput} audience - The `audience` parameter in the `createAudience` function is
|
|
117
|
+
* of type `CreateAudienceInput`. This parameter likely contains the necessary data or information
|
|
118
|
+
* needed to create a new audience.
|
|
119
|
+
* @returns The `createAudience` function is returning the data obtained from a GET request to the
|
|
120
|
+
* `/audiences` endpoint using the `apiClient` with the input provided. The data returned is of type
|
|
121
|
+
* `AudienceStruct`.
|
|
122
|
+
*/
|
|
123
|
+
createAudience(audience) {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
const data = yield this.apiClient.post('/audiences', audience);
|
|
126
|
+
return this.handleVariantAPIRes(data);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* @param {CreateExperienceInput} experience - The `experience` parameter in the `createExperience` function is
|
|
131
|
+
* of type `CreateExperienceInput`. This parameter likely contains the necessary data or information
|
|
132
|
+
* needed to create a new audience.
|
|
133
|
+
* @returns The `createExperience` function is returning the data obtained from a GET request to the
|
|
134
|
+
* `/experiences` endpoint using the `apiClient` with the input provided. The data returned is of type
|
|
135
|
+
* `ExperienceStruct`.
|
|
136
|
+
*/
|
|
137
|
+
createExperience(experience) {
|
|
138
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
139
|
+
const data = yield this.apiClient.post('/experiences', experience);
|
|
140
|
+
return this.handleVariantAPIRes(data);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* @param {UpdateExperienceInput} experience - The `experience` parameter in the `updateCTsInExperience` function is
|
|
145
|
+
* of type `UpdateExperienceInput`. This parameter likely contains the necessary data or information
|
|
146
|
+
* needed to attach CT in new created experience.
|
|
147
|
+
*/
|
|
148
|
+
updateCTsInExperience(experience, experienceUid) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
const updateCTInExpEndPoint = `/experiences/${experienceUid}/cms-integration/variant-group`;
|
|
151
|
+
const data = yield this.apiClient.post(updateCTInExpEndPoint, experience);
|
|
152
|
+
return this.handleVariantAPIRes(data);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* @param {UpdateExperienceInput} experienceUid - The `experienceUid` parameter in the `getCTsFromExperience` function is
|
|
157
|
+
* of type `string`. This parameter likely contains the necessary data or information
|
|
158
|
+
* needed to fetch CT details related to experience.
|
|
159
|
+
*/
|
|
160
|
+
getCTsFromExperience(experienceUid) {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
const getCTFromExpEndPoint = `/experiences/${experienceUid}/cms-integration/variant-group`;
|
|
163
|
+
const data = yield this.apiClient.get(getCTFromExpEndPoint);
|
|
164
|
+
return this.handleVariantAPIRes(data);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Handles the API response for variant requests.
|
|
169
|
+
* @param res - The API response object.
|
|
170
|
+
* @returns The variant API response data.
|
|
171
|
+
* @throws If the API response status is not within the success range, an error message is thrown.
|
|
172
|
+
*/
|
|
173
|
+
handleVariantAPIRes(res) {
|
|
174
|
+
const { status, data } = res;
|
|
175
|
+
if (status >= 200 && status < 300) {
|
|
176
|
+
return data;
|
|
177
|
+
}
|
|
178
|
+
const errorMsg = (data === null || data === void 0 ? void 0 : data.errors)
|
|
179
|
+
? (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!';
|
|
181
|
+
throw errorMsg;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.PersonalizationAdapter = PersonalizationAdapter;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { HttpClient, HttpClientOptions, ContentstackClient, ContentstackConfig } from '@contentstack/cli-utilities';
|
|
2
|
+
import { APIConfig, AdapterType, AnyProperty, VariantOptions, VariantsOption, VariantInterface, VariantEntryStruct, CreateVariantEntryDto, CreateVariantEntryOptions, APIResponse, PublishVariantEntryDto, PublishVariantEntryOptions } from '../types';
|
|
3
|
+
import messages from '../messages';
|
|
4
|
+
import { AdapterHelper } from './adapter-helper';
|
|
5
|
+
export declare class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implements VariantInterface<C, HttpClient> {
|
|
6
|
+
baseURL: string;
|
|
7
|
+
constructor(config: APIConfig, options?: HttpClientOptions);
|
|
8
|
+
variantEntry(options: VariantOptions): Promise<{
|
|
9
|
+
entry: {};
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* The function `variantEntries` retrieves variant entries based on specified options and stores them
|
|
13
|
+
* in an array.
|
|
14
|
+
* @param {VariantsOption} options - The `options` parameter in the `variantEntries` function is an
|
|
15
|
+
* object that contains the following properties:
|
|
16
|
+
* @param {Record<string, any>[]} entries - The `entries` parameter in the `variantEntries` function
|
|
17
|
+
* is an array of objects where each object represents a record with key-value pairs. This parameter
|
|
18
|
+
* is used to store the entries retrieved from the API response or passed down recursively when
|
|
19
|
+
* fetching all data.
|
|
20
|
+
* @returns The function `variantEntries` returns a Promise that resolves to an object with an
|
|
21
|
+
* `entries` property containing an array of record objects or an unknown array. The function can
|
|
22
|
+
* also return void if certain conditions are not met.
|
|
23
|
+
*/
|
|
24
|
+
variantEntries(options: VariantsOption, entries?: Record<string, any>[]): Promise<{
|
|
25
|
+
entries?: Record<string, any>[] | unknown[];
|
|
26
|
+
} | void>;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a variant entry.
|
|
29
|
+
*
|
|
30
|
+
* @param input - The input data for the variant entry.
|
|
31
|
+
* @param options - The options for creating the variant entry.
|
|
32
|
+
* @param apiParams - Additional parameters for the API.
|
|
33
|
+
* @returns A Promise that resolves to a VariantEntryStruct, a string, or void.
|
|
34
|
+
*/
|
|
35
|
+
createVariantEntry(input: CreateVariantEntryDto, options: CreateVariantEntryOptions, apiParams: Record<string, any>): Promise<VariantEntryStruct | string | void>;
|
|
36
|
+
/**
|
|
37
|
+
* Publishes a variant entry.
|
|
38
|
+
*
|
|
39
|
+
* @param input - The input data for publishing the variant entry.
|
|
40
|
+
* @param options - The options for publishing the variant entry.
|
|
41
|
+
* @param apiParams - Additional API parameters.
|
|
42
|
+
* @returns A Promise that resolves to the published variant entry response.
|
|
43
|
+
*/
|
|
44
|
+
publishVariantEntry(input: PublishVariantEntryDto, options: PublishVariantEntryOptions, apiParams: Record<string, any>): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Handles the API response for variant requests.
|
|
47
|
+
* @param res - The API response object.
|
|
48
|
+
* @returns The variant API response data.
|
|
49
|
+
* @throws If the API response status is not within the success range, an error message is thrown.
|
|
50
|
+
*/
|
|
51
|
+
handleVariantAPIRes(res: APIResponse): VariantEntryStruct | {
|
|
52
|
+
entries: VariantEntryStruct[];
|
|
53
|
+
count: number;
|
|
54
|
+
} | string | any;
|
|
55
|
+
}
|
|
56
|
+
export declare class VariantManagementSDK<T> extends AdapterHelper<T, ContentstackClient> implements VariantInterface<T, ContentstackClient> {
|
|
57
|
+
apiClient: ContentstackClient;
|
|
58
|
+
init(): Promise<void>;
|
|
59
|
+
variantEntry(options: VariantOptions): Promise<{
|
|
60
|
+
entry: {};
|
|
61
|
+
}>;
|
|
62
|
+
variantEntries(options: VariantsOption): Promise<{
|
|
63
|
+
entries: {}[];
|
|
64
|
+
}>;
|
|
65
|
+
createVariantEntry(input: CreateVariantEntryDto, options: CreateVariantEntryOptions, apiParams: Record<string, any>): Promise<VariantEntryStruct | string | void>;
|
|
66
|
+
handleVariantAPIRes(res: APIResponse): VariantEntryStruct | {
|
|
67
|
+
entries: VariantEntryStruct[];
|
|
68
|
+
count: number;
|
|
69
|
+
} | string;
|
|
70
|
+
constructQuery(query: Record<string, any>): string | void;
|
|
71
|
+
delay(ms: number): Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
export declare class VariantAdapter<T> {
|
|
74
|
+
protected variantInstance: T;
|
|
75
|
+
readonly messages: typeof messages;
|
|
76
|
+
constructor(config: ContentstackConfig & AnyProperty & AdapterType<T, ContentstackConfig>);
|
|
77
|
+
constructor(config: APIConfig & AdapterType<T, APIConfig & AnyProperty>, options?: HttpClientOptions);
|
|
78
|
+
}
|
|
79
|
+
export default VariantAdapter;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
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
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.VariantAdapter = exports.VariantManagementSDK = exports.VariantHttpClient = void 0;
|
|
27
|
+
const omit_1 = __importDefault(require("lodash/omit"));
|
|
28
|
+
const fs_1 = require("fs");
|
|
29
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
30
|
+
const messages_1 = __importDefault(require("../messages"));
|
|
31
|
+
const adapter_helper_1 = require("./adapter-helper");
|
|
32
|
+
const error_helper_1 = require("./error-helper");
|
|
33
|
+
class VariantHttpClient extends adapter_helper_1.AdapterHelper {
|
|
34
|
+
constructor(config, options) {
|
|
35
|
+
var _a;
|
|
36
|
+
super(config, options);
|
|
37
|
+
this.baseURL = ((_a = config.baseURL) === null || _a === void 0 ? void 0 : _a.includes('http')) ? `${config.baseURL}/v3` : `https://${config.baseURL}/v3`;
|
|
38
|
+
this.apiClient.baseUrl(this.baseURL);
|
|
39
|
+
}
|
|
40
|
+
variantEntry(options) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
// TODO single entry variant
|
|
43
|
+
return { entry: {} };
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The function `variantEntries` retrieves variant entries based on specified options and stores them
|
|
48
|
+
* in an array.
|
|
49
|
+
* @param {VariantsOption} options - The `options` parameter in the `variantEntries` function is an
|
|
50
|
+
* object that contains the following properties:
|
|
51
|
+
* @param {Record<string, any>[]} entries - The `entries` parameter in the `variantEntries` function
|
|
52
|
+
* is an array of objects where each object represents a record with key-value pairs. This parameter
|
|
53
|
+
* is used to store the entries retrieved from the API response or passed down recursively when
|
|
54
|
+
* fetching all data.
|
|
55
|
+
* @returns The function `variantEntries` returns a Promise that resolves to an object with an
|
|
56
|
+
* `entries` property containing an array of record objects or an unknown array. The function can
|
|
57
|
+
* also return void if certain conditions are not met.
|
|
58
|
+
*/
|
|
59
|
+
variantEntries(options_1) {
|
|
60
|
+
return __awaiter(this, arguments, void 0, function* (options, entries = []) {
|
|
61
|
+
const variantConfig = this.config.modules.variantEntry;
|
|
62
|
+
const { callback, entry_uid, getAllData, returnResult, content_type_uid, locale, skip = variantConfig.query.skip || 0, limit = variantConfig.query.limit || 100, include_variant = variantConfig.query.include_variant || true, include_count = variantConfig.query.include_count || true, include_publish_details = variantConfig.query.include_publish_details || true, } = options;
|
|
63
|
+
if (variantConfig.serveMockData && callback) {
|
|
64
|
+
let data = [];
|
|
65
|
+
if ((0, fs_1.existsSync)(variantConfig.mockDataPath)) {
|
|
66
|
+
data = require(variantConfig.mockDataPath);
|
|
67
|
+
}
|
|
68
|
+
callback(data);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (!locale)
|
|
72
|
+
return;
|
|
73
|
+
const start = Date.now();
|
|
74
|
+
let endpoint = `/content_types/${content_type_uid}/entries/${entry_uid}/variants?locale=${locale}`;
|
|
75
|
+
if (skip) {
|
|
76
|
+
endpoint = endpoint.concat(`&skip=${skip}`);
|
|
77
|
+
}
|
|
78
|
+
if (limit) {
|
|
79
|
+
endpoint = endpoint.concat(`&limit=${limit}`);
|
|
80
|
+
}
|
|
81
|
+
if (include_variant) {
|
|
82
|
+
endpoint = endpoint.concat(`&include_variant=${include_variant}`);
|
|
83
|
+
}
|
|
84
|
+
if (include_count) {
|
|
85
|
+
endpoint = endpoint.concat(`&include_count=${include_count}`);
|
|
86
|
+
}
|
|
87
|
+
if (include_publish_details) {
|
|
88
|
+
endpoint = endpoint.concat(`&include_publish_details=${include_publish_details}`);
|
|
89
|
+
}
|
|
90
|
+
const query = this.constructQuery((0, omit_1.default)(variantConfig.query, [
|
|
91
|
+
'skip',
|
|
92
|
+
'limit',
|
|
93
|
+
'locale',
|
|
94
|
+
'include_variant',
|
|
95
|
+
'include_count',
|
|
96
|
+
'include_publish_details',
|
|
97
|
+
]));
|
|
98
|
+
if (query) {
|
|
99
|
+
endpoint = endpoint.concat(query);
|
|
100
|
+
}
|
|
101
|
+
const data = yield this.apiClient.get(endpoint);
|
|
102
|
+
const response = this.handleVariantAPIRes(data);
|
|
103
|
+
if (callback) {
|
|
104
|
+
callback(response.entries);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
entries = entries.concat(response.entries);
|
|
108
|
+
}
|
|
109
|
+
if (getAllData && skip + limit < response.count) {
|
|
110
|
+
const end = Date.now();
|
|
111
|
+
const exeTime = end - start;
|
|
112
|
+
if (exeTime < 1000) {
|
|
113
|
+
// 1 API call per second
|
|
114
|
+
yield this.delay(1000 - exeTime);
|
|
115
|
+
}
|
|
116
|
+
if (!options.skip) {
|
|
117
|
+
options['skip'] = 0;
|
|
118
|
+
}
|
|
119
|
+
options.skip += limit;
|
|
120
|
+
return yield this.variantEntries(options, entries);
|
|
121
|
+
}
|
|
122
|
+
if (returnResult)
|
|
123
|
+
return { entries };
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Creates a variant entry.
|
|
128
|
+
*
|
|
129
|
+
* @param input - The input data for the variant entry.
|
|
130
|
+
* @param options - The options for creating the variant entry.
|
|
131
|
+
* @param apiParams - Additional parameters for the API.
|
|
132
|
+
* @returns A Promise that resolves to a VariantEntryStruct, a string, or void.
|
|
133
|
+
*/
|
|
134
|
+
createVariantEntry(input, options, apiParams) {
|
|
135
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
+
const { reject, resolve, variantUid, log } = apiParams;
|
|
137
|
+
const variantConfig = this.config.modules.variantEntry;
|
|
138
|
+
const { locale = variantConfig.query.locale || 'en-us', variant_id, entry_uid, content_type_uid } = options;
|
|
139
|
+
let endpoint = `content_types/${content_type_uid}/entries/${entry_uid}/variants/${variant_id}?locale=${locale}`;
|
|
140
|
+
const query = this.constructQuery((0, omit_1.default)(variantConfig.query, ['locale']));
|
|
141
|
+
if (query) {
|
|
142
|
+
endpoint = endpoint.concat(query);
|
|
143
|
+
}
|
|
144
|
+
const onSuccess = (response) => resolve({ response, apiData: { variantUid, entryUid: entry_uid }, log });
|
|
145
|
+
const onReject = (error) => reject({
|
|
146
|
+
error,
|
|
147
|
+
apiData: { variantUid, entryUid: entry_uid },
|
|
148
|
+
log,
|
|
149
|
+
});
|
|
150
|
+
try {
|
|
151
|
+
const res = yield this.apiClient.put(endpoint, { entry: input });
|
|
152
|
+
const data = this.handleVariantAPIRes(res);
|
|
153
|
+
if (res.status >= 200 && res.status < 300) {
|
|
154
|
+
onSuccess(data);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
onReject(data);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
onReject(error);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Publishes a variant entry.
|
|
167
|
+
*
|
|
168
|
+
* @param input - The input data for publishing the variant entry.
|
|
169
|
+
* @param options - The options for publishing the variant entry.
|
|
170
|
+
* @param apiParams - Additional API parameters.
|
|
171
|
+
* @returns A Promise that resolves to the published variant entry response.
|
|
172
|
+
*/
|
|
173
|
+
publishVariantEntry(input, options, apiParams) {
|
|
174
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
+
const { reject, resolve, log, variantUid } = apiParams;
|
|
176
|
+
const { entry_uid, content_type_uid } = options;
|
|
177
|
+
let endpoint = `content_types/${content_type_uid}/entries/${entry_uid}/publish`;
|
|
178
|
+
const onSuccess = (response) => resolve({ response, apiData: { entryUid: entry_uid, variantUid }, log });
|
|
179
|
+
const onReject = (error) => reject({
|
|
180
|
+
error,
|
|
181
|
+
apiData: { entryUid: entry_uid, variantUid },
|
|
182
|
+
log,
|
|
183
|
+
});
|
|
184
|
+
try {
|
|
185
|
+
this.apiClient.headers({ api_version: 3.2 });
|
|
186
|
+
const res = yield this.apiClient.post(endpoint, input);
|
|
187
|
+
const data = this.handleVariantAPIRes(res);
|
|
188
|
+
if (res.status >= 200 && res.status < 300) {
|
|
189
|
+
onSuccess(data);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
onReject(data);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
onReject(error);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Handles the API response for variant requests.
|
|
202
|
+
* @param res - The API response object.
|
|
203
|
+
* @returns The variant API response data.
|
|
204
|
+
* @throws If the API response status is not within the success range, an error message is thrown.
|
|
205
|
+
*/
|
|
206
|
+
handleVariantAPIRes(res) {
|
|
207
|
+
const { status, data } = res;
|
|
208
|
+
if (status >= 200 && status < 300) {
|
|
209
|
+
return data;
|
|
210
|
+
}
|
|
211
|
+
const errorMsg = (data === null || data === void 0 ? void 0 : data.errors)
|
|
212
|
+
? (0, error_helper_1.formatErrors)(data.errors)
|
|
213
|
+
: (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!';
|
|
214
|
+
throw errorMsg;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
exports.VariantHttpClient = VariantHttpClient;
|
|
218
|
+
class VariantManagementSDK extends adapter_helper_1.AdapterHelper {
|
|
219
|
+
init() {
|
|
220
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
221
|
+
this.apiClient = yield (0, cli_utilities_1.managementSDKClient)(this.config);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
variantEntry(options) {
|
|
225
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
226
|
+
// TODO SDK implementation
|
|
227
|
+
return { entry: {} };
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
variantEntries(options) {
|
|
231
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
232
|
+
// TODO SDK implementation
|
|
233
|
+
return { entries: [{}] };
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
createVariantEntry(input, options, apiParams) {
|
|
237
|
+
// FIXME placeholder
|
|
238
|
+
return Promise.resolve({});
|
|
239
|
+
}
|
|
240
|
+
handleVariantAPIRes(res) {
|
|
241
|
+
return res.data;
|
|
242
|
+
}
|
|
243
|
+
constructQuery(query) { }
|
|
244
|
+
delay(ms) {
|
|
245
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
exports.VariantManagementSDK = VariantManagementSDK;
|
|
249
|
+
class VariantAdapter {
|
|
250
|
+
constructor(config, options) {
|
|
251
|
+
if (config.httpClient) {
|
|
252
|
+
const { httpClient, Adapter } = config, restConfig = __rest(config, ["httpClient", "Adapter"]);
|
|
253
|
+
this.variantInstance = new Adapter(restConfig, options);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
const { Adapter } = config, restConfig = __rest(config, ["Adapter"]);
|
|
257
|
+
this.variantInstance = new Adapter(restConfig);
|
|
258
|
+
}
|
|
259
|
+
this.messages = messages_1.default;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
exports.VariantAdapter = VariantAdapter;
|
|
263
|
+
exports.default = VariantAdapter;
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contentstack/cli-variants",
|
|
3
|
+
"version": "0.0.1-alpha",
|
|
4
|
+
"description": "Variants plugin",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"prepack": "pnpm compile",
|
|
9
|
+
"compile": "tsc -b tsconfig.json",
|
|
10
|
+
"test": "mocha --require ts-node/register --forbid-only \"test/**/*.test.ts\"",
|
|
11
|
+
"clean": "rm -rf ./lib ./node_modules tsconfig.build.tsbuildinfo",
|
|
12
|
+
"test:unit:report": "nyc --extension .ts mocha --require ts-node/register --forbid-only \"test/unit/**/*.test.ts\""
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"variant"
|
|
16
|
+
],
|
|
17
|
+
"author": "antony.raj@contentstack.com",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@contentstack/cli-dev-dependencies": "^1.2.4",
|
|
21
|
+
"@oclif/test": "^2.5.6",
|
|
22
|
+
"@types/chai": "^4.3.14",
|
|
23
|
+
"@types/node": "^20.12.7",
|
|
24
|
+
"chai": "^4.4.1",
|
|
25
|
+
"mocha": "^10.4.0",
|
|
26
|
+
"nyc": "^15.1.0",
|
|
27
|
+
"sinon": "^17.0.1",
|
|
28
|
+
"ts-node": "^10.9.2",
|
|
29
|
+
"tslib": "^2.6.2",
|
|
30
|
+
"typescript": "^5.4.2"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@contentstack/cli-utilities": "^1.5.12",
|
|
34
|
+
"lodash": "^4.17.21",
|
|
35
|
+
"mkdirp": "^1.0.4",
|
|
36
|
+
"winston": "^3.7.2"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import omit from 'lodash/omit';
|
|
2
|
+
import { resolve as pResolve } from 'node:path';
|
|
3
|
+
import { sanitizePath } from '@contentstack/cli-utilities';
|
|
4
|
+
import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils';
|
|
5
|
+
import { PersonalizationConfig, ExportConfig, AttributesConfig, AttributeStruct } from '../types';
|
|
6
|
+
|
|
7
|
+
export default class ExportAttributes extends PersonalizationAdapter<ExportConfig> {
|
|
8
|
+
private attributesConfig: AttributesConfig;
|
|
9
|
+
private attributesFolderPath: string;
|
|
10
|
+
private attributes: Record<string, unknown>[];
|
|
11
|
+
public personalizationConfig: PersonalizationConfig;
|
|
12
|
+
|
|
13
|
+
constructor(readonly exportConfig: ExportConfig) {
|
|
14
|
+
super({
|
|
15
|
+
config: exportConfig,
|
|
16
|
+
baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name],
|
|
17
|
+
headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
|
|
18
|
+
});
|
|
19
|
+
this.personalizationConfig = exportConfig.modules.personalization;
|
|
20
|
+
this.attributesConfig = exportConfig.modules.attributes;
|
|
21
|
+
this.attributesFolderPath = pResolve(
|
|
22
|
+
sanitizePath(exportConfig.data),
|
|
23
|
+
sanitizePath(exportConfig.branchName || ''),
|
|
24
|
+
sanitizePath(this.personalizationConfig.dirName),
|
|
25
|
+
sanitizePath(this.attributesConfig.dirName),
|
|
26
|
+
);
|
|
27
|
+
this.attributes = [];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async start() {
|
|
31
|
+
try {
|
|
32
|
+
log(this.exportConfig, 'Starting attributes export', 'info');
|
|
33
|
+
await fsUtil.makeDirectory(this.attributesFolderPath);
|
|
34
|
+
this.attributes = (await this.getAttributes()) as AttributeStruct[];
|
|
35
|
+
|
|
36
|
+
if (!this.attributes?.length) {
|
|
37
|
+
log(this.exportConfig, 'No Attributes found with the given project!', 'info');
|
|
38
|
+
} else {
|
|
39
|
+
this.sanitizeAttribs();
|
|
40
|
+
fsUtil.writeFile(pResolve(sanitizePath(this.attributesFolderPath), sanitizePath(this.attributesConfig.fileName)), this.attributes);
|
|
41
|
+
log(this.exportConfig, 'All the attributes have been exported successfully!', 'success');
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
log(this.exportConfig, `Failed to export attributes!`, 'error');
|
|
45
|
+
log(this.config, error, 'error');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* function to remove invalid keys from attributes object
|
|
51
|
+
*/
|
|
52
|
+
sanitizeAttribs() {
|
|
53
|
+
this.attributes = this.attributes?.map((audience) => omit(audience, this.attributesConfig.invalidKeys)) || [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import omit from 'lodash/omit';
|
|
2
|
+
import { resolve as pResolve } from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { formatError, fsUtil, PersonalizationAdapter, log } from '../utils';
|
|
5
|
+
import { PersonalizationConfig, ExportConfig, AudienceStruct, AudiencesConfig } from '../types';
|
|
6
|
+
|
|
7
|
+
export default class ExportAudiences extends PersonalizationAdapter<ExportConfig> {
|
|
8
|
+
private audiencesConfig: AudiencesConfig;
|
|
9
|
+
private audiencesFolderPath: string;
|
|
10
|
+
private audiences: Record<string, unknown>[];
|
|
11
|
+
public personalizationConfig: PersonalizationConfig;
|
|
12
|
+
|
|
13
|
+
constructor(readonly exportConfig: ExportConfig) {
|
|
14
|
+
super({
|
|
15
|
+
config: exportConfig,
|
|
16
|
+
baseURL: exportConfig.modules.personalization.baseURL[exportConfig.region.name],
|
|
17
|
+
headers: { authtoken: exportConfig.auth_token, 'X-Project-Uid': exportConfig.project_id },
|
|
18
|
+
});
|
|
19
|
+
this.personalizationConfig = exportConfig.modules.personalization;
|
|
20
|
+
this.audiencesConfig = exportConfig.modules.audiences;
|
|
21
|
+
this.audiencesFolderPath = pResolve(
|
|
22
|
+
exportConfig.data,
|
|
23
|
+
exportConfig.branchName || '',
|
|
24
|
+
this.personalizationConfig.dirName,
|
|
25
|
+
this.audiencesConfig.dirName,
|
|
26
|
+
);
|
|
27
|
+
this.audiences = [];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async start() {
|
|
31
|
+
try {
|
|
32
|
+
log(this.exportConfig, 'Starting audiences export', 'info');
|
|
33
|
+
await fsUtil.makeDirectory(this.audiencesFolderPath);
|
|
34
|
+
this.audiences = (await this.getAudiences()) as AudienceStruct[];
|
|
35
|
+
|
|
36
|
+
if (!this.audiences?.length) {
|
|
37
|
+
log(this.exportConfig, 'No Audiences found with the given project!', 'info');
|
|
38
|
+
return;
|
|
39
|
+
} else {
|
|
40
|
+
this.sanitizeAttribs();
|
|
41
|
+
fsUtil.writeFile(pResolve(this.audiencesFolderPath, this.audiencesConfig.fileName), this.audiences);
|
|
42
|
+
log(this.exportConfig, 'All the audiences have been exported successfully!', 'success');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
log(this.exportConfig, `Failed to export audiences!`, 'error');
|
|
47
|
+
log(this.config, error, 'error');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* function to remove invalid keys from audience object
|
|
53
|
+
*/
|
|
54
|
+
sanitizeAttribs() {
|
|
55
|
+
this.audiences = this.audiences?.map((audience) => omit(audience, this.audiencesConfig.invalidKeys)) || [];
|
|
56
|
+
}
|
|
57
|
+
}
|