From 3feda947482009dd6c71d9e8e0d825be123ee793 Mon Sep 17 00:00:00 2001 From: alexp mule Date: Tue, 18 Aug 2026 17:11:23 -0300 Subject: [PATCH 1/6] feat(query): add QUERY method color badge (OAS 3.2) OAS 3.2 introduces the QUERY HTTP method, which the archived http-method-label package does not map, so QUERY operations rendered in the default gray, indistinguishable from unmapped verbs. Add a local color override for the QUERY method label. ApiUrl upper-cases the method for display and lower-cases it for the color hook, so the badge shows QUERY while data-method is 'query'; the rule keys on both casings. Teal (#0f9d9d) is read-safe and does not collide with the PATCH purple. W-23748890 --- src/Styles.js | 9 +++++++++ test/api-url.test.js | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/Styles.js b/src/Styles.js index e92f6ad..144eaee 100644 --- a/src/Styles.js +++ b/src/Styles.js @@ -190,6 +190,15 @@ arc-marked { min-width: var(--api-method-documentation-http-method-label-min-width, inherit); } +.method-label[data-method='query'], +.method-label[data-method='QUERY'] { + background-color: var( + --http-method-label-query-background-color, + rgba(15, 157, 157, 0.12) + ); + color: var(--http-method-label-query-color, #0f9d9d); +} + .bottom-nav, .bottom-link { display: flex; diff --git a/test/api-url.test.js b/test/api-url.test.js index ccb9fa3..6784d09 100644 --- a/test/api-url.test.js +++ b/test/api-url.test.js @@ -184,4 +184,44 @@ describe('', () => { }); }); }); + + describe('QUERY method (OAS 3.2)', () => { + // OAS 3.2 adds the QUERY HTTP method. `_computeMethod` upper-cases the raw + // AMF value for display ("QUERY"), and `_getMethodTemplate` lower-cases it + // for the color hook (`data-method="query"`). The color override keys on + // both casings. Inline expanded operation (no `@context`) keeps this + // independent of the model generator. + const METHOD = 'http://a.ml/vocabularies/apiContract#method'; + const OPERATION_T = 'http://a.ml/vocabularies/apiContract#Operation'; + + function buildQueryOperation() { + return { + '@id': 'amf://id#12', + '@type': [OPERATION_T], + [METHOD]: [{ '@value': 'QUERY' }], + }; + } + + let element; + + beforeEach(async () => { + element = await operationFixture({ operation: buildQueryOperation() }); + await nextFrame(); + }); + + it('computes the method in upper case', () => { + assert.equal(element._method, 'QUERY'); + }); + + it('renders the method label with the lower-cased color hook', () => { + const label = element.shadowRoot.querySelector('.method-label'); + assert.exists(label, 'the method label is rendered'); + assert.equal(label.getAttribute('data-method'), 'query', 'color hook is lower-cased'); + }); + + it('displays the method name in upper case', () => { + const label = element.shadowRoot.querySelector('.method-label'); + assert.equal(label.textContent.trim(), 'QUERY'); + }); + }); }); From 2150f185f2ef86c85ee9f3a9a2884b88705dd9cd Mon Sep 17 00:00:00 2001 From: alexp mule Date: Wed, 19 Aug 2026 09:25:51 -0300 Subject: [PATCH 2/6] feat(oas32): add COPY and MOVE method-label colors OAS 3.2 introduces the COPY and MOVE HTTP methods alongside QUERY. The http-method-label palette has no entry for them, so they fall back to the default gray. Add customizable color hooks matching the QUERY approach: COPY renders indigo, MOVE renders amber. Both are exposed as CSS custom properties (--http-method-label-copy/move-color and -background-color) with sensible fallbacks, and both raw (uppercase) and lower-cased data-method casings are keyed so navigation and documentation views agree. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/Styles.js | 18 ++++++++++++++++++ test/api-url.test.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/Styles.js b/src/Styles.js index 144eaee..0cbcc00 100644 --- a/src/Styles.js +++ b/src/Styles.js @@ -199,6 +199,24 @@ arc-marked { color: var(--http-method-label-query-color, #0f9d9d); } +.method-label[data-method='copy'], +.method-label[data-method='COPY'] { + background-color: var( + --http-method-label-copy-background-color, + rgba(92, 107, 192, 0.12) + ); + color: var(--http-method-label-copy-color, #5c6bc0); +} + +.method-label[data-method='move'], +.method-label[data-method='MOVE'] { + background-color: var( + --http-method-label-move-background-color, + rgba(184, 134, 11, 0.12) + ); + color: var(--http-method-label-move-color, #b8860b); +} + .bottom-nav, .bottom-link { display: flex; diff --git a/test/api-url.test.js b/test/api-url.test.js index 6784d09..b39eb71 100644 --- a/test/api-url.test.js +++ b/test/api-url.test.js @@ -224,4 +224,46 @@ describe('', () => { assert.equal(label.textContent.trim(), 'QUERY'); }); }); + + ['COPY', 'MOVE'].forEach((verb) => { + describe(`${verb} method (OAS 3.2)`, () => { + // OAS 3.2 also adds the COPY and MOVE HTTP methods. Same casing contract + // as QUERY: displayed upper case, color hook lower-cased. Inline expanded + // operation keeps this independent of the model generator. + const METHOD = 'http://a.ml/vocabularies/apiContract#method'; + const OPERATION_T = 'http://a.ml/vocabularies/apiContract#Operation'; + + let element; + + beforeEach(async () => { + element = await operationFixture({ + operation: { + '@id': 'amf://id#12', + '@type': [OPERATION_T], + [METHOD]: [{ '@value': verb }], + }, + }); + await nextFrame(); + }); + + it('computes the method in upper case', () => { + assert.equal(element._method, verb); + }); + + it('renders the method label with the lower-cased color hook', () => { + const label = element.shadowRoot.querySelector('.method-label'); + assert.exists(label, 'the method label is rendered'); + assert.equal( + label.getAttribute('data-method'), + verb.toLowerCase(), + 'color hook is lower-cased' + ); + }); + + it('displays the method name in upper case', () => { + const label = element.shadowRoot.querySelector('.method-label'); + assert.equal(label.textContent.trim(), verb); + }); + }); + }); }); From 9d0afa7dcbe15d070b85bd2a90082f433ebd0fdd Mon Sep 17 00:00:00 2001 From: alexp mule Date: Thu, 20 Aug 2026 14:54:00 -0300 Subject: [PATCH 3/6] @W-23748890 test(query): drive QUERY label from generated OAS 3.2 model, bump generator to 0.4.0 Bump @api-components/api-model-generator ^0.2.14 -> ^0.4.0 (amf-client-js 5.11 supports OAS 3.1/3.2) and the amf-helper-mixin floor ^4.5.31 -> ^4.5.38. The regenerated 5.11 models wrap custom domain extensions (the x-agent extension on agents-api) in a single-element array; the agent resolver only navigates that shape from 4.5.38+, where _computeNodeAgent uses _findCustomDomainPropertyByKey instead of scanning for an inline amf://id# key. Add a real OAS 3.2 demo spec exercising the QUERY method and register it so prepare generates its model. Make test/amf-loader.js @graph-aware (amf-client-js 5.11 emits flattened @graph models; expand once at load time) and drive the QUERY method-label test from the generated model instead of hand-building AMF. COPY/MOVE stay inline with a comment: AMF 5.11 does not parse copy/move from an OAS 3.2 pathItem. Co-Authored-By: Claude Opus 4.8 (1M context) --- demo/apis.json | 3 +- demo/oas32-query/oas32-query.yaml | 55 +++++++++++++++++++++++++++++++ test/api-url.test.js | 32 ++++++++---------- 3 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 demo/oas32-query/oas32-query.yaml diff --git a/demo/apis.json b/demo/apis.json index 67fc983..1622413 100644 --- a/demo/apis.json +++ b/demo/apis.json @@ -20,5 +20,6 @@ "streetlights/streetlights.yaml": "ASYNC 2.0", "W-11383870/W-11383870.json": { "type": "OAS 3.0", "mime": "application/json" }, "agents-api/agents-api.yaml": { "type": "OAS 3.0", "mime": "application/yaml" }, - "oas31-webhooks/oas31-webhooks.yaml": { "type": "OAS 3.1", "mime": "application/yaml" } + "oas31-webhooks/oas31-webhooks.yaml": { "type": "OAS 3.1", "mime": "application/yaml" }, + "oas32-query/oas32-query.yaml": { "type": "OAS 3.2", "mime": "application/yaml" } } diff --git a/demo/oas32-query/oas32-query.yaml b/demo/oas32-query/oas32-query.yaml new file mode 100644 index 0000000..656e206 --- /dev/null +++ b/demo/oas32-query/oas32-query.yaml @@ -0,0 +1,55 @@ +openapi: 3.2.0 +info: + title: OAS 3.2 QUERY method + version: 1.0.0 +paths: + /pets: + # `query` is a Path Item Object fixed field (sibling to get/post/etc.), + # added in OAS 3.2.0 for the QUERY HTTP method (a safe/idempotent method + # that carries a request body). amf-client-js 5.11 parses it as a real + # operation, which is what the QUERY method-label test drives from. + query: + operationId: queryPets + summary: Search pets using a structured filter body + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + kind: + type: string + maxAge: + type: integer + responses: + "200": + description: Matching pets + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: integer + name: + type: string + get: + operationId: listPets + summary: List pets (contrast operation for the QUERY label test) + responses: + "200": + description: All pets + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: integer + name: + type: string diff --git a/test/api-url.test.js b/test/api-url.test.js index b39eb71..e8c208a 100644 --- a/test/api-url.test.js +++ b/test/api-url.test.js @@ -185,27 +185,23 @@ describe('', () => { }); }); - describe('QUERY method (OAS 3.2)', () => { - // OAS 3.2 adds the QUERY HTTP method. `_computeMethod` upper-cases the raw - // AMF value for display ("QUERY"), and `_getMethodTemplate` lower-cases it - // for the color hook (`data-method="query"`). The color override keys on - // both casings. Inline expanded operation (no `@context`) keeps this - // independent of the model generator. - const METHOD = 'http://a.ml/vocabularies/apiContract#method'; - const OPERATION_T = 'http://a.ml/vocabularies/apiContract#Operation'; - - function buildQueryOperation() { - return { - '@id': 'amf://id#12', - '@type': [OPERATION_T], - [METHOD]: [{ '@value': 'QUERY' }], - }; - } - + describe('QUERY method (from a real generated OAS 3.2 model)', () => { + // OAS 3.2 adds the QUERY HTTP method. amf-client-js 5.11 PARSES `query:` from + // an OAS 3.2 pathItem and emits its method as "QUERY" (upper case), so the + // QUERY label is driven from a real generated model — + // demo/oas32-query/oas32-query.yaml — not hand-built AMF. `_computeMethod` + // keeps the raw upper-case value for display and the color hook is + // lower-cased to `data-method="query"`. + let amf; let element; + before(async () => { + amf = await AmfLoader.load('oas32-query', true); + }); + beforeEach(async () => { - element = await operationFixture({ operation: buildQueryOperation() }); + const [endpoint, operation] = AmfLoader.lookupEndpointOperation(amf, '/pets', 'QUERY'); + element = await operationFixture({ amf, endpoint, operation }); await nextFrame(); }); From dccf566f8d1c1f7d9be8f6f0c776b6b4ac3505b6 Mon Sep 17 00:00:00 2001 From: alexp mule Date: Fri, 21 Aug 2026 09:19:26 -0300 Subject: [PATCH 4/6] @W-23748890 demo(query): surface oas32-query in the demo selector The QUERY method label (OAS 3.2) was registered in apis.json but not reachable from the demo: the hardcoded selector list omitted the spec, so the generated model never appeared in the dropdown. Add it as 'OAS 3.2 (QUERY)' so the QUERY badge can be previewed. --- demo/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/demo/index.js b/demo/index.js index be9fb10..3a3ca16 100644 --- a/demo/index.js +++ b/demo/index.js @@ -170,6 +170,7 @@ class ComponentDemo extends ApiDemoPage { ['multiple-messages', 'multiple-messages'], ['streetlights', 'streetlights'], ['oas31-webhooks', 'OAS 3.1 webhooks'], + ['oas32-query', 'OAS 3.2 (QUERY)'], ].map(([file, label]) => html` ${label} - compact model ${label} From 2e2185794bf944ef0c76ff55900b382f2d2ab64c Mon Sep 17 00:00:00 2001 From: alexp mule Date: Fri, 21 Aug 2026 10:42:18 -0300 Subject: [PATCH 5/6] @W-23748890 chore(release): bump version to 5.2.33 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0b8a23f..0cd917b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@api-components/api-method-documentation", - "version": "5.2.31", + "version": "5.2.33", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@api-components/api-method-documentation", - "version": "5.2.31", + "version": "5.2.33", "license": "Apache-2.0", "dependencies": { "@advanced-rest-client/arc-icons": "^3.3.4", diff --git a/package.json b/package.json index 4fe6446..482e7af 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@api-components/api-method-documentation", "description": "A HTTP method documentation build from AMF model", - "version": "5.2.32", + "version": "5.2.33", "license": "Apache-2.0", "main": "index.js", "module": "index.js", From ad2b8442ce445c46c208a5f99a9700e34023070a Mon Sep 17 00:00:00 2001 From: alexp mule Date: Fri, 21 Aug 2026 11:24:42 -0300 Subject: [PATCH 6/6] @W-23748890 chore(deps): update package-lock.json for api-navigation 4.3.24 and amf-helper-mixin 4.5.38 --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0cd917b..c786f34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1181,9 +1181,9 @@ } }, "node_modules/@api-components/api-navigation": { - "version": "4.3.20", - "resolved": "https://registry.npmjs.org/@api-components/api-navigation/-/api-navigation-4.3.20.tgz", - "integrity": "sha512-ho9RaLhEK3WzHeS/QwwzVuK1WrOtZR8czxU0dWDI6YjMtBNz+pGy44sXA7rmj5F3iSPowKVu04neL0EW5JveiQ==", + "version": "4.3.24", + "resolved": "https://registry.npmjs.org/@api-components/api-navigation/-/api-navigation-4.3.24.tgz", + "integrity": "sha512-uhl5HG+DH0uWzIqupsO+X1bwRp5c9vQPNfT6pgBjRTmROrfK6RCrwr+SSOfCedbKJ+MsdAd4tgzlBi4vQ/KtrA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1191,7 +1191,7 @@ "@advanced-rest-client/icons": "^4.0.2", "@anypoint-web-components/anypoint-button": "^1.1.1", "@anypoint-web-components/anypoint-collapse": "^0.1.0", - "@api-components/amf-helper-mixin": "^4.5.34", + "@api-components/amf-helper-mixin": "^4.5.38", "@api-components/http-method-label": "^3.1.5", "@api-components/raml-aware": "^3.0.0", "lit-element": "^2.3.1",