@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.
Files changed (124) hide show
  1. package/lib/export/attributes.d.ts +15 -0
  2. package/lib/export/attributes.js +62 -0
  3. package/lib/export/audiences.d.ts +15 -0
  4. package/lib/export/audiences.js +63 -0
  5. package/lib/export/events.d.ts +15 -0
  6. package/lib/export/events.js +63 -0
  7. package/lib/export/experiences.d.ts +9 -0
  8. package/lib/export/experiences.js +99 -0
  9. package/lib/export/index.d.ts +9 -0
  10. package/lib/export/index.js +21 -0
  11. package/lib/export/projects.d.ts +9 -0
  12. package/lib/export/projects.js +73 -0
  13. package/lib/export/variant-entries.d.ts +18 -0
  14. package/lib/export/variant-entries.js +109 -0
  15. package/lib/import/attribute.d.ts +17 -0
  16. package/lib/import/attribute.js +64 -0
  17. package/lib/import/audiences.d.ts +19 -0
  18. package/lib/import/audiences.js +71 -0
  19. package/lib/import/events.d.ts +17 -0
  20. package/lib/import/events.js +62 -0
  21. package/lib/import/experiences.d.ts +46 -0
  22. package/lib/import/experiences.js +214 -0
  23. package/lib/import/index.d.ts +14 -0
  24. package/lib/import/index.js +21 -0
  25. package/lib/import/project.d.ts +13 -0
  26. package/lib/import/project.js +74 -0
  27. package/lib/import/variant-entries.d.ts +98 -0
  28. package/lib/import/variant-entries.js +407 -0
  29. package/lib/index.d.ts +5 -0
  30. package/lib/index.js +21 -0
  31. package/lib/messages/index.d.ts +35 -0
  32. package/lib/messages/index.js +55 -0
  33. package/lib/types/adapter-helper.d.ts +8 -0
  34. package/lib/types/adapter-helper.js +2 -0
  35. package/lib/types/content-types.d.ts +19 -0
  36. package/lib/types/content-types.js +2 -0
  37. package/lib/types/export-config.d.ts +264 -0
  38. package/lib/types/export-config.js +2 -0
  39. package/lib/types/import-config.d.ts +92 -0
  40. package/lib/types/import-config.js +2 -0
  41. package/lib/types/index.d.ts +8 -0
  42. package/lib/types/index.js +24 -0
  43. package/lib/types/personalization-api-adapter.d.ts +152 -0
  44. package/lib/types/personalization-api-adapter.js +2 -0
  45. package/lib/types/utils.d.ts +7 -0
  46. package/lib/types/utils.js +2 -0
  47. package/lib/types/variant-api-adapter.d.ts +49 -0
  48. package/lib/types/variant-api-adapter.js +2 -0
  49. package/lib/types/variant-entry.d.ts +47 -0
  50. package/lib/types/variant-entry.js +2 -0
  51. package/lib/utils/adapter-helper.d.ts +30 -0
  52. package/lib/utils/adapter-helper.js +95 -0
  53. package/lib/utils/attributes-helper.d.ts +7 -0
  54. package/lib/utils/attributes-helper.js +37 -0
  55. package/lib/utils/audiences-helper.d.ts +8 -0
  56. package/lib/utils/audiences-helper.js +49 -0
  57. package/lib/utils/error-helper.d.ts +6 -0
  58. package/lib/utils/error-helper.js +27 -0
  59. package/lib/utils/events-helper.d.ts +8 -0
  60. package/lib/utils/events-helper.js +27 -0
  61. package/lib/utils/helper.d.ts +4 -0
  62. package/lib/utils/helper.js +51 -0
  63. package/lib/utils/index.d.ts +9 -0
  64. package/lib/utils/index.js +25 -0
  65. package/lib/utils/logger.d.ts +3 -0
  66. package/lib/utils/logger.js +175 -0
  67. package/lib/utils/personalization-api-adapter.d.ts +73 -0
  68. package/lib/utils/personalization-api-adapter.js +184 -0
  69. package/lib/utils/variant-api-adapter.d.ts +79 -0
  70. package/lib/utils/variant-api-adapter.js +263 -0
  71. package/package.json +38 -0
  72. package/src/export/attributes.ts +55 -0
  73. package/src/export/audiences.ts +57 -0
  74. package/src/export/events.ts +57 -0
  75. package/src/export/experiences.ts +80 -0
  76. package/src/export/index.ts +11 -0
  77. package/src/export/projects.ts +45 -0
  78. package/src/export/variant-entries.ts +88 -0
  79. package/src/import/attribute.ts +60 -0
  80. package/src/import/audiences.ts +69 -0
  81. package/src/import/events.ts +58 -0
  82. package/src/import/experiences.ts +224 -0
  83. package/src/import/index.ts +16 -0
  84. package/src/import/project.ts +71 -0
  85. package/src/import/variant-entries.ts +483 -0
  86. package/src/index.ts +5 -0
  87. package/src/messages/index.ts +63 -0
  88. package/src/types/adapter-helper.ts +10 -0
  89. package/src/types/content-types.ts +41 -0
  90. package/src/types/export-config.ts +292 -0
  91. package/src/types/import-config.ts +95 -0
  92. package/src/types/index.ts +8 -0
  93. package/src/types/personalization-api-adapter.ts +197 -0
  94. package/src/types/utils.ts +8 -0
  95. package/src/types/variant-api-adapter.ts +56 -0
  96. package/src/types/variant-entry.ts +61 -0
  97. package/src/utils/adapter-helper.ts +79 -0
  98. package/src/utils/attributes-helper.ts +31 -0
  99. package/src/utils/audiences-helper.ts +50 -0
  100. package/src/utils/error-helper.ts +26 -0
  101. package/src/utils/events-helper.ts +26 -0
  102. package/src/utils/helper.ts +34 -0
  103. package/src/utils/index.ts +9 -0
  104. package/src/utils/logger.ts +160 -0
  105. package/src/utils/personalization-api-adapter.ts +188 -0
  106. package/src/utils/variant-api-adapter.ts +326 -0
  107. package/test/unit/export/variant-entries.test.ts +80 -0
  108. package/test/unit/import/variant-entries.test.ts +200 -0
  109. package/test/unit/mock/contents/content_types/CT-1.json +7 -0
  110. package/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/9b0da6xd7et72y-6gv7he23.json +12 -0
  111. package/test/unit/mock/contents/entries/CT-1/en-us/variants/E-1/index.json +3 -0
  112. package/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/9b0da6xd7et72y-6gv7he23.json +12 -0
  113. package/test/unit/mock/contents/entries/CT-1/en-us/variants/E-2/index.json +3 -0
  114. package/test/unit/mock/contents/mapper/assets/uid-mapping.json +6 -0
  115. package/test/unit/mock/contents/mapper/assets/url-mapping.json +6 -0
  116. package/test/unit/mock/contents/mapper/entries/data-for-variant-entry.json +6 -0
  117. package/test/unit/mock/contents/mapper/entries/empty-data/data-for-variant-entry.json +1 -0
  118. package/test/unit/mock/contents/mapper/entries/uid-mapping.json +6 -0
  119. package/test/unit/mock/contents/mapper/marketplace_apps/uid-mapping.json +3 -0
  120. package/test/unit/mock/contents/mapper/personalization/experiences/variants-uid-mapping.json +5 -0
  121. package/test/unit/mock/contents/mapper/taxonomies/terms/success.json +1 -0
  122. package/test/unit/mock/export-config.json +48 -0
  123. package/test/unit/mock/import-config.json +63 -0
  124. 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
+ }