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

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.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tokowaka-client-v1.11.0...@adobe/spacecat-shared-tokowaka-client-v1.11.1) (2026-03-10)
2
+
3
+ ### Bug Fixes
4
+
5
+ * UA change for edge optimize status api ([#1418](https://github.com/adobe/spacecat-shared/issues/1418)) ([43b14b5](https://github.com/adobe/spacecat-shared/commit/43b14b5ae26346fef73bbe501dee0ed0b08874e8))
6
+
7
+ ## [@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)
8
+
9
+ ### Features
10
+
11
+ * **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))
12
+
1
13
  ## [@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
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.10.2",
3
+ "version": "1.11.1",
4
4
  "description": "Tokowaka Client for SpaceCat - Edge optimization config management",
5
5
  "type": "module",
6
6
  "engines": {
package/src/index.js CHANGED
@@ -1135,7 +1135,7 @@ class TokowakaClient {
1135
1135
  const response = await tracingFetch(targetUrl, {
1136
1136
  method: 'GET',
1137
1137
  headers: {
1138
- 'User-Agent': 'Tokowaka-AI Tokowaka/1.0 AdobeEdgeOptimize-AI AdobeEdgeOptimize/1.0',
1138
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Tokowaka-AI Tokowaka/1.0 AdobeEdgeOptimize-AI AdobeEdgeOptimize/1.0',
1139
1139
  'fastly-debug': '1',
1140
1140
  },
1141
1141
  timeout: REQUEST_TIMEOUT_MS,
@@ -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: (data.format === 'hast' || data.format === 'json') ? JSON.parse(data.patchValue) : data.patchValue,
61
- valueFormat: data.format || 'text',
71
+ value,
72
+ valueFormat,
62
73
  target: TARGET_USER_AGENTS_CATEGORIES.AI_BOTS,
63
74
  };
64
75
 
@@ -3932,7 +3932,9 @@ describe('TokowakaClient', () => {
3932
3932
  await esmockClient.checkEdgeOptimizeStatus(site, '/');
3933
3933
 
3934
3934
  const fetchOptions = tracingFetchStub.firstCall.args[1];
3935
- expect(fetchOptions.headers['User-Agent']).to.equal('Tokowaka-AI Tokowaka/1.0 AdobeEdgeOptimize-AI AdobeEdgeOptimize/1.0');
3935
+ const userAgent = fetchOptions.headers['User-Agent'];
3936
+ expect(userAgent).to.include('Tokowaka-AI Tokowaka/1.0 AdobeEdgeOptimize-AI AdobeEdgeOptimize/1.0');
3937
+ expect(userAgent).to.include('Mozilla/5.0');
3936
3938
  });
3937
3939
 
3938
3940
  it('should pass timeout option to tracingFetch', async () => {
@@ -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',