From e9ed7df7f35c622a849367124847b436bd86d97e Mon Sep 17 00:00:00 2001 From: Lorna Jane Mitchell Date: Sat, 8 Aug 2026 19:59:32 +0100 Subject: [PATCH 01/10] Move in-progress versions to dev branch, main is only published content --- schemas/v1.2-dev/readme.md | 37 -- schemas/v1.2-dev/schema.yaml | 130 ----- versions/1.2.0-dev.md | 925 ----------------------------------- 3 files changed, 1092 deletions(-) delete mode 100644 schemas/v1.2-dev/readme.md delete mode 100644 schemas/v1.2-dev/schema.yaml delete mode 100644 versions/1.2.0-dev.md diff --git a/schemas/v1.2-dev/readme.md b/schemas/v1.2-dev/readme.md deleted file mode 100644 index d98a4e0..0000000 --- a/schemas/v1.2-dev/readme.md +++ /dev/null @@ -1,37 +0,0 @@ -# OpenAPI Overlay 1.2.x JSON Schema - -Here you can find the JSON Schema for validating Overlays of versions 1.2.x. - -As a reminder, the JSON Schema is not the source of truth for the Specification. -In cases of conflicts between the Specification itself and the JSON Schema, the -Specification wins. Also, some Specification constraints cannot be represented -with the JSON Schema so it's highly recommended to employ other methods to -ensure compliance. - -The iteration version of the JSON Schema can be found in the `$id` field. -For example, the value of `$id: https://spec.openapis.org/overlay/1.2/schema/2024-10-17` means this iteration was created on October 17, 2024. - -## Contributing - -To submit improvements to the schema, modify the `schema.yaml` and add test cases for your changes. - -The TSC will then: - -- Run tests on the updated schema -- Update the iteration version -- Publish the new version - -## Tests - -The [test suite](../../tests/v1.2-dev) is part of this package. - -```bash -npm install -npm test -``` - -You can also validate a document individually. - -```bash -node scripts/validate.mjs path/to/document/to/validate.yaml -``` diff --git a/schemas/v1.2-dev/schema.yaml b/schemas/v1.2-dev/schema.yaml deleted file mode 100644 index f1d9917..0000000 --- a/schemas/v1.2-dev/schema.yaml +++ /dev/null @@ -1,130 +0,0 @@ -$id: https://spec.openapis.org/overlay/1.2/schema/WORK-IN-PROGRESS -$schema: https://json-schema.org/draft/2020-12/schema -description: The description of Overlay v1.2.x documents -type: object -properties: - overlay: - type: string - pattern: ^1\.2\.\d+$ - $self: - type: string - format: uri-reference - $comment: MUST NOT contain a fragment - pattern: "^[^#]*$" - info: - $ref: "#/$defs/info-object" - extends: - type: string - format: uri-reference - $comment: MUST NOT contain a fragment - pattern: "^[^#]*$" - actions: - type: array - minItems: 1 - uniqueItems: true - items: - oneOf: - - $ref: "#/$defs/reusable-action-reference-object" - - $ref: "#/$defs/action-object" - components: - $ref: "#/$defs/components-object" -required: - - overlay - - info - - actions -$ref: "#/$defs/specification-extensions" -unevaluatedProperties: false -$defs: - reusable-action-reference-object: - type: object - allOf: - - $ref: "#/$defs/specification-extensions" - - $ref: "#/$defs/description-field" - - $ref: "#/$defs/target-field" - properties: - $ref: - type: string - pattern: ^#\/components\/actions\/(?:[^~/]|~0|~1)+$ - required: - - $ref - - target - unevaluatedProperties: false - reusable-action-fields-object: - type: object - allOf: - - $ref: "#/$defs/description-field" - - $ref: "#/$defs/action-fields" - - $ref: "#/$defs/specification-extensions" - unevaluatedProperties: false - reusable-action-object: - type: object - allOf: - - $ref: "#/$defs/specification-extensions" - - $ref: "#/$defs/description-field" - properties: - fields: - $ref: "#/$defs/reusable-action-fields-object" - unevaluatedProperties: false - components-object: - type: object - properties: - actions: - type: object - additionalProperties: - $ref: "#/$defs/reusable-action-object" - $ref: "#/$defs/specification-extensions" - unevaluatedProperties: false - info-object: - type: object - properties: - title: - type: string - version: - type: string - allOf: - - $ref: "#/$defs/description-field" - required: - - title - - version - $ref: "#/$defs/specification-extensions" - unevaluatedProperties: false - description-field: - type: object - properties: - description: - type: string - target-field: - type: object - properties: - target: - type: string - pattern: ^\$ - action-fields: - type: object - properties: - update: - type: - - string - - boolean - - object - - array - - number - - "null" - copy: - type: string - remove: - type: boolean - default: false - action-object: - type: object - allOf: - - $ref: "#/$defs/description-field" - - $ref: "#/$defs/target-field" - - $ref: "#/$defs/action-fields" - - $ref: "#/$defs/specification-extensions" - required: - - target - unevaluatedProperties: false - specification-extensions: - patternProperties: - ^x-: true diff --git a/versions/1.2.0-dev.md b/versions/1.2.0-dev.md deleted file mode 100644 index 994f039..0000000 --- a/versions/1.2.0-dev.md +++ /dev/null @@ -1,925 +0,0 @@ -# Overlay Specification - -## Abstract - -The Overlay Specification defines a document format for information that augments an existing [[OpenAPI]] description yet remains separate from the OpenAPI description's source document(s). - -## Version 1.2.0 - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14](https://tools.ietf.org/html/bcp14) [RFC2119](https://tools.ietf.org/html/rfc2119) [RFC8174](https://tools.ietf.org/html/rfc8174) when, and only when, they appear in all capitals, as shown here. - -This document is licensed under [The Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.html). - -## Introduction - -The Overlay Specification is a companion to the [[OpenAPI]] Specification. -An Overlay describes a set of changes to be applied or "overlaid" onto an existing OpenAPI description. - -The main purpose of the Overlay Specification is to provide a way to repeatably apply transformations to one or many OpenAPI descriptions. Use cases include updating descriptions, adding metadata to be consumed by another tool, or removing certain elements from an API description before sharing it with partners. An Overlay may be specific to a single OpenAPI description or be designed to apply the same transform to any OpenAPI description. - -## Definitions - -### Overlay - -An Overlay is represented in JSON or YAML and contains [actions](#overlay-actions) that are applied in order to an [[OpenAPI]] description. Each action uses a target expressed as a [[RFC9535|RFC9535 JSONPath]] query expression to identify where changes apply. [Reusable actions](#reusable-action-object) may be used to reduce duplication through references. - -## Specification - -### Versions - -The Overlay Specification is versioned using a `major`.`minor`.`patch` versioning scheme. The `major`.`minor` portion of the version string (for example 1.0) SHALL designate the Overlay feature set. `patch` versions address errors in, or provide clarifications to, this document, not the feature set. The patch version SHOULD NOT be considered by tooling, making no distinction between 1.0.0 and 1.0.1 for example. - -**Note:** Version 1.0.0 of the Overlay Specification was released after spending some time in draft and being implemented by a few early-adopting tool providers. Check with your tool provider for the details of what is supported in each tool. - -### Format - -An Overlay that conforms to the Overlay Specification is itself a JSON object, which may be represented either in [[RFC8259|JSON]] or [[YAML|YAML]] format. Examples in this specification will be shown in YAML for brevity. - -Implementations MUST support applying either JSON or YAML Overlay documents to -[[OpenAPI|OpenAPI]] descriptions -represented in either YAML or JSON format. - -All field names in the specification are **case sensitive**. -This includes all fields that are used as keys in a map, except where explicitly noted that keys are **case insensitive**. - -The Overlay [schema](#schema) defines two types of fields: _fixed fields_, which have a declared name, and _patterned fields_, which have a declared pattern for the field name. - -Patterned fields MUST have unique names within the containing object. - -#### JSON and YAML Compatibility - -In order to preserve the ability to round-trip between YAML and JSON formats, YAML version [1.2](https://yaml.org/spec/1.2/spec.html) is RECOMMENDED along with the additional constraints listed in [[!RFC9512]] [Section 3.4](https://www.rfc-editor.org/rfc/rfc9512.html#name-yaml-and-json). - -The recommendation in previous versions of this specification to restrict YAML to its "JSON" [schema ruleset](https://yaml.org/spec/1.2/spec.html#id2803231) allowed for the inclusion of certain values that (despite the name) cannot be represented in JSON. -Overlay authors SHOULD NOT rely on any such JSON-incompatible YAML values. - -#### Case Sensitivity - -As most field names and values in the Overlay Specification are case-sensitive, this document endeavors to call out any case-insensitive names and values. - -#### Rich Text Formatting - -Throughout the specification `description` fields are noted as supporting CommonMark markdown formatting. -Where Overlay tooling renders rich text it MUST support, at a minimum, markdown syntax as described by [CommonMark 0.27](https://spec.commonmark.org/0.27/). Tooling MAY choose to ignore some CommonMark or extension features to address security concerns. - -While the framing of CommonMark 0.27 as a minimum requirement means that tooling MAY choose to implement extensions on top of it, note that any such extensions are by definition implementation-defined and will not be interoperable. -Overlay Description authors SHOULD consider how text using such extensions will be rendered by tools that offer only the minimum support. - -### Parsing Documents - -Implementations MUST check all possible target [[OpenAPI]] Description documents provided to the implementation before treating an `extends` value as unresolvable. - -To ensure portability, when a target [[OpenAPI]] Description defines `$self`, the Overlay's `extends` value SHOULD match the target's `$self` URI. - -### Relative References in URIs - -URIs used in an Overlay document, including `$self` and `extends`, are identifiers, and not necessarily locators (URLs). - -Unless specified otherwise, all fields that are URI references MAY be relative references as defined by [RFC3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2). - -#### Establishing the Base URI - -Relative URI references are resolved using the appropriate base URI, which MUST be determined in accordance with [RFC3986 Section 5.1.1 - 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.1). - -The base URI for resolving relative references within an Overlay document is determined as follows: - -- If the [`$self`](#overlay-self) field is present and is an absolute URI, the base URI is the `$self` URI (per [RFC3986 Section 5.1.1](https://tools.ietf.org/html/rfc3986#section-5.1.1): Base URI Embedded in Content). -- If the [`$self`](#overlay-self) field is present and is a relative URI-reference, it MUST first be resolved against the next possible base URI source per [RFC3986 Section 5.1.2 - 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.2) before being used as the base URI for resolving other relative references. -- If the [`$self`](#overlay-self) field is not present, the base URI MUST be determined from the next possible base URI source per [RFC3986 Section 5.1.2 - 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.2). - -The most common base URI source in this case is the retrieval URI of the Overlay document (per [RFC3986 Section 5.1.3](https://tools.ietf.org/html/rfc3986#section-5.1.3)), though other sources such as encapsulating entities ([RFC3986 Section 5.1.2](https://tools.ietf.org/html/rfc3986#section-5.1.2)) or application-specific defaults ([RFC3986 Section 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.4)) MAY apply. - -#### Resolving URI Fragments - -For Overlay Object fields that identify whole documents (`$self` and `extends`), fragment identifiers MUST NOT be used. - -#### Relative URI References in CommonMark Fields - -Relative references in CommonMark hyperlinks (such as those in `description` fields) are resolved in their rendered context, which might differ from the context of the Overlay document. - -### Schema - -In the following description, if a field is not explicitly **REQUIRED** or described with a MUST or SHALL, it can be considered OPTIONAL. - -#### Overlay Object - -This is the root object of the [Overlay](#overlay). - -##### Fixed Fields - -| Field Name | Type | Description | -| ---- | :----: | ---- | -| overlay | `string` | **REQUIRED**. This string MUST be the [version number](#versions) of the Overlay Specification that the Overlay document uses. The `overlay` field SHOULD be used by tooling to interpret the Overlay document. | -| $self | `string` | A URI-reference for the Overlay document. This string MUST be in the form of a URI-reference as defined by [RFC3986 Section 4.1](https://tools.ietf.org/html/rfc3986#section-4.1). When present, this field provides the self-assigned URI of this Overlay document, which also serves as its base URI in accordance with [RFC3986 Section 5.1.1](https://tools.ietf.org/html/rfc3986#section-5.1.1) for resolving relative references within this document. The `$self` URI MUST NOT contain a fragment identifier. Overlay documents MAY include a `$self` field to ensure portable, unambiguous reference resolution. | -| info | [Info Object](#info-object) | **REQUIRED**. Provides metadata about the Overlay. The metadata MAY be used by tooling as required. | -| extends | `string` | URI reference that identifies the target document (such as an [[OpenAPI]] document) this overlay applies to. | -| actions | [[Action Object](#action-object) \| [Reusable Action Reference Object](#reusable-action-reference-object)] | **REQUIRED** An ordered list of actions to be applied to the target document. The array MUST contain at least one value. | -| components | [Components Object](#components-object) | A set of components to reuse across the Overlay Document. | - -This object MAY be extended with [Specification Extensions](#specification-extensions). - -The list of actions MUST be applied in sequential order to ensure a consistent outcome. Actions are applied to the result of the previous action. This enables objects to be deleted in one action and then re-created in a subsequent action, for example. - -The `extends` property can be used to indicate that the Overlay was designed to update a specific [[OpenAPI]] description. -Where no `extends` is provided it is the responsibility of tooling to apply the Overlay document to the appropriate OpenAPI description(s). - -In the following example, the Overlay identifies a target OpenAPI description using an absolute URI: - -```yaml -overlay: 1.2.0 -info: - title: Overlay for the Tic Tac Toe API document - version: 1.0.0 -extends: 'https://api.example.com/openapi/tictactoe.yaml' -... -``` - -In the following example, the Overlay document also includes `$self`, which establishes the document's identity and base URI: - -```yaml -overlay: 1.2.0 -$self: 'https://example.com/overlays/tictactoe.overlay.yaml' -info: - title: Overlay for the Tic Tac Toe API document - version: 1.0.0 -extends: 'https://api.example.com/openapi/tictactoe.yaml' -... -``` - -The `extends` property can also specify a relative URI reference. -Relative `extends` values are resolved using the base URI rules in [Relative References in URIs](#relative-references-in-uris): - -```yaml -overlay: 1.2.0 -$self: 'https://example.com/overlays/tictactoe.overlay.yaml' -info: - title: Overlay for the Tic Tac Toe API document - version: 1.0.0 -extends: '../openapi/tictactoe.yaml' -``` - -With the above Overlay document, `extends` resolves to `https://example.com/openapi/tictactoe.yaml`. - -#### Info Object - -The object provides metadata about the Overlay. -The metadata MAY be used by the clients if needed. - -##### Fixed Fields - -| Field Name | Type | Description | -| ---- | :----: | ---- | -| title | `string` | **REQUIRED**. A human readable description of the purpose of the overlay. | -| version | `string` | **REQUIRED**. A version identifier for indicating changes to the Overlay document. | -| description | `string` | A description of the Overlay Document. [[CommonMark]] syntax MAY be used for rich text representation. | - -This object MAY be extended with [Specification Extensions](#specification-extensions). - -#### Components Object - -The object provides a set of components to be reused across the Overlay document. - -##### Fixed Fields - -| Field Name | Type | Description | -| ---- | :----: | ---- | -| actions | Map(`string`, [Reusable Action Object](#reusable-action-object)) | A key-value set of reusable actions to reference in the actions through a [Reusable Action Reference Object](#reusable-action-reference-object). | - -When a key under `components.actions` is referenced by a Reusable Action Reference Object, that key is part of a JSON Pointer token and MUST be encoded according to [[RFC6901], Section 3](https://www.rfc-editor.org/rfc/rfc6901#section-3) (for example, `~` as `~0` and `/` as `~1`). - -This object MAY be extended with [Specification Extensions](#specification-extensions). - -#### Action Object - -This object represents one or more changes to be applied to the target document at the locations defined by the target JSONPath expression. - -##### Fixed Fields - -| Field Name | Type | Description | -| ---- | :----: | ---- | -| target | `string` | **REQUIRED** A RFC9535 JSONPath query expression selecting nodes in the target document. | -| description | `string` | A description of the action. [[CommonMark]] syntax MAY be used for rich text representation. | -| update | Any | If the `target` selects object nodes, the value of this field MUST be an object with the properties and values to merge with each selected object. If the `target` selects array nodes, the value of this field MUST be an array to concatenate with each selected array, or an object or primitive value to append to each selected array. If the `target` selects primitive nodes, the value of this field MUST be a primitive value to replace each selected node. This field has no impact if the `remove` field of this action object is `true` or if the `copy` field contains a value. | -| copy | `string` | A JSONPath expression selecting a single node to copy into the `target` nodes. If the `target` selects object nodes, the value of this field MUST be an object with the properties and values to merge with each selected object. If the `target` selects array nodes, the value of this field MUST be an array to concatenate with each selected array, or an object or primitive value to append to each selected array. If the `target` selects primitive nodes, the value of this field MUST be a primitive value to replace each selected node. This field has no impact if the `remove` field of this action object is `true` or if the `update` field contains a value. | -| remove | `boolean` | A boolean value that indicates that each of the target nodes MUST be removed from the the map or array it is contained in. The default value is `false`. | - -If the `target` JSONPath expression selects zero nodes, the action succeeds without changing the target document. -If the `target` JSONPath expression selects two or more nodes for an `update` or `copy` action, the selected nodes MUST be either all objects or all arrays or all primitives. - -The properties of the `update` or `copy` object MUST be compatible with the target object referenced by the JSONPath key. When the Overlay document is applied, the `update` or `copy` object is merged with the target object by recursively applying these steps: - -- A property that only exists in the target object is left unchanged. -- A property that only exists in the `update` or `copy` object is inserted into the target object. -- If a property exists in both `update` or `copy` and target object: - - A primitive value of the `update` or `copy` property replaces a primitive value of the target property. - - An array value of the `update` or `copy` property is concatenated with an array value of the target property. - - An object value of the `update` or `copy` property is recursively merged with an object value of the target property. - - Other property value combinations are incompatible and result in an error. - -This object MAY be extended with [Specification Extensions](#specification-extensions). - -#### Reusable Action Object - -This object defines a reusable action in [`components.actions`](#component-actions). -It can be referenced from [`actions`](#overlay-actions) by a [Reusable Action Reference Object](#reusable-action-reference-object). - -##### Fixed fields - -| Field Name | Type | Description | -| ---- | :----: | ---- | -| description | `string` | A description of the reusable action. This description is independent of the `description` field on the contained [Action Object](#action-object) and is intended to document the reusable action itself (for example, its purpose or usage). [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. | -| fields | [Action Object](#action-object) | An [Action Object](#action-object) where no field is required, except that the `target` field MUST NOT be provided. The `target` MUST be supplied by the [Reusable Action Reference Object](#reusable-action-reference-object). | - -This object MAY be extended with [Specification Extensions](#specification-extensions). - -A reusable action is similar to an action but differs in important ways: - -1. Action fields are nested inside the `fields` property, not defined as peer properties. The `fields` object may omit any action field, and MUST NOT include the `target` field; the `target` MUST be supplied by the [Reusable Action Reference Object](#reusable-action-reference-object). -1. A Reusable Action Object has to be referenced by a Reusable Action Reference Object to have any effect on the OpenAPI description. - -#### Reusable Action Reference Object - -A Reusable Action Reference Object applies a reusable action defined in `components.actions` to a specific target in the source document. -It references the reusable action by `$ref` and MAY provide action fields that override values from the referenced reusable action for that use. - -##### Fixed fields - -| Field Name | Type | Description | -| ---- | :----: | ---- | -| $ref | `string` | **REQUIRED** A [same-document](https://www.rfc-editor.org/rfc/rfc3986.html#section-4.4) (or fragment-only) relative URI reference, per RFC3986 ยง4.4, where the fragment syntax is JSON Pointer with the pointer prefix restricted to `/components/actions/`. Component action keys in this pointer MUST be encoded according to [[RFC6901], Section 3](https://www.rfc-editor.org/rfc/rfc6901#section-3). | -| target | `string` | **REQUIRED** A JSONPath query expression, as described in [[RFC9535]], referencing the target objects in the source document. | -| description | `string` | A description of the action. [[CommonMark]] syntax MAY be used for rich text representation. | - -This object MAY be extended with [Specification Extensions](#specification-extensions). - -In case a description is defined in `fields` of the referenced [Reusable Action Object](#reusable-action-object) and in the [Reusable Action Reference Object](#reusable-action-reference-object), the description from the Reusable Action Reference Object MUST be used. - -### Examples - -#### Structured Overlay Example - -When updating properties throughout the target document it may be more efficient to create a single `Action Object` that mirrors the structure of the target document. e.g. - -```yaml -overlay: 1.2.0 -info: - title: Structured Overlay - version: 1.0.0 -actions: - - target: '$' # Root of document - update: - info: - x-overlay-applied: structured-overlay - paths: - '/': - summary: 'The root resource' - get: - summary: 'Retrieve the root resource' - x-rate-limit: 100 - '/pets': - get: - summary: 'Retrieve a list of pets' - x-rate-limit: 100 - components: - tags: -``` - -#### Targeted Overlay Example - -Alternatively, where only a small number of updates need to be applied to a large document, each [Action Object](#action-object) MAY be more targeted. - -```yaml -overlay: 1.1.0 -info: - title: Targeted Overlay - version: 1.0.0 -actions: - - target: $.paths['/foo'].get.description - update: This is the new description - - target: $.paths['/bar'].get.description - update: This is the updated description - - target: $.paths['/bar'] - update: - post: - description: This is an updated description of a child object - x-safe: false -``` - -#### Wildcard Overlay Example - -One significant advantage of using the JSONPath syntax is that it allows referencing multiple nodes in the target document. This would allow a single update object to be applied to multiple target objects using wildcards and other multi-value selectors. - -```yaml -overlay: 1.2.0 -info: - title: Update many objects at once - version: 1.0.0 -actions: - - target: $.paths.*.get - update: - x-safe: true - - target: $.paths.*.get.parameters[?@.name=='filter' && @.in=='query'] - update: - schema: - $ref: '#/components/schemas/filterSchema' -``` - -#### Array Modification Examples - -Array elements can be added using the `update` action. - -```yaml -overlay: 1.2.0 -info: - title: Add an array element - version: 1.0.0 -actions: - - target: $.paths.*.get.parameters - update: - name: newParam - in: query -``` - -Array elements can be deleted using the `remove` action. Use of array indexes to remove array items should be avoided where possible as indexes will change when items are removed. - -```yaml -overlay: 1.2.0 -info: - title: Remove an array element - version: 1.0.0 -actions: - - target: $.paths.*.get.parameters[?@.name == 'dummy'] - remove: true -``` - -This also works for primitive target nodes: - -```yaml -overlay: 1.1.0 -info: - title: Remove a primitive array element - version: 1.0.0 -actions: - - target: $.paths.*.get.tags[?@ == 'dummy'] - remove: true -``` - -#### Traits Example - -By annotating a target document (such as an [[OpenAPI]] document) using [Specification Extensions](#specification-extensions) such as `x-oai-traits`, the author of the target document MAY identify where overlay updates should be applied. - -```yaml -openapi: 3.2.0 -info: - title: API with a paged collection - version: 1.0.0 -paths: - /items: - get: - x-oai-traits: ['paged'] - responses: - 200: - description: OK - /items/{id}/subitems: - get: - x-oai-traits: ['paged'] - parameters: - - name: id - in: path - required: true - responses: - 200: - description: OK - /other: - get: - responses: - 200: - description: OK -``` - -With the above OpenAPI document, the following Overlay document will apply the necessary updates to describe how paging is implemented, where that trait has been applied. - -```yaml -overlay: 1.2.0 -info: - title: Apply Traits - version: 1.0.0 -actions: - - target: $.paths[?(@.get['x-oai-traits'][?(@ == 'paged')])].get - update: - parameters: - - name: top - in: query - # ... - - name: skip - in: query - # ... -``` - -resulting in - -```yaml -openapi: 3.2.0 -info: - title: API with a paged collection - version: 1.0.0 -paths: - /items: - get: - x-oai-traits: ["paged"] - responses: - 200: - description: OK - parameters: - - name: top - in: query - # ... - - name: skip - in: query - # ... - /items/{id}/subitems: - get: - x-oai-traits: ["paged"] - parameters: - - name: id - in: path - required: true - - name: top - in: query - # ... - - name: skip - in: query - # ... - responses: - 200: - description: OK - /other: - get: - responses: - 200: - description: OK -``` - -This approach allows inversion of control as to where the Overlay updates apply to the target document itself. - -#### Copy Example - -Copy actions behave similarly to `update` actions but source the new values to merge with the target from the document being transformed instead of providing them in the Overlay document. Copy actions MAY be used in sequence with `update` or `remove` actions to perform more advanced transformations like moving or renaming nodes. - -##### Simple Copy - -This example shows how to copy all operations from the `items` path item to the `some-items` path item. - -###### Source Description - -```yaml -openapi: 3.2.0 -info: - title: Example API - version: 1.0.0 -paths: - /items: - get: - responses: - 200: - description: OK - /some-items: - delete: - responses: - 200: - description: OK -``` - -###### Overlay - -```yaml -overlay: 1.1.0 -info: - title: Copy contents of an existing path to a new location - version: 1.0.0 -actions: - - target: '$.paths["/some-items"]' - copy: '$.paths["/items"]' - description: 'copies recursively all elements from the "items" path item to the new "some-items" path item without ensuring the node exists before the copy' -``` - -###### Result Description - -```yaml -openapi: 3.2.0 -info: - title: Example API - version: 1.0.0 -paths: - /items: - get: - responses: - 200: - description: OK - /some-items: - get: - responses: - 200: - description: OK - delete: - responses: - 200: - description: OK -``` - -##### Ensure the Target Exists and Copy - -This example shows how to copy all operations from the `items` path item to the `other-items` path item after first ensuring the target exists with an update action. - -###### Source Description - -```yaml -openapi: 3.2.0 -info: - title: Example API - version: 1.0.0 -paths: - /items: - get: - responses: - 200: - description: OK - /some-items: - delete: - responses: - 200: - description: OK -``` - -###### Overlay - -```yaml -overlay: 1.1.0 -info: - title: Create a path and copy the contents of an existing path to the new path - version: 1.0.0 -actions: - - target: '$.paths' - update: { "/other-items": {} } - - target: '$.paths["/other-items"]' - copy: '$.paths["/items"]' - description: 'copies recursively all elements from the "items" path item to the new "other-items" path item while ensuring the node exists before the copy' -``` - -###### Result Description - -```yaml -openapi: 3.2.0 -info: - title: Example API - version: 1.0.0 -paths: - /items: - get: - responses: - 200: - description: OK - /other-items: - get: - responses: - 200: - description: OK - /some-items: - delete: - responses: - 200: - description: OK -``` - -##### Move Example - -This example shows how to rename the `items` path item to `new-items` using a sequence of overlay actions: - -1. Use an `update` action to ensure the target path item exists. -2. Use a `copy` action to copy the source path item to the target. -3. Use a `remove` action to delete the original source path item. - -###### Source Description - -```yaml -openapi: 3.2.0 -info: - title: Example API - version: 1.0.0 -paths: - /items: - get: - responses: - 200: - description: OK - /some-items: - delete: - responses: - 200: - description: OK -``` - -###### Overlay - -```yaml -overlay: 1.1.0 -info: - title: Update the path for an API endpoint - version: 1.0.0 -actions: - - target: '$.paths' - update: { "/new-items": {} } - - target: '$.paths["/new-items"]' - copy: '$.paths["/items"]' - - target: '$.paths["/items"]' - remove: true - description: 'moves (renames) the "items" path item to "new-items"' -``` - -###### Result Description - -```yaml -openapi: 3.2.0 -info: - title: Example API - version: 1.0.0 -paths: - /new-items: - get: - responses: - 200: - description: OK - /some-items: - delete: - responses: - 200: - description: OK -``` - -##### Reusable Action Reference Example - Overrides - -This example shows how a reusable action can provide shared update content while a reusable action reference supplies the `target` locally. In this case, each reference reuses the same error response definition but supplies a different `target` so the update is applied to different operations. - -###### Source Description - -```yaml -openapi: 3.2.0 -info: - title: Example API - version: 1.0.0 -paths: - /items: - get: - responses: - 200: - description: OK - /some-items: - delete: - responses: - 200: - description: OK -``` - -###### Overlay - -```yaml -overlay: 1.2.0 -info: - title: Use reusable actions to insert error responses - version: 1.0.0 -components: - actions: - errorResponse: - fields: - update: - 404: - description: Not Found - content: - application/json: - schema: - type: object - properties: - message: - type: string - description: Adds an error response to the operation -actions: -- $ref: '#/components/actions/errorResponse' - target: "$.paths['/items'].get.responses" -- $ref: '#/components/actions/errorResponse' - target: "$.paths['/some-items'].delete.responses" -``` - -###### Result Description - -```yaml -openapi: 3.2.0 -info: - title: Example API - version: 1.0.0 -paths: - /items: - get: - responses: - 200: - description: OK - 404: - description: Not Found - content: - application/json: - schema: - type: object - properties: - message: - type: string - /some-items: - delete: - responses: - 200: - description: OK - 404: - description: Not Found - content: - application/json: - schema: - type: object - properties: - message: - type: string -``` - -### Specification Extensions - -While the Overlay Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points. - -The extension properties are implemented as patterned fields that are always prefixed by `"x-"`. - -| Field Pattern | Type | Description | -| ---- | :--: | ---- | -| ^x- | Any | Allows extensions to the Overlay Specification. The field name MUST begin with `x-`, for example, `x-internal-id`. Field names beginning `x-oai-` and `x-oas-` are reserved for uses defined by the [OpenAPI Initiative](https://www.openapis.org/). The value MAY be `null`, a primitive, an array or an object. | - -The extensions may or may not be supported by the available tooling, but those may be extended as well to add requested support (if tools are internal or open-sourced). - -### File Naming Convention - -Overlay files MAY choose to follow the convention of a `purpose.overlay.yaml` file naming pattern. -Other file naming conventions are also supported. - -### RFC9535 Compliance - -[[RFC9535]] is a recent specification and libraries implementing JSONPath support might predate the RFC. Those libraries might differ entirely (expressions syntax is incompatible), or implement additional capabilities (superset of the RFC). A tool or library MUST fully implement [[RFC9535]] when parsing and expanding JSONPath query expressions to be compliant with the Overlay specification. - -Interoperable Overlay Documents MUST use RFC9535 JSONPath query expressions and MUST NOT use tool-specific JSONPath extensions. - - -### Comments in OpenAPI Descriptions - -Some formats, like [YAML](https://yaml.org/) or [JSONC](https://jsonc.org/), support using comments which do not impact the semantic meaning of the description. Applying Overlay Actions to a description MAY result in the loss of such comments in the updated description. The exact behavior is specific to the tool implementing the Overlay Specification. - -## Appendix A: Revision History - -| Version | Date | Notes | -| ---- | ---- | ---- | -| 1.2.0 | TBD | Release of the Overlay Specification 1.2.0 | -| 1.1.0 | 2026-01-14 | Release of the Overlay Specification 1.1.0 | -| 1.0.0 | 2024-10-17 | First release of the Overlay Specification | - -## Appendix B: Examples of Base URI Determination and Identifier Resolution - -This appendix provides concrete examples demonstrating how the [`$self`](#overlay-self) field, Source Description URLs, and relative references work together across different deployment scenarios. - -### Base URI Within Content (Using `$self`) - -Assume the following Overlay document is retrieved from `file:///Users/dev/projects/overlays/purchase.overlay.yaml`: - -```yaml -overlay: 1.2.0 -$self: https://example.com/overlays/purchase.overlay.yaml -info: - title: Purchase overlay - version: 1.0.0 -extends: ../openapi/petstore.yaml -actions: - - target: '$.info' - update: - x-overlay: purchase -``` - -The relative `extends` URI `../openapi/petstore.yaml` resolves against the `$self` base URI `https://example.com/overlays/purchase.overlay.yaml`, producing `https://example.com/openapi/petstore.yaml`, regardless of the retrieval URI. - -### Base URI From the Retrieval URI (No `$self`) - -If the same Overlay document does not define `$self`: - -```yaml -overlay: 1.2.0 -info: - title: Purchase overlay - version: 1.0.0 -extends: ../openapi/petstore.yaml -actions: - - target: '$.info' - update: - x-overlay: purchase -``` - -Retrieved from `file:///Users/dev/projects/overlays/purchase.overlay.yaml`, the relative `extends` URI resolves to `file:///Users/dev/projects/openapi/petstore.yaml`. - -### Base URI From Encapsulating Entity - -Per [RFC3986 Section 5.1.2](https://tools.ietf.org/html/rfc3986#section-5.1.2), the base URI can be provided by an encapsulating entity. For example, in a `multipart/related` response where an Overlay document is embedded: - -```http -Content-Type: multipart/related; boundary=example; type=application/json - ---example -Content-Type: application/json -Content-Location: https://example.com/overlays/purchase.overlay.json - -{ - "overlay": "1.2.0", - "info": {"title": "Purchase overlay", "version": "1.0.0"}, - "extends": "../openapi/petstore.json", - "actions": [ - { - "target": "$.info", - "update": {"x-overlay": "purchase"} - } - ] -} ---example-- -``` - -The `Content-Location` header provides the base URI (`https://example.com/overlays/purchase.overlay.json`), so `../openapi/petstore.json` resolves to `https://example.com/openapi/petstore.json` even without a `$self` field. - -### Application-Specific Default Base URI - -Per [RFC3986 Section 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.4), applications may define default base URIs. For documents loaded without explicit retrieval URIs (e.g., from a database), implementations typically generate a unique base URI per document using a fixed prefix plus a unique identifier. - -For example, an API management platform might construct base URIs as `https://overlays.example.com/{uuid}` for each document: - -```yaml -overlay: 1.2.0 -# No $self field -# Loaded from database, assigned base URI: https://overlays.example.com/a7b3c4d5 -info: - title: Purchase overlay - version: 1.0.0 -extends: specs/petstore.yaml # Resolves using application default -actions: - - target: '$.info' - update: - x-overlay: purchase -``` - -If the application assigns base URI `https://overlays.example.com/a7b3c4d5` to this document, then `specs/petstore.yaml` resolves to `https://overlays.example.com/specs/petstore.yaml`. - -### Resolving Relative `$self` - -When `$self` is itself a relative URI-reference, it must be resolved before being used as a base URI: - -```yaml -overlay: 1.2.0 -$self: overlays/purchase.overlay.yaml -info: - title: Purchase overlay - version: 1.0.0 -extends: ../openapi/petstore.yaml -actions: - - target: '$.info' - update: - x-overlay: purchase -``` - -Retrieved from `https://example.com/v2/api-description.yaml`: - -1. First, resolve the `$self` relative reference `overlays/purchase.overlay.yaml` against the retrieval URI `https://example.com/v2/api-description.yaml`, which resolves to `https://example.com/v2/overlays/purchase.overlay.yaml` per [RFC3986 Section 5.2](https://tools.ietf.org/html/rfc3986#section-5.2). -2. Then resolve the `extends` relative reference `../openapi/petstore.yaml` against the resolved `$self` base URI `https://example.com/v2/overlays/purchase.overlay.yaml`, which resolves to `https://example.com/v2/openapi/petstore.yaml`. - -### Why Potential Target Documents Should Be Checked for `$self` - -An Overlay may be given this `extends` value: - -```yaml -overlay: 1.2.0 -info: - title: Overlay for approved API description - version: 1.0.0 -extends: https://apis.example.com/approved/petstore.yaml -actions: - - target: '$.info' - update: - x-overlay: approved -``` - -A candidate target OpenAPI description might be retrieved from `https://cdn.example.net/mirror/petstore.yaml` while declaring: - -```yaml -openapi: 3.2.0 -$self: https://apis.example.com/approved/petstore.yaml -info: - title: Petstore - version: 1.0.0 -paths: {} -``` - -Because `extends` is identifier-based, the match succeeds using the target description's `$self` URI, even though retrieval occurred from a different location. From ed9fcc6ea1504d16b8b15b6086b5ccfb0f64ecb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2026 04:36:33 +0000 Subject: [PATCH 02/10] build(deps): bump highlight.js from 11.11.1 to 11.12.0 Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 11.11.1 to 11.12.0. - [Release notes](https://github.com/highlightjs/highlight.js/releases) - [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md) - [Commits](https://github.com/highlightjs/highlight.js/compare/11.11.1...11.12.0) --- updated-dependencies: - dependency-name: highlight.js dependency-version: 11.12.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1b97db..428e466 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "cheerio": "^1.2.0", - "highlight.js": "^11.11.1", + "highlight.js": "^11.12.0", "markdown-it": "^15.0.0", "respec": "37.2.0", "yargs": "^18.1.0" @@ -2070,9 +2070,9 @@ } }, "node_modules/highlight.js": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.12.0.tgz", + "integrity": "sha512-nbfWpyRMcMrPMmDwJB+dhX/eiaPKtc2RB+0QZskqJ3WjRA/FDS0e9hZrx8EC/lbEv8gXy98FcDbNa/dspAaJMg==", "license": "BSD-3-Clause", "engines": { "node": ">=12.0.0" diff --git a/package.json b/package.json index 8a06ad3..2e0147c 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "readmeFilename": "README.md", "dependencies": { "cheerio": "^1.2.0", - "highlight.js": "^11.11.1", + "highlight.js": "^11.12.0", "markdown-it": "^15.0.0", "respec": "37.2.0", "yargs": "^18.1.0" From 47c99b188a34d5f66c4cb3323ab999bb49f4c41e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2026 04:36:42 +0000 Subject: [PATCH 03/10] build(deps): bump respec from 37.2.0 to 37.3.0 Bumps [respec](https://github.com/speced/respec) from 37.2.0 to 37.3.0. - [Release notes](https://github.com/speced/respec/releases) - [Changelog](https://github.com/speced/respec/blob/main/CHANGELOG.md) - [Commits](https://github.com/speced/respec/compare/v37.2.0...v37.3.0) --- updated-dependencies: - dependency-name: respec dependency-version: 37.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 60 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1b97db..eee2653 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "cheerio": "^1.2.0", "highlight.js": "^11.11.1", "markdown-it": "^15.0.0", - "respec": "37.2.0", + "respec": "37.3.0", "yargs": "^18.1.0" }, "devDependencies": { @@ -374,12 +374,12 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.6.tgz", - "integrity": "sha512-B/gKoqlFkzhvzsI6jo9K1cZz9o5ypviVv/xu8CwA4grZzyVwN+XfkT+tu8T1zrauuEXv6VhS2oGX+6NL95WcKA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.2.0.tgz", + "integrity": "sha512-LlBrE8oqGfU7b1Nk2d5Q1SbuPhZxTj0cJEMDPEws28OjNMELlflekmPPuf4FnK03x0ZRjKaYwJElUcKK4kyqJA==", "license": "Apache-2.0", "dependencies": { - "modern-tar": "^0.7.6", + "modern-tar": "^0.8.0", "yargs": "^18.0.0" }, "bin": { @@ -1623,9 +1623,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1653615", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1653615.tgz", - "integrity": "sha512-pGVkY3T/qXxAp2nFPodwYqOevk6ncNMSmvL8QfRCx5ZWGd6Vor7AFNmyaA8Zs6uJyP1QAfjuLandCgvSix1BNA==", + "version": "0.0.1666840", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1666840.tgz", + "integrity": "sha512-gCcO42XCHKEs7Ag0S7aGYsnJ7hlgrO3qderYqeiY0Eqk+0GFfuvT13IA0hHreJTa2KCdDVyGMeOhdMNmrrTjVg==", "license": "BSD-3-Clause" }, "node_modules/dom-serializer": { @@ -3230,9 +3230,9 @@ } }, "node_modules/marked": { - "version": "18.0.5", - "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.5.tgz", - "integrity": "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==", + "version": "18.0.9", + "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.9.tgz", + "integrity": "sha512-/Sa4qiiHZxf0/FQdBBowr9q4r10krCwMvpK48FUBdXdUXScDxiQGR9zCPrFgRVR5LU3iySOiIjy09ZQvADir1w==", "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -4210,9 +4210,9 @@ "license": "MIT" }, "node_modules/modern-tar": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.7.7.tgz", - "integrity": "sha512-t9VmxaqrmANnEOBhpSDI6HD192Ge48k8vmWqQQL7hSFEqHEYwZbbsu49+aKLWZeRvFs3j1pMhXOqqF4kPlvjkQ==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/modern-tar/-/modern-tar-0.8.4.tgz", + "integrity": "sha512-gN54ddmyzEg10orwZ2u4OOv+bjpMWdIl5jIkodK97bMq8QBSL5c0D7YX0lT1Ooz+99S7+PvFbnxzdjgHo1r41g==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -4680,17 +4680,17 @@ } }, "node_modules/puppeteer": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-25.4.0.tgz", - "integrity": "sha512-xfQp8dFBcGaLc1hEMaVr7s+oW4ZkAurr8Y9H81ilKhu6QoLfSTkZjU7IavnyJ/VWpB9ni3KNJUQHUatslLWyGw==", + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-25.7.0.tgz", + "integrity": "sha512-zLBIYuW66SGwY7JNqGmiqeKiM92CYOs6xPibSRBPIeYGIfM1nE/8VCE8G0fGot2EfXENC4PbhktxLrQ0EK5Thg==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "3.0.6", + "@puppeteer/browsers": "3.2.0", "chromium-bidi": "17.0.2", - "devtools-protocol": "0.0.1653615", + "devtools-protocol": "0.0.1666840", "lilconfig": "^3.1.3", - "puppeteer-core": "25.4.0", + "puppeteer-core": "25.7.0", "typed-query-selector": "^2.12.2" }, "bin": { @@ -4701,14 +4701,14 @@ } }, "node_modules/puppeteer-core": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.4.0.tgz", - "integrity": "sha512-K1plkLOdeoUnGeT1OvdqF3qxl33v+Ra/uH5VyPEhXdMcpvGiEskHzxxEU3fgpccJpJLIipB/rPUsvkZRWeKqOA==", + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-25.7.0.tgz", + "integrity": "sha512-wgBBj7dU5ceGyoT2PCrJpkYOhxPY8mDOmcSKZP92Cj5GgqQ3kv/UxzawnOLxiYuupe4bDf/yiQm3bzs/1nI0rQ==", "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "3.0.6", + "@puppeteer/browsers": "3.2.0", "chromium-bidi": "17.0.2", - "devtools-protocol": "0.0.1653615", + "devtools-protocol": "0.0.1666840", "typed-query-selector": "^2.12.2", "webdriver-bidi-protocol": "0.4.2", "ws": "^8.21.1" @@ -4826,15 +4826,15 @@ } }, "node_modules/respec": { - "version": "37.2.0", - "resolved": "https://registry.npmjs.org/respec/-/respec-37.2.0.tgz", - "integrity": "sha512-Uyo3EmzYT/z/ZCXKpt2gmUfCGOZzji2w1oY5zuAWxK5iR9uvJA8Aa/JWS8KPe9wQT27iLQKQV8KMOzOmVJNGOA==", + "version": "37.3.0", + "resolved": "https://registry.npmjs.org/respec/-/respec-37.3.0.tgz", + "integrity": "sha512-I0ARzzQvR/qrCaJxPUwiY70SUHt7YtjhIxVfVN8yj9Nblbow84/qtRUdKqk8spqvDKqM+MVmm2gDCoUBZEay6A==", "license": "W3C", "dependencies": { "colors": "1.4.0", "finalhandler": "^2.1.1", - "marked": "^18.0.4", - "puppeteer": "^25.0.4", + "marked": "^18.0.9", + "puppeteer": "^25.5.0", "sade": "^1.8.1", "serve-static": "^2.2.1" }, diff --git a/package.json b/package.json index 8a06ad3..ffecbb7 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "cheerio": "^1.2.0", "highlight.js": "^11.11.1", "markdown-it": "^15.0.0", - "respec": "37.2.0", + "respec": "37.3.0", "yargs": "^18.1.0" }, "devDependencies": { From ba1e42ecf1806d8c81f9b46a644c20982e49b50f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2026 04:33:21 +0000 Subject: [PATCH 04/10] build(deps): bump respec from 37.3.0 to 37.3.2 Bumps [respec](https://github.com/speced/respec) from 37.3.0 to 37.3.2. - [Release notes](https://github.com/speced/respec/releases) - [Changelog](https://github.com/speced/respec/blob/main/CHANGELOG.md) - [Commits](https://github.com/speced/respec/compare/v37.3.0...v37.3.2) --- updated-dependencies: - dependency-name: respec dependency-version: 37.3.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index a16d007..bfe5610 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "cheerio": "^1.2.0", "highlight.js": "^11.12.0", "markdown-it": "^15.0.0", - "respec": "37.3.0", + "respec": "37.3.2", "yargs": "^18.1.0" }, "devDependencies": { @@ -4826,15 +4826,15 @@ } }, "node_modules/respec": { - "version": "37.3.0", - "resolved": "https://registry.npmjs.org/respec/-/respec-37.3.0.tgz", - "integrity": "sha512-I0ARzzQvR/qrCaJxPUwiY70SUHt7YtjhIxVfVN8yj9Nblbow84/qtRUdKqk8spqvDKqM+MVmm2gDCoUBZEay6A==", + "version": "37.3.2", + "resolved": "https://registry.npmjs.org/respec/-/respec-37.3.2.tgz", + "integrity": "sha512-nV+xI0C5QblPuD+6QCloCxFoeCNzHHs6f4UMNmSrfJoG98woWdJGSYELW2Hr02s1aGeH6jDn9bI91Fg41mlN0g==", "license": "W3C", "dependencies": { "colors": "1.4.0", "finalhandler": "^2.1.1", "marked": "^18.0.9", - "puppeteer": "^25.5.0", + "puppeteer": "^25.7.0", "sade": "^1.8.1", "serve-static": "^2.2.1" }, diff --git a/package.json b/package.json index ab179c2..fdcf885 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "cheerio": "^1.2.0", "highlight.js": "^11.12.0", "markdown-it": "^15.0.0", - "respec": "37.3.0", + "respec": "37.3.2", "yargs": "^18.1.0" }, "devDependencies": { From 5c7d1767cab9b38aebe6620c113dc72985550a97 Mon Sep 17 00:00:00 2001 From: Lorna Jane Mitchell Date: Sat, 8 Aug 2026 21:35:21 +0100 Subject: [PATCH 05/10] Remove scripts folder, scripts are provided by new package --- scripts/adjust-release-branch.sh | 37 ---- scripts/md2html/.gitignore | 2 - scripts/md2html/analytics/google.html | 8 - scripts/md2html/build.sh | 84 ------- scripts/md2html/gist.css | 75 ------- scripts/md2html/main.css | 237 -------------------- scripts/md2html/md2html.js | 304 -------------------------- scripts/md2html/style-finish.html | 1 - scripts/md2html/style-start.html | 5 - scripts/md2html/syntax-github.css | 99 --------- scripts/schema-publish.sh | 91 -------- scripts/start-release.sh | 98 --------- scripts/validate.mjs | 52 ----- 13 files changed, 1093 deletions(-) delete mode 100644 scripts/adjust-release-branch.sh delete mode 100644 scripts/md2html/.gitignore delete mode 100644 scripts/md2html/analytics/google.html delete mode 100755 scripts/md2html/build.sh delete mode 100644 scripts/md2html/gist.css delete mode 100644 scripts/md2html/main.css delete mode 100644 scripts/md2html/md2html.js delete mode 100644 scripts/md2html/style-finish.html delete mode 100644 scripts/md2html/style-start.html delete mode 100644 scripts/md2html/syntax-github.css delete mode 100755 scripts/schema-publish.sh delete mode 100644 scripts/start-release.sh delete mode 100755 scripts/validate.mjs diff --git a/scripts/adjust-release-branch.sh b/scripts/adjust-release-branch.sh deleted file mode 100644 index 28ecc1a..0000000 --- a/scripts/adjust-release-branch.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -# Author: @ralfhandl - -# Run this script from the root of the repo. It is designed to be run manually in a release branch. - -branch=$(git branch --show-current) -today=$(date +%Y-%m-%d) - -if [[ ! $branch =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rel$ ]]; then - echo "This script is intended to be run from a release branch, e.g. v1.1.0-rel" - exit 1 -fi - -vVersion=$(basename "$branch" "-rel") -version=${vVersion:1} -echo Prepare release of $version - -# create snapshot of current editors -cp EDITORS.md versions/$version-editors.md - -# "move" dev version of spec to release version - git will treat this as a rename -# Replace release date placeholder with current date - should only appear in the history table -sed "s/| TBD |/| $today |/g" versions/$version-dev.md > versions/$version.md -# show what changed in the spec - should only be the history table line for the current release -diff -Z versions/$version-dev.md versions/$version.md -# remove dev version of spec -rm versions/$version-dev.md - -# rename schemas dev folder and tests folder if present -vMinor=$(echo $vVersion | cut -d. -f1,2) -if [ -d "schemas/$vMinor-dev" ]; then - mv "schemas/$vMinor-dev" "schemas/$vMinor" -fi -if [ -d "tests/$vMinor-dev" ]; then - mv "tests/$vMinor-dev" "tests/$vMinor" -fi diff --git a/scripts/md2html/.gitignore b/scripts/md2html/.gitignore deleted file mode 100644 index 1251657..0000000 --- a/scripts/md2html/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.err -input.bs diff --git a/scripts/md2html/analytics/google.html b/scripts/md2html/analytics/google.html deleted file mode 100644 index dce8d08..0000000 --- a/scripts/md2html/analytics/google.html +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/scripts/md2html/build.sh b/scripts/md2html/build.sh deleted file mode 100755 index 0b7f60a..0000000 --- a/scripts/md2html/build.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash - -# Author: @ralfhandl (inspired by the work of @MikeRalphson) - -# run this script from the root of the repo -# It is designed to be run by a GitHub workflow - -# Usage: build.sh [version | "latest" | "dev"] -# When run with no arguments, it builds artifacts for all published specification versions. -# It may also be run with a specific version argument, such as "1.0.0" or "latest" -# Finally, it may be run with "dev" to build "versions/*-dev.md" -# -# It contains bashisms - -if [ "$1" = "dev" ]; then - deploydir="deploy-preview" -else - deploydir="deploy/overlay" -fi - -mkdir -p $deploydir/js -mkdir -p $deploydir/temp -cp -p node_modules/respec/builds/respec-w3c.* $deploydir/js/ - -latest=$(git describe --abbrev=0 --tags) - -if [ -z "$1" ]; then - specifications=$(ls -1 versions/[1-9].[0-9].[0-9].md | sort -r) -elif [ "$1" = "latest" ]; then - specifications=$(ls -1 versions/$latest.md) -elif [ "$1" = "dev" ]; then - specifications=$(ls -1 versions/[1-9].[0-9].[0-9]-dev.md | sort -r) -else - specifications=$(ls -1 versions/$1.md) -fi - -latestCopied="none" -lastMinor="-" - -for specification in $specifications; do - version=$(basename "$specification" .md) - - destination="$deploydir/v$version.html" - if [ "$1" = "dev" ]; then - maintainers="EDITORS.md" - else - maintainers="$(dirname $specification)/$version-editors.md" - fi - - minorVersion=${version:0:3} - tempfile="$deploydir/temp/$version.html" - tempfile2="$deploydir/temp/$version-2.html" - - echo === Building $version to $destination - - node scripts/md2html/md2html.js --maintainers $maintainers $specification "$allVersions" > $tempfile - npx respec --no-sandbox --use-local --timeout 20 --src $tempfile --out $tempfile2 - # remove unwanted Google Tag Manager and Google Analytics scripts - sed -e 's/'; - preface += `\n`; - preface += '\n'; - preface += ''; - preface += `

