@contentstack/cli-variants 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/lib/export/attributes.js +27 -10
  2. package/lib/export/audiences.js +28 -10
  3. package/lib/export/events.js +28 -10
  4. package/lib/export/experiences.js +48 -13
  5. package/lib/export/projects.js +24 -6
  6. package/lib/export/variant-entries.js +25 -4
  7. package/lib/import/attribute.d.ts +2 -3
  8. package/lib/import/attribute.js +16 -8
  9. package/lib/import/audiences.d.ts +2 -3
  10. package/lib/import/audiences.js +21 -8
  11. package/lib/import/events.d.ts +3 -4
  12. package/lib/import/events.js +16 -9
  13. package/lib/import/experiences.d.ts +2 -3
  14. package/lib/import/experiences.js +60 -17
  15. package/lib/import/project.d.ts +2 -3
  16. package/lib/import/project.js +11 -6
  17. package/lib/import/variant-entries.js +62 -25
  18. package/lib/types/export-config.d.ts +2 -1
  19. package/lib/types/utils.d.ts +11 -0
  20. package/lib/utils/attributes-helper.js +17 -1
  21. package/lib/utils/audiences-helper.js +37 -6
  22. package/lib/utils/events-helper.js +17 -4
  23. package/lib/utils/personalization-api-adapter.d.ts +2 -1
  24. package/lib/utils/personalization-api-adapter.js +119 -27
  25. package/lib/utils/variant-api-adapter.d.ts +4 -1
  26. package/lib/utils/variant-api-adapter.js +91 -17
  27. package/package.json +8 -5
  28. package/src/export/attributes.ts +34 -10
  29. package/src/export/audiences.ts +35 -7
  30. package/src/export/events.ts +35 -7
  31. package/src/export/experiences.ts +74 -24
  32. package/src/export/projects.ts +31 -7
  33. package/src/export/variant-entries.ts +47 -12
  34. package/src/import/attribute.ts +22 -9
  35. package/src/import/audiences.ts +28 -10
  36. package/src/import/events.ts +21 -10
  37. package/src/import/experiences.ts +74 -20
  38. package/src/import/project.ts +22 -8
  39. package/src/import/variant-entries.ts +116 -40
  40. package/src/types/export-config.ts +2 -1
  41. package/src/types/utils.ts +12 -0
  42. package/src/utils/attributes-helper.ts +21 -2
  43. package/src/utils/audiences-helper.ts +41 -1
  44. package/src/utils/events-helper.ts +19 -1
  45. package/src/utils/personalization-api-adapter.ts +95 -19
  46. package/src/utils/variant-api-adapter.ts +79 -8
@@ -8,6 +8,7 @@ import {
8
8
  ContentstackConfig,
9
9
  managementSDKClient,
10
10
  authenticationHandler,
11
+ log,
11
12
  } from '@contentstack/cli-utilities';
12
13
 
