@nuskin/contentstack-lib 2.1.0-pa-1117.7 → 2.1.0-pa-1117.9

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/README.md CHANGED
@@ -11,13 +11,13 @@ FOR COMMON SPANISH AND MX-es FOR EXAMPLE.
11
11
 
12
12
  ## Installing
13
13
 
14
- Usng npm:
14
+ Using npm:
15
15
 
16
16
  ```bash
17
17
  npm install @nuskin/contentstack-lib
18
18
  ```
19
19
 
20
- Usng yarn:
20
+ Using yarn:
21
21
 
22
22
  ```bash
23
23
  yarn add @nuskin/contentstack-lib
@@ -28,8 +28,9 @@ yarn add @nuskin/contentstack-lib
28
28
  ```js
29
29
  const { getStack } = require('@nuskin/contentstack-lib')
30
30
 
31
- // Call getStack to get the stack object
32
- const Stack = getStack()
31
+ // Pass an environment explicitly outside the browser.
32
+ // In the browser, getStack() can infer the env from the hostname.
33
+ const Stack = getStack('prod')
33
34
 
34
35
  // get all languages
35
36
  const languages = await Stack.ContentType('supported_language').Query().toJSON().find();
@@ -37,16 +38,6 @@ const languages = await Stack.ContentType('supported_language').Query().toJSON()
37
38
  // get all markets
38
39
  const markets = await Stack.ContentType('market').Query().toJSON().find();
39
40
 
40
- // Use the extended getStrings function to get translations
41
- // ==================== Deprecated - Dont use this function ==========================
42
- const translations = Stack.getStrings({
43
- contentTypes: ['checkout_adr_strings', 'checkout_cart_strings'], // List of content types you want to get translations for
44
- language: 'en',
45
- country: 'US',
46
- merge: true // Will combine checkout_adr_strings and checkout_cart_strings object with single list of strings
47
- });
48
-
49
- // Use this function instead to get your translations
50
41
  // The entries are returned in the order they were requested so you can destructure the array accordingly
51
42
  // To get the result in camelcase instead of snake case you can pass in the option.camelcase: true
52
43
  // Contentstack does not merge common english strings with en_US strings. This function allows you to merge the two with mergeWithFallback: true
@@ -76,10 +67,13 @@ const addressForms = await Stack.getAddressForms(['United States']);
76
67
  // field: 'address1',
77
68
  // width: 'full',
78
69
  // editable: true,
79
- // max_length: 40
70
+ // max_length: 40,
71
+ // required: true
80
72
  // }
81
73
  // ],
82
- // postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$'
74
+ // postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$',
75
+ // verify_after_autocomplete: true,
76
+ // wrap_address1_to_address2: false
83
77
  // }
84
78
  // ]
85
79
 
@@ -87,8 +81,54 @@ const addressForms = await Stack.getAddressForms(['United States']);
87
81
  const camelizedAddressForms = await Stack.getAddressForms(['United States'], true);
88
82
 
89
83
  // Get shipping address forms with referenced address form fields expanded.
90
- // The second parameter works the same way here.
84
+ // countries is normalized to a list of { code, name } objects.
91
85
  const shippingAddressForms = await Stack.getShippingAddressForms(['United States']);
86
+
87
+ // Example result:
88
+ // [
89
+ // {
90
+ // countries: [
91
+ // {
92
+ // code: 'US',
93
+ // name: 'United States'
94
+ // }
95
+ // ],
96
+ // pre_address_fields: [
97
+ // {
98
+ // field: 'givenName',
99
+ // width: 'half',
100
+ // editable: true,
101
+ // max_length: 30,
102
+ // required: true
103
+ // }
104
+ // ],
105
+ // address_form: {
106
+ // address_elements: [
107
+ // {
108
+ // field: 'address1',
109
+ // width: 'full',
110
+ // editable: true,
111
+ // max_length: 40,
112
+ // required: true
113
+ // }
114
+ // ],
115
+ // postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$',
116
+ // verify_after_autocomplete: true,
117
+ // wrap_address1_to_address2: false
118
+ // },
119
+ // post_address_fields: [
120
+ // {
121
+ // field: 'mobilePhone',
122
+ // width: 'full',
123
+ // editable: true,
124
+ // max_length: 20,
125
+ // required: true
126
+ // }
127
+ // ]
128
+ // }
129
+ // ]
130
+
131
+ // Pass true as the second parameter to camelCase the returned keys.
92
132
  const camelizedShippingAddressForms = await Stack.getShippingAddressForms(['United States'], true);