${title.split('|')[0]}

`; - preface += ``; - preface += `

${abstract}

\n`; - preface += options.abstract.join('\n'); - preface += '
'; - preface += '
'; - preface += '

Status of This Document

'; - preface += 'The source-of-truth for this specification is the HTML file referenced above as This version.'; - preface += '
'; - - return preface; -} - -function doMaintainers() { - let m = fs.readFileSync(argv.maintainers,'utf8'); - let h = md.render(m); - let $ = cheerio.load(h); - let u = $('ul').first(); - $(u).children('li').each(function(e){ - let t = $(this).text().split('@')[0]; - maintainers.push({name:t}); - }); - if ($("ul").length < 2) return; - u = $("ul").last(); - $(u).children('li').each(function(e){ - let t = $(this).text().split('@')[0]; - emeritus.push({name:t}); - }); -} - -function getPublishDate(m) { - let result = new Date(); - let h = md.render(m); - let $ = cheerio.load(h); - $('table').each(function(i,table){ - const h = $(table).find('th'); - const headers = []; - $(h).each(function(i,header){ - headers.push($(header).text()); - }); - if (headers.length >= 2 && headers[0] === 'Version' && headers[1] === 'Date') { - let c = $(table).find('tr').find('td'); - let v = $(c[0]).text(); - let d = $(c[1]).text(); - argv.subtitle = v; - if (d !== 'TBD') result = new Date(d); - } - }); - return result; -} - -if (argv.maintainers) { - doMaintainers(); -} - -let s = fs.readFileSync(argv._[0],'utf8'); - -argv.publishDate = getPublishDate(s); - -let lines = s.split(/\r?\n/); - -let prevHeading = 0; -let inTOC = false; -let inDefs = false; -let inCodeBlock = false; -let indents = [0]; -let inAbstract = false; -argv.abstract = []; - -// process the markdown -for (let l in lines) { - let line = lines[l]; - - // extract Abstract - if (line.startsWith('## Abstract')) { - inAbstract = true; - line = ''; - } - else if (line.startsWith('#')) inAbstract = false; - else if (inAbstract) { - argv.abstract.push(line); - line = ''; - } - - // remove TOC from older spec versions, respec will generate a new one - if (line.startsWith('## Table of Contents')) inTOC = true; - else if (line.startsWith('#')) inTOC = false; - if (inTOC) line = ''; - - // special formatting for Definitions section - if (line.startsWith('## Definitions')) { - inDefs = true; - } - else if (line.startsWith('## ')) inDefs = false; - - // recognize code blocks - if (line.startsWith('```')) { - inCodeBlock = !inCodeBlock; - } - - // replace with - respec can't deal with it, and mdv needs it for link checks - line = line.replace(/<\/a>/g,''); - - line = line.split('\\|').join('|'); // was ¦ - - if (!inCodeBlock) { - // minor fixups to get RFC links to work properly - line = line.replace(/\[RFC ?([0-9]{1,5})\]\(/g,'[[RFC$1]]('); - - // handle url fragments in RFC links and construct section links as well as RFC links - line = line.replace(/\]\]\(https:\/\/tools.ietf.org\/html\/rfc([0-9]{1,5})\/?(\#[^)]*)?\)/g, function(match, rfcNumber, fragment) { - if (fragment) { - // Extract section title from the fragment - let sectionTitle = fragment.replace('#', '').replace(/-/g, ' '); - sectionTitle = sectionTitle.charAt(0).toUpperCase() + sectionTitle.slice(1); // Capitalize the first letter - //TODO: section links to https://www.rfc-editor.org/rfc/rfc* for newer RFCs (>= 8700) - return `]] [${sectionTitle}](https://datatracker.ietf.org/doc/html/rfc${rfcNumber}${fragment})`; - } else { - return ']]'; - } - }); - } - - // fix indentation of headings - // - make sure that each heading is at most one level deeper than the previous heading - // - reduce heading level by one if we're in respec mode except for h1 - if (!inCodeBlock && line.startsWith('#')) { - let indent = 0; - while (line[indent] === '#') indent++; - let originalIndent = indent; - - let prevIndent = indents[indents.length-1]; // peek - let delta = indent-prevIndent; - - if (indent > 1) { - indent--; - } - let newIndent = indent; - - let title = line.split('# ')[1]; - if (inDefs) title = ''+title+''; - line = ('#'.repeat(newIndent)+' '+title); - - if (delta>0) indents.push(originalIndent); - if (delta<0) { - let d = Math.abs(delta); - while (d>0) { - indents.pop(); - d--; - } - } - } - - // wrap section text in
...
tags for respec - if (!inCodeBlock && line.startsWith('#')) { - let heading = 0; - while (line[heading] === '#') heading++; - let delta = heading-prevHeading; - if (delta>1) console.warn(delta,line); - if (delta>0) delta = 1; - let prefix = ''; - let newSection = '
'; - const m = line.match(/# Version ([0-9.]+)$/); - if (m) { - // our conformance section is headlined with 'Version x.y.z' - // and respec needs a conformance section in a "formal" specification - newSection = '
'; - // adjust the heading to be at level 2 because respec insists on h2 here - // Note: older specs had this at h4, newer specs at h2, and all heading levels have been reduced by 1 in the preceding block - line = '#' + m[0]; - delta = 1; - heading = 2; - } - if (line.includes('Appendix')) { - newSection = '
'; - } - - // heading level delta is either 0 or is +1/-1, or we're in respec mode - // respec insists on
...
breaks around headings - - if (delta === 0) { - prefix = '
'+newSection; - } - else if (delta > 0) { - prefix = newSection.repeat(delta); - } - else { - prefix = '
'+('
').repeat(Math.abs(delta))+newSection; - } - prevHeading = heading; - line = prefix+md.render(line); - } - - lines[l] = line; -} - -s = preface(`Overlay Specification v${argv.subtitle} | Introduction, Definitions, & More`,argv)+'\n\n'+lines.join('\n'); -let out = md.render(s); -console.log(out); diff --git a/scripts/md2html/style-finish.html b/scripts/md2html/style-finish.html deleted file mode 100644 index 5d2c91d..0000000 --- a/scripts/md2html/style-finish.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/scripts/md2html/style-start.html b/scripts/md2html/style-start.html deleted file mode 100644 index cfb7bf7..0000000 --- a/scripts/md2html/style-start.html +++ /dev/null @@ -1,5 +0,0 @@ -