13
14
  import {
@@ -32,23 +33,33 @@ import { formatErrors } from './error-helper';
32
33
 
33
34
  export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implements VariantInterface<C, HttpClient> {
34
35
  public baseURL: string;
36
+ public exportConfig?: ExportConfig;
37
+
35
38
  constructor(config: APIConfig, options?: HttpClientOptions) {
36
39
  super(config, options);
37
40
  this.baseURL = config.baseURL?.includes('http') ? `${config.baseURL}/v3` : `https://${config.baseURL}/v3`;
38
41
  this.apiClient.baseUrl(this.baseURL);
42
+ log.debug(`VariantHttpClient initialized with base URL: ${this.baseURL}`, this.exportConfig?.context );
39
43
  }
40
44
 
41
45
  async init(): Promise<void> {
46
+ log.debug('Initializing VariantHttpClient...', this.exportConfig?.context );
42
47
  await authenticationHandler.getAuthDetails();
43
48
  const token = authenticationHandler.accessToken;
49
+ log.debug(`Authentication type: ${authenticationHandler.isOauthEnabled ? 'OAuth' : 'Token'}`, this.exportConfig?.context );
50
+
44
51
  if (authenticationHandler.isOauthEnabled) {
52
+ log.debug('Setting OAuth authorization header', this.exportConfig?.context );
45
53
  this.apiClient.headers({ authorization: token });
46
54
  } else {
55
+ log.debug('Setting authtoken header', this.exportConfig?.context );
47
56
  this.apiClient.headers({ authtoken: token });
48
57
  }
58
+ log.debug('VariantHttpClient initialization completed', this.exportConfig?.context );
49
59
  }
50
60
 
51
61
  async variantEntry(options: VariantOptions) {
62
+ log.debug('VariantEntry method called (placeholder implementation)', { module: 'variant-api-adapter' });
52
63
  // TODO single entry variant
53
64
  return { entry: {} };
54
65
  }
@@ -85,16 +96,24 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
85
96
  include_publish_details = variantConfig.query.include_publish_details || true,
86
97
  } = options;
87
98
 
99
+ log.debug(`Fetching variant entries for content type: ${content_type_uid}, entry: ${entry_uid}, locale: ${locale}`, this.exportConfig?.context );
100
+ log.debug(`Query parameters - skip: ${skip}, limit: ${limit}, include_variant: ${include_variant}, include_count: ${include_count}, include_publish_details: ${include_publish_details}`, this.exportConfig?.context );
101
+
88
102
  if (variantConfig.serveMockData && callback) {
103
+ log.debug('Using mock data for variant entries', this.exportConfig?.context );
89
104
  let data = [] as Record<string, any>[];
90
105
 
91
106
  if (existsSync(variantConfig.mockDataPath)) {
107
+ log.debug(`Loading mock data from: ${variantConfig.mockDataPath}`, this.exportConfig?.context );
92
108
  data = require(variantConfig.mockDataPath) as Record<string, any>[];
93
109
  }
94
110
  callback(data);
95
111
  return;
96
112
  }
97
- if (!locale) return;
113
+ if (!locale) {
114
+ log.debug('No locale provided, skipping variant entries fetch', this.exportConfig?.context );
115
+ return;
116
+ }
98
117
 
99
118
  const start = Date.now();
100
119
  let endpoint = `/content_types/${content_type_uid}/entries/${entry_uid}/variants?locale=${locale}`;
@@ -134,12 +153,19 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
134
153
  endpoint = endpoint.concat(query);
135
154
  }
136
155
 
156
+ log.debug(`Making API call to: ${endpoint}`, this.exportConfig?.context );
137
157
  const data = await this.apiClient.get(endpoint);
138
158
  const response = (await this.handleVariantAPIRes(data)) as { entries: VariantEntryStruct[]; count: number };
159
+
160
+ if (response?.entries?.length) {
161
+ log.debug(`Received ${response.entries?.length} variant entries out of total ${response.count}`, this.exportConfig?.context );
162
+ }
139
163
 
140
164
  if (callback) {
165
+ log.debug('Executing callback with variant entries', this.exportConfig?.context );
141
166
  callback(response.entries);
142
167
  } else {
168
+ log.debug('Adding variant entries to collection', this.exportConfig?.context );
143
169
  entries = entries.concat(response.entries);
144
170
  }
145
171
 
@@ -149,6 +175,7 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
149
175
 
150
176
  if (exeTime < 1000) {
151
177
  // 1 API call per second
178
+ log.debug(`Rate limiting: waiting ${1000 - exeTime}ms before next request`, this.exportConfig?.context );
152
179
  await this.delay(1000 - exeTime);
153
180
  }
154
181
  if (!options.skip) {
@@ -156,10 +183,14 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
156
183
  }
157
184
 
158
185
  options.skip += limit;
186
+ log.debug(`Continuing to fetch variant entries with skip: ${options.skip}`, this.exportConfig?.context );
159
187
  return await this.variantEntries(options, entries);
160
188
  }
161
189
 
162
- if (returnResult) return { entries };
190
+ if (returnResult) {
191
+ log.debug('Returning variant entries result', this.exportConfig?.context );
192
+ return { entries };
193
+ }
163
194
  }
164
195
 
