From a542989f03cb6ef7db39859327ce304f410ba483 Mon Sep 17 00:00:00 2001 From: alexp mule Date: Wed, 19 Aug 2026 15:27:22 -0300 Subject: [PATCH 1/2] 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, mirroring the existing publish/subscribe overrides. AMF emits apiContract#method as QUERY (upper case) in navigation, so the rule keys on both 'query' and 'QUERY'. Teal (#0f9d9d) is read-safe and does not collide with the PATCH purple. W-23748890 --- src/Styles.js | 9 +++++ test/api-navigation.test.js | 70 +++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/Styles.js b/src/Styles.js index ad0b612..b3b80a1 100644 --- a/src/Styles.js +++ b/src/Styles.js @@ -254,6 +254,15 @@ export default css` color: var(--http-method-label-subscribe-color, #3490dc); } + .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); + } + .stream-type-badge { display: inline-block; padding: 4px 8px; diff --git a/test/api-navigation.test.js b/test/api-navigation.test.js index 8bfd053..373d33c 100644 --- a/test/api-navigation.test.js +++ b/test/api-navigation.test.js @@ -1672,4 +1672,74 @@ describe('', () => { }); }); }); + + describe('QUERY method (OAS 3.2)', () => { + // OAS 3.2 introduces the QUERY HTTP method. AMF emits its + // `apiContract#method` value verbatim in upper case ("QUERY"), unlike the + // classic verbs which arrive lower case ("get"). The navigation renders + // `data-method` straight from that raw value, so the color override keys on + // both casings. This inline expanded model (no `@context`) keeps the test + // independent of the model generator. + const DOC = 'http://a.ml/vocabularies/document#Document'; + const ENCODES = 'http://a.ml/vocabularies/document#encodes'; + const WEBAPI = 'http://a.ml/vocabularies/apiContract#WebAPI'; + const ENDPOINT = 'http://a.ml/vocabularies/apiContract#endpoint'; + const ENDPOINT_T = 'http://a.ml/vocabularies/apiContract#EndPoint'; + const OPERATION_T = 'http://a.ml/vocabularies/apiContract#Operation'; + const SUPPORTED_OP = 'http://a.ml/vocabularies/apiContract#supportedOperation'; + const PATH = 'http://a.ml/vocabularies/apiContract#path'; + const METHOD = 'http://a.ml/vocabularies/apiContract#method'; + + function buildQueryModel() { + return { + '@type': [DOC], + [ENCODES]: [{ + '@id': 'amf://id#1', + '@type': [WEBAPI], + [ENDPOINT]: [{ + '@id': 'amf://id#10', + '@type': [ENDPOINT_T], + [PATH]: [{ '@value': '/pets' }], + [SUPPORTED_OP]: [{ + '@id': 'amf://id#11', + '@type': [OPERATION_T], + [METHOD]: [{ '@value': 'get' }], + }, { + '@id': 'amf://id#12', + '@type': [OPERATION_T], + [METHOD]: [{ '@value': 'QUERY' }], + }], + }], + }], + }; + } + + let element; + + beforeEach(async () => { + element = await basicFixture(); + element.amf = buildQueryModel(); + await aTimeout(0); + await nextFrame(); + }); + + it('renders a QUERY operation with data-method="QUERY"', () => { + const labels = Array.from( + element.shadowRoot.querySelectorAll('.operation .method-label') + ); + const methods = labels.map((node) => node.getAttribute('data-method')); + assert.include(methods, 'QUERY', 'a method-label carries the raw QUERY value'); + }); + + it('keeps the raw AMF casing (does not lower-case QUERY)', () => { + const methods = Array.from( + element.shadowRoot.querySelectorAll('.operation .method-label') + ).map((node) => node.getAttribute('data-method')); + assert.notInclude(methods, 'query', 'QUERY is not silently lower-cased'); + }); + + it('does not flag a QUERY-only REST API as gRPC', () => { + assert.isFalse(element._isGrpc, 'the API is treated as REST, not gRPC'); + }); + }); }); From 9d0e206fe4d8c29b29d27edcd6893b6fa7c3d4cf Mon Sep 17 00:00:00 2001 From: alexp mule Date: Wed, 19 Aug 2026 15:27:23 -0300 Subject: [PATCH 2/2] 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-navigation.test.js | 20 ++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/Styles.js b/src/Styles.js index b3b80a1..60dbfdb 100644 --- a/src/Styles.js +++ b/src/Styles.js @@ -263,6 +263,24 @@ export default css` 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); + } + .stream-type-badge { display: inline-block; padding: 4px 8px; diff --git a/test/api-navigation.test.js b/test/api-navigation.test.js index 373d33c..27d0838 100644 --- a/test/api-navigation.test.js +++ b/test/api-navigation.test.js @@ -1673,8 +1673,8 @@ describe('', () => { }); }); - describe('QUERY method (OAS 3.2)', () => { - // OAS 3.2 introduces the QUERY HTTP method. AMF emits its + describe('OAS 3.2 methods (QUERY, COPY, MOVE)', () => { + // OAS 3.2 introduces the QUERY, COPY and MOVE HTTP methods. AMF emits their // `apiContract#method` value verbatim in upper case ("QUERY"), unlike the // classic verbs which arrive lower case ("get"). The navigation renders // `data-method` straight from that raw value, so the color override keys on @@ -1708,6 +1708,14 @@ describe('', () => { '@id': 'amf://id#12', '@type': [OPERATION_T], [METHOD]: [{ '@value': 'QUERY' }], + }, { + '@id': 'amf://id#13', + '@type': [OPERATION_T], + [METHOD]: [{ '@value': 'COPY' }], + }, { + '@id': 'amf://id#14', + '@type': [OPERATION_T], + [METHOD]: [{ '@value': 'MOVE' }], }], }], }], @@ -1741,5 +1749,13 @@ describe('', () => { it('does not flag a QUERY-only REST API as gRPC', () => { assert.isFalse(element._isGrpc, 'the API is treated as REST, not gRPC'); }); + + it('renders COPY and MOVE operations with their raw data-method', () => { + const methods = Array.from( + element.shadowRoot.querySelectorAll('.operation .method-label') + ).map((node) => node.getAttribute('data-method')); + assert.include(methods, 'COPY', 'a method-label carries the raw COPY value'); + assert.include(methods, 'MOVE', 'a method-label carries the raw MOVE value'); + }); }); });