@adobe/spacecat-shared-tokowaka-client 1.10.1 → 1.11.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.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [@adobe/spacecat-shared-tokowaka-client-v1.11.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tokowaka-client-v1.10.2...@adobe/spacecat-shared-tokowaka-client-v1.11.0) (2026-03-10)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **tokowaka-client:** add HTML-to-HAST converter to generic mapper ([#1416](https://github.com/adobe/spacecat-shared/issues/1416)) ([510ce3b](https://github.com/adobe/spacecat-shared/commit/510ce3b267d0b68011b677e8e493a56aaaeebb87))
|
|
6
|
+
|
|
7
|
+
## [@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)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **deps:** update external fixes ([#1410](https://github.com/adobe/spacecat-shared/issues/1410)) ([e5b5634](https://github.com/adobe/spacecat-shared/commit/e5b5634f788a8f440ef49218c0b2fa1ccb42fb8a))
|
|
12
|
+
|
|
1
13
|
## [@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
14
|
|
|
3
15
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/spacecat-shared-tokowaka-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
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.
|
|
39
|
-
"@aws-sdk/client-s3": "3.
|
|
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
|
|
31
|
-
const
|
|
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
|
-
|
|
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
|
|
85
|
+
value,
|
|
119
86
|
valueFormat: 'json',
|
|
120
87
|
target: TARGET_USER_AGENTS_CATEGORIES.AI_BOTS,
|
|
121
88
|
tag: 'script',
|
|
122
|
-
attrs: { type: 'application/
|
|
89
|
+
attrs: { type: 'application/json' },
|
|
123
90
|
});
|
|
124
91
|
});
|
|
125
92
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { hasText } from '@adobe/spacecat-shared-utils';
|
|
14
14
|
import { TARGET_USER_AGENTS_CATEGORIES } from '../constants.js';
|
|
15
|
+
import { htmlToHast } from '../utils/html-utils.js';
|
|
15
16
|
import BaseOpportunityMapper from './base-mapper.js';
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -33,6 +34,13 @@ export default class GenericMapper extends BaseOpportunityMapper {
|
|
|
33
34
|
return this.prerenderRequired;
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
// eslint-disable-next-line class-methods-use-this
|
|
38
|
+
#resolveValue(data) {
|
|
39
|
+
if (data.format === 'html') return htmlToHast(data.patchValue);
|
|
40
|
+
if (data.format === 'hast' || data.format === 'json') return JSON.parse(data.patchValue);
|
|
41
|
+
return data.patchValue;
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
/**
|
|
37
45
|
* Converts suggestions to Tokowaka patches
|
|
38
46
|
* @param {string} urlPath - URL path for the suggestions
|
|
@@ -53,12 +61,15 @@ export default class GenericMapper extends BaseOpportunityMapper {
|
|
|
53
61
|
const data = suggestion.getData();
|
|
54
62
|
const { transformRules } = data;
|
|
55
63
|
|
|
64
|
+
const value = this.#resolveValue(data);
|
|
65
|
+
const valueFormat = data.format === 'html' ? 'hast' : (data.format || 'text');
|
|
66
|
+
|
|
56
67
|
const patch = {
|
|
57
68
|
...this.createBasePatch(suggestion, opportunityId),
|
|
58
69
|
op: transformRules.action,
|
|
59
70
|
selector: transformRules.selector,
|
|
60
|
-
value
|
|
61
|
-
valueFormat
|
|
71
|
+
value,
|
|
72
|
+
valueFormat,
|
|
62
73
|
target: TARGET_USER_AGENTS_CATEGORIES.AI_BOTS,
|
|
63
74
|
};
|
|
64
75
|
|
|
@@ -194,7 +194,7 @@ describe('CommercePageEnrichmentMapper', () => {
|
|
|
194
194
|
};
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
it('should produce a
|
|
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/
|
|
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
|
|
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
|
|
250
|
-
expect(
|
|
251
|
-
expect(
|
|
252
|
-
expect(
|
|
253
|
-
expect(
|
|
254
|
-
expect(
|
|
255
|
-
expect(
|
|
256
|
-
expect(
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
412
|
-
expect(
|
|
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
|
|
374
|
+
it('should exclude null values from output', () => {
|
|
418
375
|
const suggestion = makeSuggestion({
|
|
419
376
|
patchValue: JSON.stringify({
|
|
420
377
|
sku: 'TEST',
|
|
421
|
-
|
|
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
|
|
390
|
+
expect(patches[0].value).to.deep.equal({ sku: 'TEST', brand: 'Lovesac' });
|
|
451
391
|
});
|
|
452
392
|
});
|
|
453
393
|
});
|
|
@@ -12,9 +12,18 @@
|
|
|
12
12
|
|
|
13
13
|
/* eslint-env mocha */
|
|
14
14
|
|
|
15
|
+
import { readFileSync } from 'fs';
|
|
16
|
+
import { dirname, join } from 'path';
|
|
17
|
+
import { fileURLToPath } from 'url';
|
|
15
18
|
import { expect } from 'chai';
|
|
16
19
|
import GenericMapper from '../../src/mappers/generic-mapper.js';
|
|
17
20
|
|
|
21
|
+
const filename = fileURLToPath(import.meta.url);
|
|
22
|
+
const fixturesPath = join(dirname(filename), '../fixtures/semantic-value-visibility');
|
|
23
|
+
const carahsoftFixture = JSON.parse(
|
|
24
|
+
readFileSync(join(fixturesPath, 'Carahsoft.json'), 'utf8'),
|
|
25
|
+
);
|
|
26
|
+
|
|
18
27
|
describe('GenericMapper', () => {
|
|
19
28
|
let mapper;
|
|
20
29
|
let log;
|
|
@@ -768,6 +777,62 @@ describe('GenericMapper', () => {
|
|
|
768
777
|
expect(patch.attrs).to.be.undefined;
|
|
769
778
|
});
|
|
770
779
|
|
|
780
|
+
it('should convert HTML patchValue to HAST when format is html', () => {
|
|
781
|
+
const suggestion = {
|
|
782
|
+
getId: () => 'sugg-html',
|
|
783
|
+
getUpdatedAt: () => '2025-01-15T10:00:00.000Z',
|
|
784
|
+
getData: () => ({
|
|
785
|
+
transformRules: {
|
|
786
|
+
action: 'insertAfter',
|
|
787
|
+
selector: 'img[src="test.jpg"]',
|
|
788
|
+
},
|
|
789
|
+
patchValue: '<section data-llm-context="image"><h2>Title</h2><p>Description</p></section>',
|
|
790
|
+
format: 'html',
|
|
791
|
+
url: 'https://example.com/page',
|
|
792
|
+
}),
|
|
793
|
+
};
|
|
794
|
+
|
|
795
|
+
const patches = mapper.suggestionsToPatches('/page', [suggestion], 'opp-html');
|
|
796
|
+
|
|
797
|
+
expect(patches.length).to.equal(1);
|
|
798
|
+
const patch = patches[0];
|
|
799
|
+
|
|
800
|
+
expect(patch.valueFormat).to.equal('hast');
|
|
801
|
+
expect(patch.value).to.be.an('object');
|
|
802
|
+
expect(patch.value.type).to.equal('root');
|
|
803
|
+
const section = patch.value.children.find((c) => c.tagName === 'section');
|
|
804
|
+
expect(section).to.exist;
|
|
805
|
+
expect(section.properties.dataLlmContext).to.equal('image');
|
|
806
|
+
const h2 = section.children.find((c) => c.tagName === 'h2');
|
|
807
|
+
expect(h2).to.exist;
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
it('should convert HTML to HAST using real fixture data', () => {
|
|
811
|
+
const fixtureData = carahsoftFixture.suggestions[0].data;
|
|
812
|
+
const suggestion = {
|
|
813
|
+
getId: () => 'sugg-fixture',
|
|
814
|
+
getUpdatedAt: () => '2025-01-15T10:00:00.000Z',
|
|
815
|
+
getData: () => ({
|
|
816
|
+
transformRules: fixtureData.transformRules,
|
|
817
|
+
patchValue: fixtureData.semanticHtml,
|
|
818
|
+
format: 'html',
|
|
819
|
+
url: carahsoftFixture.url,
|
|
820
|
+
}),
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
const patches = mapper.suggestionsToPatches('/', [suggestion], 'opp-fixture');
|
|
824
|
+
|
|
825
|
+
expect(patches.length).to.equal(1);
|
|
826
|
+
const patch = patches[0];
|
|
827
|
+
|
|
828
|
+
expect(patch.valueFormat).to.equal('hast');
|
|
829
|
+
expect(patch.value.type).to.equal('root');
|
|
830
|
+
const section = patch.value.children.find((c) => c.tagName === 'section');
|
|
831
|
+
expect(section).to.exist;
|
|
832
|
+
expect(section.properties.dataLlmContext).to.equal('image');
|
|
833
|
+
expect(section.properties.dataLlmShadow).to.equal('image-text');
|
|
834
|
+
});
|
|
835
|
+
|
|
771
836
|
it('should not include UI-only fields in patch', () => {
|
|
772
837
|
const suggestion = {
|
|
773
838
|
getId: () => 'sugg-ui',
|