93
133
 
94
134
  // We could possibly add functionality to return the list of regions markets and languages in a single object structure
@@ -86,14 +86,18 @@ const addressFormFieldEntries = [
86
86
  width: 'full',
87
87
  editable: true,
88
88
  max_length: '40',
89
- required: true
89
+ required: true,
90
+ api_mappings: ['address1'],
91
+ autocomplete_token: 'address-line1'
90
92
  },
91
93
  {
92
94
  field: 'postalCode',
93
95
  width: 'half',
94
96
  editable: false,
95
97
  max_length: '10',
96
- required: false
98
+ required: false,
99
+ api_mappings: ['postalCode'],
100
+ validation_message: 'Invalid postal code'
97
101
  }
98
102
  ];
99
103
 
@@ -171,14 +175,18 @@ describe("ContentstackApi", () => {
171
175
  width: 'full',
172
176
  editable: true,
173
177
  max_length: 40,
174
- required: true
178
+ required: true,
179
+ api_mappings: ['address1'],
180
+ autocomplete_token: 'address-line1'
175
181
  },
176
182
  {
177
183
  field: 'postalCode',
178
184
  width: 'half',
179
185
  editable: false,
180
186
  max_length: 10,
181
- required: false
187
+ required: false,
188
+ api_mappings: ['postalCode'],
189
+ validation_message: 'Invalid postal code'
182
190
  }
183
191
  ]);
184
192
  });
@@ -192,14 +200,18 @@ describe("ContentstackApi", () => {
192
200
  width: 'full',
193
201
  editable: true,
194
202
  maxLength: 40,
195
- required: true
203
+ required: true,
204
+ apiMappings: ['address1'],
205
+ autocompleteToken: 'address-line1'
196
206
  },
197
207
  {
198
208
  field: 'postalCode',
199
209
  width: 'half',
200
210
  editable: false,
201
211
  maxLength: 10,
202
- required: false
212
+ required: false,
213
+ apiMappings: ['postalCode'],
214
+ validationMessage: 'Invalid postal code'
203
215
  }
204
216
  ]);
205
217
  });
@@ -217,7 +229,8 @@ describe("ContentstackApi", () => {
217
229
  address_elements: addressFormFieldEntries,
218
230
  postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$',
219
231
  verify_after_autocomplete: true,
220
- wrap_address1_to_address2: false
232
+ wrap_address1_to_address2: false,
233
+ allowed_countries: ['US', 'CA']
221
234
  }
222
235
  ]]);
223
236
  const {getStack} = require('../src/api');
@@ -230,19 +243,24 @@ describe("ContentstackApi", () => {
230
243
  width: 'full',
231
244
  editable: true,
232
245
  max_length: 40,
233
- required: true
246
+ required: true,
247
+ api_mappings: ['address1'],
248
+ autocomplete_token: 'address-line1'
234
249
  },
235
250
  {
236
251
  field: 'postalCode',
237
252
  width: 'half',
238
253
  editable: false,
239
254
  max_length: 10,
240
- required: false
255
+ required: false,
256
+ api_mappings: ['postalCode'],
257
+ validation_message: 'Invalid postal code'
241
258
  }
242
259
  ],
243
260
  postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$',
244
261
  verify_after_autocomplete: true,
245
- wrap_address1_to_address2: false
262
+ wrap_address1_to_address2: false,
263
+ allowed_countries: ['US', 'CA']
246
264
  }
247
265
  ]);
248
266
  });
@@ -253,7 +271,8 @@ describe("ContentstackApi", () => {
253
271
  address_elements: addressFormFieldEntries,
254
272
  postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$',
255
273
  verify_after_autocomplete: true,
256
- wrap_address1_to_address2: false
274
+ wrap_address1_to_address2: false,
275
+ allowed_countries: ['US', 'CA']
257
276
  }
258
277
  ]]);