165
196
  /**
@@ -178,6 +209,9 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
178
209
  const { reject, resolve, variantUid, log } = apiParams;
179
210
  const variantConfig = (this.config as ImportConfig).modules.variantEntry;
180
211
  const { locale = variantConfig.query.locale || 'en-us', variant_id, entry_uid, content_type_uid } = options;
212
+
213
+ log.debug(`Creating variant entry for content type: ${content_type_uid}, entry: ${entry_uid}, variant: ${variant_id}`, this.exportConfig?.context );
214
+
181
215
  let endpoint = `content_types/${content_type_uid}/entries/${entry_uid}/variants/${variant_id}?locale=${locale}`;
182
216
 
183
217
  const query = this.constructQuery(omit(variantConfig.query, ['locale']));
@@ -186,13 +220,20 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
186
220
  endpoint = endpoint.concat(query);
187
221
  }
188
222
 
189
- const onSuccess = (response: any) => resolve({ response, apiData: { variantUid, entryUid: entry_uid }, log });
190
- const onReject = (error: any) =>
223
+ log.debug(`Making API call to: ${endpoint}`, this.exportConfig?.context );
224
+
225
+ const onSuccess = (response: any) => {
226
+ log.debug(`Variant entry created successfully: ${variantUid}`, this.exportConfig?.context );
227
+ resolve({ response, apiData: { variantUid, entryUid: entry_uid }, log });
228
+ };
229
+ const onReject = (error: any) => {
230
+ log.debug(`Failed to create variant entry: ${variantUid}`, this.exportConfig?.context );
191
231
  reject({
192
232
  error,
193
233
  apiData: { variantUid, entryUid: entry_uid },
194
234
  log,
195
235
  });
236
+ };
196
237
 
197
238
  try {
198
239
  this.apiClient.headers({ api_version: undefined });
@@ -224,16 +265,25 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
224
265
  ) {
225
266
  const { reject, resolve, log, variantUid } = apiParams;
226
267
  const { entry_uid, content_type_uid } = options;
268
+
269
+ log.debug(`Publishing variant entry for content type: ${content_type_uid}, entry: ${entry_uid}`, this.exportConfig?.context );
270
+
227
271
  let endpoint = `content_types/${content_type_uid}/entries/${entry_uid}/publish`;
228
272
 
229
- const onSuccess = (response: any) =>
273
+ log.debug(`Making API call to: ${endpoint}`, this.exportConfig?.context );
274
+
275
+ const onSuccess = (response: any) => {
276
+ log.debug(`Variant entry published successfully: ${entry_uid}`, this.exportConfig?.context );
230
277
  resolve({ response, apiData: { entryUid: entry_uid, variantUid, locales: input.entry.locales }, log });
231
- const onReject = (error: any) =>
278
+ };
279
+ const onReject = (error: any) => {
280
+ log.debug(`Failed to publish variant entry: ${entry_uid}`, this.exportConfig?.context );
232
281
  reject({
233
282
  error,
234
283
  apiData: { entryUid: entry_uid, variantUid, locales: input.entry.locales },
235
284
  log,
236
285
  });
286
+ };
237
287
 
238
288
  try {
239
289
  this.apiClient.headers({ api_version: 3.2 });
@@ -260,11 +310,14 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
260
310
  res: APIResponse,
261
311
  ): Promise<VariantEntryStruct | { entries: VariantEntryStruct[]; count: number } | string | any> {
262
312
  const { status, data } = res;
313
+ log.debug(`API response status: ${status}`, this.exportConfig?.context );
263
314
 
264
315
  if (status >= 200 && status < 300) {
316
+ log.debug('API request successful', this.exportConfig?.context );
265
317
  return data;
266
318
  }
267
319
 
320
+ log.debug(`API request failed with status: ${status}`, this.exportConfig?.context );
268
321
  // Refresh the access token if the response status is 401
269
322
  await authenticationHandler.refreshAccessToken(res);
270
323
 
@@ -272,6 +325,7 @@ export class VariantHttpClient<C> extends AdapterHelper<C, HttpClient> implement
272
325
  ? formatErrors(data.errors)
273
326
  : data?.error_message || data?.message || data;
274
327
 
328
+ log.debug(`API error: ${errorMsg}`, this.exportConfig?.context );
275
329
  throw errorMsg;
276
330
  }
277
331
  }
@@ -281,17 +335,22 @@ export class VariantManagementSDK<T>
281
335
  implements VariantInterface<T, ContentstackClient>
282
336
  {
283
337
  public override apiClient!: ContentstackClient;
338
+ public exportConfig?: any;
284
339
 
285
340
  async init(): Promise<void> {
341
+ log.debug('Initializing VariantManagementSDK...', this.exportConfig?.context );
286
342
  this.apiClient = await managementSDKClient(this.config);
343
+ log.debug('VariantManagementSDK initialized successfully', this.exportConfig?.context );
287
344
  }
288
345
 
289
346
  async variantEntry(options: VariantOptions) {
347
+ log.debug('VariantEntry method called (SDK placeholder implementation)', this.exportConfig?.context );
290
348
  // TODO SDK implementation
291
349
  return { entry: {} };
292
350
  }
293
351
 
294
352
  async variantEntries(options: VariantsOption) {
353
+ log.debug('VariantEntries method called (SDK placeholder implementation)', this.exportConfig?.context );
295
354
  // TODO SDK implementation
296
355
  return { entries: [{}] };
297
356
  }
@@ -301,6 +360,7 @@ export class VariantManagementSDK<T>
301
360
  options: CreateVariantEntryOptions,
302
361
  apiParams: Record<string, any>,
303
362
  ): Promise<VariantEntryStruct | string | void> {
363
+ log.debug('CreateVariantEntry method called (SDK placeholder implementation)', this.exportConfig?.context );
304
364
  // FIXME placeholder
305
365
  return Promise.resolve({} as VariantEntryStruct);
306
366
  }
@@ -308,17 +368,23 @@ export class VariantManagementSDK<T>
308
368
  async handleVariantAPIRes(
309
369
  res: APIResponse,
310
370
  ): Promise<VariantEntryStruct | { entries: VariantEntryStruct[]; count: number } | string> {
371
+ log.debug('HandleVariantAPIRes method called (SDK implementation)', this.exportConfig?.context );
311
372
  return res.data;
312
373
  }
313
374
 
314
- constructQuery(query: Record<string, any>): string | void {}
375
+ constructQuery(query: Record<string, any>): string | void {
376
+ log.debug('ConstructQuery method called (SDK placeholder implementation)', this.exportConfig?.context );
377
+ }
315
378
 
316
- async delay(ms: number): Promise<void> {}
379
+ async delay(ms: number): Promise<void> {
380
+ log.debug(`Delay method called for ${ms}ms (SDK placeholder implementation)`, this.exportConfig?.context );
381
+ }
317
382
  }
318
383
 
319
384
  export class VariantAdapter<T> {
320
385
  protected variantInstance;
321
386
  public readonly messages: typeof messages;
387
+ public exportConfig?: any;
322
388
 
323
389
  constructor(config: ContentstackConfig & AnyProperty & AdapterType<T, ContentstackConfig>);
324
390
  constructor(config: APIConfig & AdapterType<T, APIConfig & AnyProperty>, options?: HttpClientOptions);
@@ -326,15 +392,20 @@ export class VariantAdapter<T> {
326
392
  config: APIConfig & AdapterType<T, (APIConfig & AnyProperty) | ContentstackConfig>,
327
393
  options?: HttpClientOptions,
328
394
  ) {
395
+ log.debug('Initializing VariantAdapter...', this.exportConfig?.context );
396
+
329
397
  if (config.httpClient) {
398
+ log.debug('Using HTTP client variant instance', this.exportConfig?.context );
330
399
  const { httpClient, Adapter, ...restConfig } = config;
331
400
  this.variantInstance = new Adapter(restConfig, options);
332
401
  } else {
402
+ log.debug('Using SDK variant instance', this.exportConfig?.context );
333
403
  const { Adapter, ...restConfig } = config;
334
404
  this.variantInstance = new Adapter(restConfig);
335
405
  }
336
406
 
337
407
  this.messages = messages;
408
+ log.debug('VariantAdapter initialized successfully', this.exportConfig?.context );
338
409
  }
339
410
  }
340
411