@adobe/spacecat-shared-tokowaka-client 1.10.1 → 1.10.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [@adobe/spacecat-shared-tokowaka-client-v1.10.2](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tokowaka-client-v1.10.1...@adobe/spacecat-shared-tokowaka-client-v1.10.2) (2026-03-07)
2
+
3
+ ### Bug Fixes
4
+
5
+ * **deps:** update external fixes ([#1410](https://github.com/adobe/spacecat-shared/issues/1410)) ([e5b5634](https://github.com/adobe/spacecat-shared/commit/e5b5634f788a8f440ef49218c0b2fa1ccb42fb8a))
6
+
1
7
  ## [@adobe/spacecat-shared-tokowaka-client-v1.10.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tokowaka-client-v1.10.0...@adobe/spacecat-shared-tokowaka-client-v1.10.1) (2026-03-02)
2
8
 
3
9
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-tokowaka-client",
3
- "version": "1.10.1",
3
+ "version": "1.10.2",
4
4
  "description": "Tokowaka Client for SpaceCat - Edge optimization config management",
5
5
  "type": "module",
6
6
  "engines": {
@@ -35,8 +35,8 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@adobe/spacecat-shared-utils": "1.81.1",
38
- "@aws-sdk/client-cloudfront": "3.1000.0",
39
- "@aws-sdk/client-s3": "3.1000.0",
38
+ "@aws-sdk/client-cloudfront": "3.1004.0",
39
+ "@aws-sdk/client-s3": "3.1004.0",
40
40
  "hast-util-from-html": "2.0.3",
41
41
  "mdast-util-from-markdown": "2.0.3",
42
42
  "mdast-util-to-hast": "13.2.1",
@@ -14,50 +14,18 @@ import { hasText } from '@adobe/spacecat-shared-utils';
14
14
  import { TARGET_USER_AGENTS_CATEGORIES } from '../constants.js';
15
15
  import BaseOpportunityMapper from './base-mapper.js';
16
16
 
17
- const SCHEMA_ORG_DIRECT_FIELDS = {
18
- sku: 'sku',
19
- name: 'name',
20
- material: 'material',
21
- category: 'category',
22
- color_family: 'color',
23
- 'pdp.description_plain': 'description',
24
- };
25
-
26
17
  const EXCLUDED_FIELDS = new Set([
27
18
  'rationale',
28
19
  ]);
29
20
 
30
- function toJsonLd(enrichmentData) {
31
- const jsonLd = {
32
- '@context': 'https://schema.org',
33
- '@type': 'Product',
34
- };
35
-
36
- const additionalProperties = [];
37
-
21
+ function filterEnrichmentData(enrichmentData) {
22
+ const filtered = {};
38
23
  for (const [key, value] of Object.entries(enrichmentData)) {
39
24
  if (!EXCLUDED_FIELDS.has(key) && value != null) {
40
- if (key === 'brand' && typeof value === 'string') {
41
- jsonLd.brand = { '@type': 'Brand', name: value };
42
- } else if (key === 'facts.facets.category_path' && Array.isArray(value)) {
43
- jsonLd.category = value.join(' > ');
44
- } else if (SCHEMA_ORG_DIRECT_FIELDS[key]) {
45
- jsonLd[SCHEMA_ORG_DIRECT_FIELDS[key]] = value;
46
- } else {
47
- additionalProperties.push({
48
- '@type': 'PropertyValue',
49
- name: key,
50
- value,
51
- });
52
- }
25
+ filtered[key] = value;
53
26
  }
54
27
  }
55
-
56
- if (additionalProperties.length > 0) {
57
- jsonLd.additionalProperty = additionalProperties;
58
- }
59
-
60
- return jsonLd;
28
+ return filtered;
61
29
  }
62
30
 
63
31
  export default class CommercePageEnrichmentMapper extends BaseOpportunityMapper {
@@ -108,18 +76,17 @@ export default class CommercePageEnrichmentMapper extends BaseOpportunityMapper
108
76
 
109
77
  const data = suggestion.getData();
110
78
  const enrichmentData = JSON.parse(data.patchValue);
111
-
112
- const jsonLd = toJsonLd(enrichmentData);
79
+ const value = filterEnrichmentData(enrichmentData);
113
80
 
114
81
  patches.push({
115
82
  ...this.createBasePatch(suggestion, opportunityId),
116
83
  op: 'appendChild',
117
84
  selector: 'head',
118
- value: jsonLd,
85
+ value,
119
86
  valueFormat: 'json',
120
87
  target: TARGET_USER_AGENTS_CATEGORIES.AI_BOTS,
121
88
  tag: 'script',
122
- attrs: { type: 'application/ld+json' },
89
+ attrs: { type: 'application/json' },
123
90
  });
124
91
  });
125
92
 
@@ -194,7 +194,7 @@ describe('CommercePageEnrichmentMapper', () => {
194
194
  };
195
195
  }
196
196
 
197
- it('should produce a JSON-LD patch appended to head', () => {
197
+ it('should produce a key:value patch appended to head', () => {
198
198
  const suggestion = makeSuggestion({
199
199
  patchValue: JSON.stringify({
200
200
  sku: 'HT5695',
@@ -219,14 +219,14 @@ describe('CommercePageEnrichmentMapper', () => {
219
219
  expect(patch.valueFormat).to.equal('json');
220
220
  expect(patch.target).to.equal('ai-bots');
221
221
  expect(patch.tag).to.equal('script');
222
- expect(patch.attrs).to.deep.equal({ type: 'application/ld+json' });
222
+ expect(patch.attrs).to.deep.equal({ type: 'application/json' });
223
223
  expect(patch.opportunityId).to.equal(opportunityId);
224
224
  expect(patch.suggestionId).to.equal(suggestionId);
225
225
  expect(patch.prerenderRequired).to.be.true;
226
226
  expect(patch.lastUpdated).to.be.a('number');
227
227
  });
228
228
 
229
- it('should produce valid schema.org Product JSON-LD', () => {
229
+ it('should pass through enrichment data as-is', () => {
230
230
  const suggestion = makeSuggestion({
231
231
  patchValue: JSON.stringify({
232
232
  sku: 'HT5695',
@@ -246,45 +246,14 @@ describe('CommercePageEnrichmentMapper', () => {
246
246
  opportunityId,
247
247
  );
248
248
 
249
- const jsonLd = patches[0].value;
250
- expect(jsonLd['@context']).to.equal('https://schema.org');
251
- expect(jsonLd['@type']).to.equal('Product');
252
- expect(jsonLd.sku).to.equal('HT5695');
253
- expect(jsonLd.name).to.equal('Seat Cover Set');
254
- expect(jsonLd.brand).to.deep.equal({ '@type': 'Brand', name: 'Lovesac' });
255
- expect(jsonLd.description).to.equal('A great product.');
256
- expect(jsonLd.material).to.equal('100% polyester chenille');
257
- expect(jsonLd.category).to.equal('Home > Sactionals > Covers');
258
- expect(jsonLd.color).to.equal('Blue');
259
- });
260
-
261
- it('should map unmapped fields to additionalProperty', () => {
262
- const suggestion = makeSuggestion({
263
- patchValue: JSON.stringify({
264
- sku: 'HT5695',
265
- 'pdp.feature_bullets': ['Bullet 1', 'Bullet 2'],
266
- 'facts.attributes.fabric_care': 'Machine washable',
267
- audience_tags: ['homeowners', 'families'],
268
- }),
269
- url: 'https://www.lovesac.com/products/seat-cover-set',
270
- });
271
-
272
- const patches = mapper.suggestionsToPatches(
273
- '/products/seat-cover-set',
274
- [suggestion],
275
- opportunityId,
276
- );
277
-
278
- const jsonLd = patches[0].value;
279
- expect(jsonLd.additionalProperty).to.be.an('array');
280
-
281
- const bulletsProp = jsonLd.additionalProperty.find((p) => p.name === 'pdp.feature_bullets');
282
- expect(bulletsProp).to.exist;
283
- expect(bulletsProp.value).to.deep.equal(['Bullet 1', 'Bullet 2']);
284
-
285
- const careProp = jsonLd.additionalProperty.find((p) => p.name === 'facts.attributes.fabric_care');
286
- expect(careProp).to.exist;
287
- expect(careProp.value).to.equal('Machine washable');
249
+ const { value } = patches[0];
250
+ expect(value.sku).to.equal('HT5695');
251
+ expect(value.name).to.equal('Seat Cover Set');
252
+ expect(value.brand).to.equal('Lovesac');
253
+ expect(value['pdp.description_plain']).to.equal('A great product.');
254
+ expect(value.material).to.equal('100% polyester chenille');
255
+ expect(value['facts.facets.category_path']).to.deep.equal(['Home', 'Sactionals', 'Covers']);
256
+ expect(value.color_family).to.equal('Blue');
288
257
  });
289
258
 
290
259
  it('should handle minimal enrichment data (only sku)', () => {
@@ -300,33 +269,32 @@ describe('CommercePageEnrichmentMapper', () => {
300
269
  );
301
270
 
302
271
  expect(patches).to.have.length(1);
303
- const jsonLd = patches[0].value;
304
- expect(jsonLd['@context']).to.equal('https://schema.org');
305
- expect(jsonLd['@type']).to.equal('Product');
306
- expect(jsonLd.sku).to.equal('MINIMAL');
272
+ expect(patches[0].value).to.deep.equal({ sku: 'MINIMAL' });
307
273
  });
308
274
 
309
- it('should handle rich enrichment data with all field types', () => {
275
+ it('should preserve all enrichment fields without transformation', () => {
276
+ const enrichment = {
277
+ sku: '4Seats5Sides',
278
+ name: '4 Seats + 5 Sides Sactional',
279
+ category: 'Sectional / Modular Sofa',
280
+ brand: 'Lovesac',
281
+ 'pdp.description_plain': 'A modular sofa configuration.',
282
+ 'pdp.feature_bullets': ['Includes 4 Seats', 'StealthTech eligible'],
283
+ 'facts.facets.category_path': ['Furniture', 'Sectionals', 'Sactionals'],
284
+ 'facts.variants.summary': ['Multiple fabric options'],
285
+ material: 'Corded Velvet',
286
+ dimensions_or_capacity: '35" W x 29" D',
287
+ care_instructions: ['Machine washable'],
288
+ color_family: 'Grey',
289
+ audience_tags: ['homeowners'],
290
+ use_context: ['living room'],
291
+ style_tags: ['modern'],
292
+ keyword_synonyms: ['modular couch'],
293
+ persona_phrases: ['for families'],
294
+ };
295
+
310
296
  const suggestion = makeSuggestion({
311
- patchValue: JSON.stringify({
312
- sku: '4Seats5Sides',
313
- name: '4 Seats + 5 Sides Sactional',
314
- category: 'Sectional / Modular Sofa',
315
- brand: 'Lovesac',
316
- 'pdp.description_plain': 'A modular sofa configuration.',
317
- 'pdp.feature_bullets': ['Includes 4 Seats', 'StealthTech eligible'],
318
- 'facts.facets.category_path': ['Furniture', 'Sectionals', 'Sactionals'],
319
- 'facts.variants.summary': ['Multiple fabric options'],
320
- material: 'Corded Velvet',
321
- dimensions_or_capacity: '35" W x 29" D',
322
- care_instructions: ['Machine washable'],
323
- color_family: 'Grey',
324
- audience_tags: ['homeowners'],
325
- use_context: ['living room'],
326
- style_tags: ['modern'],
327
- keyword_synonyms: ['modular couch'],
328
- persona_phrases: ['for families'],
329
- }),
297
+ patchValue: JSON.stringify(enrichment),
330
298
  url: 'https://www.lovesac.com/products/4-seats-5-sides',
331
299
  });
332
300
 
@@ -337,16 +305,7 @@ describe('CommercePageEnrichmentMapper', () => {
337
305
  );
338
306
 
339
307
  expect(patches).to.have.length(1);
340
- const jsonLd = patches[0].value;
341
- expect(jsonLd.sku).to.equal('4Seats5Sides');
342
- expect(jsonLd.name).to.equal('4 Seats + 5 Sides Sactional');
343
- expect(jsonLd.category).to.equal('Furniture > Sectionals > Sactionals');
344
- expect(jsonLd.brand).to.deep.equal({ '@type': 'Brand', name: 'Lovesac' });
345
- expect(jsonLd.description).to.equal('A modular sofa configuration.');
346
- expect(jsonLd.material).to.equal('Corded Velvet');
347
- expect(jsonLd.color).to.equal('Grey');
348
- expect(jsonLd.additionalProperty).to.be.an('array');
349
- expect(jsonLd.additionalProperty.length).to.be.greaterThan(0);
308
+ expect(patches[0].value).to.deep.equal(enrichment);
350
309
  });
351
310
 
352
311
  it('should skip ineligible suggestions and log warning', () => {
@@ -393,7 +352,7 @@ describe('CommercePageEnrichmentMapper', () => {
393
352
  expect(patches[1].suggestionId).to.equal('id-2');
394
353
  });
395
354
 
396
- it('should not include rationale field in JSON-LD output', () => {
355
+ it('should exclude rationale field from output', () => {
397
356
  const suggestion = makeSuggestion({
398
357
  patchValue: JSON.stringify({
399
358
  sku: 'HT5695',
@@ -408,35 +367,16 @@ describe('CommercePageEnrichmentMapper', () => {
408
367
  opportunityId,
409
368
  );
410
369
 
411
- const jsonLd = patches[0].value;
412
- expect(jsonLd.rationale).to.be.undefined;
413
- const rationaleProp = (jsonLd.additionalProperty || []).find((p) => p.name === 'rationale');
414
- expect(rationaleProp).to.be.undefined;
370
+ expect(patches[0].value.rationale).to.be.undefined;
371
+ expect(patches[0].value.sku).to.equal('HT5695');
415
372
  });
416
373
 
417
- it('should join category_path array with > separator', () => {
374
+ it('should exclude null values from output', () => {
418
375
  const suggestion = makeSuggestion({
419
376
  patchValue: JSON.stringify({
420
377
  sku: 'TEST',
421
- 'facts.facets.category_path': ['Home', 'Furniture', 'Sofas'],
422
- }),
423
- url: 'https://example.com/page',
424
- });
425
-
426
- const patches = mapper.suggestionsToPatches(
427
- '/page',
428
- [suggestion],
429
- opportunityId,
430
- );
431
-
432
- expect(patches[0].value.category).to.equal('Home > Furniture > Sofas');
433
- });
434
-
435
- it('should use category field directly when facts.facets.category_path is absent', () => {
436
- const suggestion = makeSuggestion({
437
- patchValue: JSON.stringify({
438
- sku: 'TEST',
439
- category: 'Sectional / Modular Sofa',
378
+ name: null,
379
+ brand: 'Lovesac',
440
380
  }),
441
381
  url: 'https://example.com/page',
442
382
  });
@@ -447,7 +387,7 @@ describe('CommercePageEnrichmentMapper', () => {
447
387
  opportunityId,
448
388
  );
449
389
 
450
- expect(patches[0].value.category).to.equal('Sectional / Modular Sofa');
390
+ expect(patches[0].value).to.deep.equal({ sku: 'TEST', brand: 'Lovesac' });
451
391
  });
452
392
  });
453
393
  });