259
278
  const {getStack} = require('../src/api');
@@ -266,19 +285,24 @@ describe("ContentstackApi", () => {
266
285
  width: 'full',
267
286
  editable: true,
268
287
  maxLength: 40,
269
- required: true
288
+ required: true,
289
+ apiMappings: ['address1'],
290
+ autocompleteToken: 'address-line1'
270
291
  },
271
292
  {
272
293
  field: 'postalCode',
273
294
  width: 'half',
274
295
  editable: false,
275
296
  maxLength: 10,
276
- required: false
297
+ required: false,
298
+ apiMappings: ['postalCode'],
299
+ validationMessage: 'Invalid postal code'
277
300
  }
278
301
  ],
279
302
  postalCodeRegex: '^[0-9]{5}(?:-[0-9]{4})?$',
280
303
  verifyAfterAutocomplete: true,
281
- wrapAddress1ToAddress2: false
304
+ wrapAddress1ToAddress2: false,
305
+ allowedCountries: ['US', 'CA']
282
306
  }
283
307
  ]);
284
308
  });
@@ -323,10 +347,12 @@ describe("ContentstackApi", () => {
323
347
  address_elements: addressFormFieldEntries,
324
348
  postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$',
325
349
  verify_after_autocomplete: true,
326
- wrap_address1_to_address2: false
350
+ wrap_address1_to_address2: false,
351
+ allowed_countries: ['US', 'CA']
327
352
  }
328
353
  ],
329
- post_address_fields: [addressFormFieldEntries[1]]
354
+ post_address_fields: [addressFormFieldEntries[1]],
355
+ display_name: 'North America'
330
356
  }
331
357
  ]]);
332
358
  const {getStack} = require('../src/api');
@@ -349,7 +375,9 @@ describe("ContentstackApi", () => {
349
375
  width: 'full',
350
376
  editable: true,
351
377
  max_length: 40,
352
- required: true
378
+ required: true,
379
+ api_mappings: ['address1'],
380
+ autocomplete_token: 'address-line1'
353
381
  }
354
382
  ],
355
383
  address_form: {
@@ -359,19 +387,24 @@ describe("ContentstackApi", () => {
359
387
  width: 'full',
360
388
  editable: true,
361
389
  max_length: 40,
362
- required: true
390
+ required: true,
391
+ api_mappings: ['address1'],
392
+ autocomplete_token: 'address-line1'
363
393
  },
364
394
  {
365
395
  field: 'postalCode',
366
396
  width: 'half',
367
397
  editable: false,
368
398
  max_length: 10,
369
- required: false
399
+ required: false,
400
+ api_mappings: ['postalCode'],
401
+ validation_message: 'Invalid postal code'
370
402
  }
371
403
  ],
372
404
  postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$',
373
405
  verify_after_autocomplete: true,
374
- wrap_address1_to_address2: false
406
+ wrap_address1_to_address2: false,
407
+ allowed_countries: ['US', 'CA']
375
408
  },
376
409
  post_address_fields: [
377
410
  {
@@ -379,9 +412,12 @@ describe("ContentstackApi", () => {
379
412
  width: 'half',
380
413
  editable: false,
381
414
  max_length: 10,
382
- required: false
415
+ required: false,
416
+ api_mappings: ['postalCode'],
417
+ validation_message: 'Invalid postal code'
383
418
  }
384
- ]
419
+ ],
420
+ display_name: 'North America'
385
421
  }
386
422
  ]);
387
423
  });
@@ -411,10 +447,12 @@ describe("ContentstackApi", () => {
411
447
  address_elements: addressFormFieldEntries,
412
448
  postal_code_regex: '^[0-9]{5}(?:-[0-9]{4})?$',
413
449
  verify_after_autocomplete: true,
414
- wrap_address1_to_address2: false
450
+ wrap_address1_to_address2: false,
451
+ allowed_countries: ['US', 'CA']
415
452
  }
416
453
  ],
417
- post_address_fields: [addressFormFieldEntries[1]]
454
+ post_address_fields: [addressFormFieldEntries[1]],
455
+ display_name: 'North America'
418
456
  }
419
457
  ]]);
420
458
  const {getStack} = require('../src/api');
@@ -437,7 +475,9 @@ describe("ContentstackApi", () => {
437
475
  width: 'full',
438
476
  editable: true,
439
477
  maxLength: 40,
440
- required: true
478
+ required: true,
479
+ apiMappings: ['address1'],
480
+ autocompleteToken: 'address-line1'
441
481
  }
442
482
  ],
443
483
  addressForm: {
@@ -447,19 +487,24 @@ describe("ContentstackApi", () => {
447
487
  width: 'full',
448
488
  editable: true,
449
489
  maxLength: 40,
450
- required: true
490
+ required: true,
491
+ apiMappings: ['address1'],
492
+ autocompleteToken: 'address-line1'
451
493
  },
452
494
  {
453
495
  field: 'postalCode',
454
496
  width: 'half',
455
497
  editable: false,
456
498
  maxLength: 10,
457
- required: false
499
+ required: false,
500
+ apiMappings: ['postalCode'],
501
+ validationMessage: 'Invalid postal code'
458
502
  }
459
503
  ],
460
504
  postalCodeRegex: '^[0-9]{5}(?:-[0-9]{4})?$',
461
505
  verifyAfterAutocomplete: true,
462
- wrapAddress1ToAddress2: false
506
+ wrapAddress1ToAddress2: false,
507
+ allowedCountries: ['US', 'CA']
463
508
  },
464
509
  postAddressFields: [
465
510
  {
@@ -467,9 +512,12 @@ describe("ContentstackApi", () => {
467
512
  width: 'half',
468
513
  editable: false,
469
514
  maxLength: 10,
470
- required: false
515
+ required: false,
516
+ apiMappings: ['postalCode'],
517
+ validationMessage: 'Invalid postal code'
471
518
  }
472
- ]
519
+ ],
520
+ displayName: 'North America'
473
521
  }
474
522
  ]);
475
523
  });
package/docs/CHANGELOG.md CHANGED
@@ -1 +1 @@
1
- # [2.1.0-pa-1117.7](https://code.tls.nuskin.io/ns-am/utility/npm/contentstack-lib/compare/v2.1.0-pa-1117.6...v2.1.0-pa-1117.7) (2026-04-08)
1
+ # [2.1.0-pa-1117.9](https://code.tls.nuskin.io/ns-am/utility/npm/contentstack-lib/compare/v2.1.0-pa-1117.8...v2.1.0-pa-1117.9) (2026-05-18)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/contentstack-lib",
3
- "version": "2.1.0-pa-1117.7",
3
+ "version": "2.1.0-pa-1117.9",
4
4
  "description": "This project contains configuration and api code to access Contentstack, to be shared between the backend (AWS Lambda) and frontend (Vue, etc).",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/api.js CHANGED
@@ -22,6 +22,22 @@ const COMMON_LANGUAGES = {
22
22
  'tr': 'tr-tr'
23
23
  };
24
24
 
25
+ const CONTENTSTACK_SYSTEM_FIELDS = new Set([
26
+ '_content_type_uid',
27
+ 'uid',
28
+ 'title',
29
+ 'tags',
30
+ 'locale',
31
+ 'created_by',
32
+ 'updated_by',
33
+ 'created_at',
34
+ 'updated_at',
35
+ 'ACL',
36
+ '_version',
37
+ '_in_progress',
38
+ 'publish_details'
39
+ ]);
40
+
25
41
  /**
26
42
  * Gets the correct contentstack config settings
27
43
  * @param {string} env
@@ -195,6 +211,18 @@ const _getMultiEntries = async (contentType, includeRefs, values) => {
195
211
  }
196
212
  }
197
213
 
214
+ /**
215
+ * Removes Contentstack-managed metadata fields while preserving custom content fields.
216
+ * @param {Object} entry
217
+ * @return {Object}
218
+ * @private
219
+ */
220
+ const _omitContentstackSystemFields = (entry = {}) => {
221
+ return Object.fromEntries(
222
+ Object.entries(entry).filter(([key]) => !CONTENTSTACK_SYSTEM_FIELDS.has(key))
223
+ );
224
+ }
225
+
198
226
  /**
199
227
  * Maps address form field entries into a small normalized dataset.
200
228
  * @param {Object[]} addressFormFields
@@ -202,13 +230,15 @@ const _getMultiEntries = async (contentType, includeRefs, values) => {
202
230
  * @private
203
231
  */
204
232
  const _extractAddressFormFields = (addressFormFields = [], camelcase = false) => {
205
- const mappedFields = addressFormFields.map(({field, width, editable, max_length, required}) => ({
206
- field,
207
- width,
208
- editable,
209
- max_length: Number(max_length),
210
- required
211
- }));
233
+ const mappedFields = addressFormFields.map((addressFormField) => {
234
+ const mappedField = _omitContentstackSystemFields(addressFormField);
235
+
236
+ if (mappedField.max_length !== undefined && mappedField.max_length !== null) {
237
+ mappedField.max_length = Number(mappedField.max_length);
238
+ }
239
+
240
+ return mappedField;
241
+ });
212
242
 
213
243
  return camelcase ? _snakeObjectToCamel(mappedFields) : mappedFields;
214
244
  }
@@ -218,12 +248,8 @@ const _extractAddressForm = (addressForm, camelcase = false) => {
218
248
  return addressForm;
219
249
  }
220
250
 
221
- const mappedForm = {
222
- address_elements: _extractAddressFormFields(addressForm.address_elements, camelcase),
223
- postal_code_regex: addressForm.postal_code_regex,
224
- verify_after_autocomplete: addressForm.verify_after_autocomplete,
225
- wrap_address1_to_address2: addressForm.wrap_address1_to_address2
226
- };
251
+ const mappedForm = _omitContentstackSystemFields(addressForm);
252
+ mappedForm.address_elements = _extractAddressFormFields(addressForm.address_elements, camelcase);
227
253
 
228
254
  return camelcase ? _snakeObjectToCamel(mappedForm) : mappedForm;
229
255
  }
@@ -237,24 +263,26 @@ const _extractShippingCountries = (countries = []) => {
237
263
  }));
238
264
  }
239
265
 
240
- const getShippingAddressForms = async (countries, camelcase = false) => {
266
+ const getShippingAddressForms = async (forms, camelcase = false) => {
241
267
  const results = await _getMultiEntries(
242
268
  'shipping_address_form',
243
269
  ['countries', 'pre_address_fields', 'address_form', 'address_form.address_elements', 'post_address_fields'],
244
- countries
270
+ forms
245
271
  );
246
- const mappedResults = (results || []).map((result) => ({
247
- countries: _extractShippingCountries(result.countries),
248
- pre_address_fields: _extractAddressFormFields(result.pre_address_fields, camelcase),
249
- address_form: _extractAddressForm(result.address_form[0], camelcase),
250
- post_address_fields: _extractAddressFormFields(result.post_address_fields, camelcase)
251
- }));
272
+ const mappedResults = (results || []).map((result) => {
273
+ const mappedResult = _omitContentstackSystemFields(result);
274
+ mappedResult.countries = _extractShippingCountries(result.countries);
275
+ mappedResult.pre_address_fields = _extractAddressFormFields(result.pre_address_fields, camelcase);
276
+ mappedResult.address_form = _extractAddressForm(result.address_form[0], camelcase);
277
+ mappedResult.post_address_fields = _extractAddressFormFields(result.post_address_fields, camelcase);
278
+ return mappedResult;
279
+ });
252
280
 
253
281
  return camelcase ? _snakeObjectToCamel(mappedResults) : mappedResults;
254
282
  }
255
283
 
256
- const getAddressForms = async (countries, camelcase = false) => {
257
- const results = await _getMultiEntries('address_form', 'address_elements', countries);
284
+ const getAddressForms = async (forms, camelcase = false) => {
285
+ const results = await _getMultiEntries('address_form', 'address_elements', forms);
258
286
  const mappedResults = (results || []).map((result) => _extractAddressForm(result, camelcase));
259
287
 
260
288
  return camelcase ? _snakeObjectToCamel(mappedResults) : mappedResults;