.
57 |
58 | *** Note this is a placeholder registry. Don't take the values seriously. ***
59 |
60 | Initial contents of the registry will include:
61 |
62 | |Name |Link |Description |
63 | |--- | --- | --- |
64 | |jsonSchema |TBD |JSON Schema | |xsdSchema |TBD |XML Schema |
65 |
66 | ## Backwards compatibility
67 |
68 | This proposal makes use of the extensibility features of OpenAPI. All changes sould appear as extensions and handled accordingly.
69 |
70 | ## Alternatives considered
71 |
72 | Embedding non-JSON content in the OAS document would have imposed an unacceptable burden on tooling. Therefore, an external link was preferred. Considerable discussion was held over exactly how the links should be represented in the Schema Object. The selected option should support the greatest number of possible combinations of external schema that can be expressed with the OpenAPI schema language.
73 |
74 |
--------------------------------------------------------------------------------
/proposals/2019-12-24-Overlays.md:
--------------------------------------------------------------------------------
1 | # Overlays
2 |
3 | ## Metadata
4 |
5 | |Tag |Value |
6 | |---- | ---------------- |
7 | |Proposal |[2019-12-24-Overlays](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/2019-12-24-Overlays.md)|
8 | |Authors|[Darrel Miller](https://github.com/darrelmiller)|
9 | |Status |Proposal|
10 | |Issues |[1442](https://github.com/OAI/OpenAPI-Specification/issues/1442) [1722](https://github.com/OAI/OpenAPI-Specification/issues/1722)|
11 |
12 | ## Change Log
13 |
14 | |Date |Responsible Party |Description |
15 | |---- | ---------------- | ---------- |
16 | | 24th December 2019 | Darrel Miller | Initial draft |
17 | | 2nd January 2019 | Darrel Miller | Update to wording around removing items from arrays. Added section on backward compatibility. Clarified process around applying a set of updates. Started to add supported scenarios.|
18 | | 29th July 2020 | Darrel Miller | Updated to be explicit about update operations |
19 |
20 | ## Introduction
21 |
22 | In recent months we have been discussing various use cases for overlays and various solutions. The following proposal takes a somewhat more radical approach to the problem. It is a more ambitious proposal than the others we have seen before but the additional complexity does allow for supporting many of the scenarios that have been discussed to date.
23 |
24 | #### Overlay Document
25 |
26 | An overlay document contains a list of [Update Objects](#overlayUpdates) that are to be applied to the target document. Each [Update Object](#updateObject) has a `target` property and a `value` property. The `target` property is a [JMESPath](http://jmespath.org/specification.html) query that identifies what part of the target document is to be updated and the `value` property contains an object with the properties to be overlaid.
27 |
28 |
29 | #### Overlay Object
30 |
31 | This is the root object of the [OpenAPI Overlay document](#oasDocument).
32 |
33 | ##### Fixed Fields
34 |
35 | Field Name | Type | Description
36 | ---|:---:|---
37 | overlay | `string` | Version of the Overlay specification that this document conforms to.
38 | info | [[Info Object](#overlayInfoObject)] | Identifying information about the overlay.
39 | extends | `url` | URL to an OpenAPI document this overlay applies to.
40 | updates | [[Update Object](#updateObject)] | A list of update objects to be applied to the target document.
41 |
42 | The list of update objects MUST be applied in sequential order to ensure a consistent outcome. Updates are applied to the result of the previous updates. This enables objects to be deleted in one update and then re-created in a subsequent update.
43 |
44 | The `extends` property can be used to indicate that the Overlay was designed to update a specific OpenAPI description. This is an optional property. Where no `extends` is provided it is the responsibility of tooling to apply the Overlay documents to the appropriate OpenAPI description.
45 |
46 | #### Info Object
47 |
48 | This object contains identifying information about the [OpenAPI Overlay document](#oasDocument).
49 |
50 | ##### Fixed Fields
51 |
52 | Field Name | Type | Description
53 | ---|:---:|---
54 | title | `string` | A human readable description of the purpose of the overlay.
55 | version | `string` | A version identifier for indicating changes to an overlay document.
56 |
57 | #### Update Object
58 |
59 | This object represents one or more changes to be applied to the target document at the location defined by the target JMESPath.
60 |
61 | ##### Fixed Fields
62 |
63 | Field Name | Type | Description
64 | ---|:---:|---
65 | target | `string` | A JMESPath expression referencing the target objects in the target document.
66 | add | [Any](#addObject) | An object to be added as a child of the object(s) referenced by the target. Property has no impact if `remove` property is `true`.
67 | merge | [Any](#mergeObject) | An object with the properties and values to be merged with the object(s) referenced by the target. Property has no impact if `remove` property is `true`.
68 | remove | `boolean` | A boolean value that indicates that the target object is to be removed from the the map or array it is contained in. The default value is false.
69 |
70 | The properties of the merge object MUST be compatible with the target object referenced by the JMESPath key. When the Overlay document is applied, the properties in the merge object replace properties in the target object with the same name and new properties are appended to the target object.
71 |
72 | ##### Structured Overlays Example
73 |
74 | When updating properties throughout the target document it may be more efficient to create a single `Update Object` that mirrors the structure of the target document. e.g.
75 |
76 | ```yaml
77 | overlay: 1.0.0
78 | info:
79 | title: Structured Overlay
80 | version: 1.0.0
81 | updates:
82 | - target: "@"
83 | merge:
84 | info:
85 | x-overlay-applied: structured-overlay
86 | paths:
87 | "/":
88 | summary: "The root resource"
89 | get:
90 | summary: "Retrieve the root resource"
91 | x-rate-limit: 100
92 | "/pets":
93 | get:
94 | summary: "Retrieve a list of pets"
95 | x-rate-limit: 100
96 | components:
97 | tags:
98 | ```
99 |
100 | ##### Targeted Overlays
101 |
102 | Alternatively, where only a small number of updates need to be applied to a large document, each [Update Object](#updateObject) can be more targeted.
103 |
104 | ```yaml
105 | overlay: 1.0.0
106 | info:
107 | title: Targeted Overlays
108 | version: 1.0.0
109 | updates:
110 | - target: paths."/foo".get
111 | merge:
112 | description: This is the new description
113 | - target: paths."/bar".get
114 | merge:
115 | description: This is the updated description
116 | - target: paths."/bar"
117 | merge:
118 | post:
119 | description: This is an updated description of a child object
120 | x-safe: false
121 | ```
122 |
123 | ##### Wildcard Overlays Examples
124 |
125 | One significant advantage of using the JMESPath syntax 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.
126 |
127 | ```yaml
128 | overlay: 1.0.0
129 | info:
130 | title: Update many objects at once
131 | version: 1.0.0
132 | updates:
133 | - target: paths.*.get
134 | merge:
135 | x-safe: true
136 | - target: paths.*.get.parameters[?name=='filter' && in=='query']
137 | merge:
138 | schema:
139 | $ref: "/components/schemas/filterSchema"
140 | ```
141 |
142 | ##### Array Modification Examples
143 |
144 | Due to the fact that we can now reference specific elements of the parameter array, it allows adding parameters. Parameters can be deleted using the `remove` property. Use of indexes to remove array items should be avoided where possible as indexes will change when items are removed.
145 |
146 | ```yaml
147 | overlay: 1.0.0
148 | info:
149 | title: Add an array element
150 | version: 1.0.0
151 | updates:
152 | - target: paths.*.get.parameters
153 | add:
154 | name: newParam
155 | in: query
156 | ```
157 |
158 | ```yaml
159 | overlay: 1.0.0
160 | info:
161 | title: Remove a array element
162 | version: 1.0.0
163 | updates:
164 | - target: paths[*].get.parameters[? name == 'dummy']
165 | remove: true
166 | ```
167 |
168 | ##### Traits Examples
169 |
170 | By annotating an OpenAPI description using extension such as `x-oai-traits` an author of OpenAPI description can identify where overlay updates should be applied.
171 |
172 | ```yaml
173 | openapi: 3.1.0
174 | info:
175 | title: Api with a paged collection
176 | version: 1.0.0
177 | paths:
178 | /items:
179 | get:
180 | x-oai-traits: ["paged"]
181 | responses:
182 | 200:
183 | description: OK
184 | ```
185 |
186 | With the above OpenAPI description, following Overlay document will apply the necessary updates to describe how paging is implemented, where that trait has been applied.
187 |
188 | ```yaml
189 | overlay: 1.0.0
190 | info:
191 | title: Apply Traits
192 | version: 1.0.0
193 | updates:
194 | - target: $.paths[*].get[?contains(x-traits,'paged')]
195 | merge:
196 | parameters:
197 | - name: top
198 | in: query
199 | - name: skip
200 | in: query
201 | ```
202 |
203 | This approach allows flipping control of where Overlays apply updates to the OpenAPI description itself.
204 |
205 | ## Proposal Summary
206 |
207 | ### Benefits
208 |
209 | - This approach addresses the two distinct approaches of structured overlay vs targeted overlay which suits distinct but equally valid scenarios.
210 | - Addresses the problem of modifying the parameters array and removes the need to replace the entire array when a small change is required.
211 | - Allows sets of related overlays to be stored in a same file.
212 | - Enables updating a set of objects based on a pattern. This might be an effective way of apply common behaviour across many operations in an API.
213 |
214 | ### Challenges
215 |
216 | - Tooling will need a JMESPath implementation.
217 | - Large overlays may be slow to process.
218 | - Multiple complex pattern based overlays may cause overlapping updates causing confusing outcomes.
219 |
220 | ## Alternatives considered
221 |
222 | JMESPath was chosen over JSONPath due to the fact that JMESPath has a [specification](http://jmespath.org/specification.html) and a set of test cases. This will help to ensure compatibility between implementations.
223 |
224 | ## Backwards compatibility
225 |
226 | Overlays will be described in a new specification that can be used alongside an OpenAPI Description, therefore there will be no compatibility issues for the initial release. Overlay documents can be used against OpenAPI v2 and v3 descriptions.
227 |
228 | ## Scenarios Considered
229 |
230 | - Multi-language support. An Overlay document for each language is used to target a specific OpenAPI description. The Overlay document will likely use a duplicate structure to the original OpenAPI description and replace all `description` properties.
231 | - Applying API wide standards. An Overlay document contains update objects that describe standard headers, parameters, responses. These documents would use JMESPath queries to target the appropriate objects in the OpenAPI description. Tooling could be used to target the OpenAPI description rather than using extends.
232 | - Add tool specific OpenAPI metadata. Overlay adds additional metadata such as SLA information, client codegen hints or middleware policies. Using Overlays to manage this data separately is valuable when there is a different audience for the data and/or there the information has different sensitivity levels.
233 |
--------------------------------------------------------------------------------
/proposals/2020-10-28-Experimental.md:
--------------------------------------------------------------------------------
1 | # Experimental marker
2 |
3 | ## Metadata
4 |
5 | |Tag |Value |
6 | |---- | ---------------- |
7 | |Proposal |[Experimental](https://github.com/OAI/OpenAPI-Specification/blob/main/proposals/2020-10-28-Experimental.md)|
8 | |Authors|[David Goss](https://github.com/davidjgoss)|
9 | |Review Manager |TBD |
10 | |Status |Proposal|
11 | |Implementations ||
12 | |Issues ||
13 | |Previous Revisions ||
14 |
15 | ## Change Log
16 |
17 | |Date |Responsible Party |Description |
18 | |---- | ---------------- | ---------- |
19 |
20 | ## Introduction
21 |
22 | A way to mark an aspect of the API as "experimental", indicating that it is not yet a fully stable and supported part of the API.
23 |
24 | ## Motivation
25 |
26 | Consider an API with two categories of thing in it:
27 |
28 | - Core, stable things, where we are committed to the ongoing stability and have no intention of making breaking changes.
29 | - New, experimental things, where we are getting them out there for feedback and early adopters, but they may change before we consider them to be in the first category, or even just get removed.
30 |
31 | These sit together fine in principle, but cause friction when trying to apply something like semver to the API as a whole. How do we make changes to the experimental stuff - without bumping the major version several times a year and scaring consumers - while also ensuring we can't make breaking changes to the core stuff we never _want_ to break.
32 |
33 | ## Proposed solution
34 |
35 | Add an "experimental" field which specifies that an items in the API is not yet fully stable and supported, may change or be removed without a major version bump, and as such should be used with caution.
36 |
37 | _(I don't have a strong opinion about the naming - "beta" is another idea, though I think "experimental" does the job better in terms of being the most noncommital.)_
38 |
39 | Downstream tools could then make use of this metadata:
40 |
41 | - Tools like swagger-ui could surface this in the documentation they generate so consumers are made aware. Experimental items could also be filtered out of the documentation and stubs if desired.
42 | - Tools for detecting and preventing breaking changes could take this into consideration when deciding whether a change is breaking.
43 |
44 | ## Detailed design
45 |
46 | A new boolean field named `experimental`, defaulting to `false`, is added to:
47 |
48 | - Operation
49 | - Parameter
50 | - Schema
51 |
52 | This specifies that the operation, parameter or schema is not yet stable and SHOULD be used with caution.
53 |
54 | ### Operation Object
55 |
56 | ...
57 |
58 | ##### Fixed Fields
59 |
60 | Field Name | Type | Description
61 | ---|:---:|---
62 | ... | ... | ...
63 | experimental | `boolean` | Specifies that an operation is in experimental status, meaning it may change outside of the normal breaking change process. Consumers SHOULD use with caution. Default value is `false`.
64 |
65 | ### Parameter Object
66 |
67 | ...
68 |
69 | ##### Fixed Fields
70 |
71 | Field Name | Type | Description
72 | ---|:---:|---
73 | ... | ... | ...
74 | experimental | `boolean` | Specifies that a parameter is in experimental status, meaning it may change outside of the normal breaking change process. Consumers SHOULD use with caution. Default value is `false`. Cannot be `true` when the parameter is `required`.
75 |
76 | ### Schema Object
77 |
78 | ...
79 |
80 | ##### Fixed Fields
81 |
82 | Field Name | Type | Description
83 | ---|:---:|---
84 | ... | ... | ...
85 | experimental | `boolean` | Specifies that a schema is in experimental status, meaning it may change outside of the normal breaking change process. Consumers SHOULD use with caution. Default value is `false`.
86 |
87 | ### Example Spec
88 |
89 | ```yaml
90 | /asset/constraints:
91 | get:
92 | tags:
93 | - Asset
94 | - Constraints
95 | summary: Get a set of asset constraints
96 | operationId: constraints
97 | parameters:
98 | - name: siteToken
99 | in: query
100 | description: Site token obtained from Site API
101 | required: true
102 | schema:
103 | type: string
104 | experimental: true
105 | ```
106 | ### Prior Art
107 |
108 | This kind of requirement is handled for TypeScript libraries by [api-extractor](https://api-extractor.com/pages/tsdoc/doc_comment_syntax/#release-tags) - they have both "alpha" and "beta" markers with a somewhat opinionated flow attached - I'm not sure that level of granularity is necessary. But the "beta" and "public" ones map well to the motivations described here:
109 |
110 | > - **beta**: Indicates that an API item has been released as a preview or for experimental purposes. Third parties are encouraged to try it and provide feedback. However, a “beta” API should NOT be used in production, because it may be changed or removed in a future version.
111 | > - **public**: Indicates that an API item has been officially released, and is now part of the supported contract for a package. If the SemVer versioning scheme is used, then the API signature cannot be changed without a MAJOR version increment.
112 |
113 | ### Unanswered Questions
114 |
115 | - If an operation is not marked as experimental, but it is using a schema which is (i.e. as its request object), then it is implicitly also unstable. Would this usage be considered invalid?
116 |
117 | ## Backwards compatibility
118 |
119 | The `experimental` field would default to false, meaning existing behaviour is preserved, and the new field is only used on an opt-in basis.
120 |
121 | `experimental` can coexist with `deprecated` - an operation, parameter or schema can be both experimental and deprecated, having never gotten to a stable point before being deprecated.
122 |
123 | ## Alternatives considered
124 |
125 | - _Specification extensions_ - publishers could add an extension in their own domain, but the benefit of the metadata being available to downstream tools (including those used by consumers, not just publishers) would be lost.
126 | - _Tags_ - as above, but this also gets to mixing other kinds of metadata in with resource taxonomy, which seems wrong.
127 | - _Overlays_ - The [Overlays proposal](https://github.com/OAI/OpenAPI-Specification/blob/main/proposals/2019-12-24-Overlays.md) is sufficiently powerful to be able to implement this, with a canonical spec representing the stable API and an overlay used to apply experimental additions. Downsides: not as ergonomic for authors, the OpenAPI specification would still not have "experimental" as a first-class concept so there'd be reliance on conventions being observed across the ecosystem for how it's done with overlays.
128 | - _Different API_ - this would be the least messy from a technical perspective - maintain a completely separate API for experimental items, and then "promote" them to the main API once they are considered stable. This has increased overhead for publishers and consumers, and could also reduce the likelihood of getting feedback on, and early uptake of, experimental items if they are segregated in a different place altogether.
129 |
130 |
--------------------------------------------------------------------------------
/proposals/2024-08-01-Self-Identification.md:
--------------------------------------------------------------------------------
1 | # Self-Identification
2 |
3 | ## Metadata
4 |
5 | |Tag |Value |
6 | |---- | ---------------- |
7 | |Proposal |[2024-08-01 Self-Identification](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/{2024-08-01-Self-Identification-and-Bundling.md})|
8 | |Relevant Specification(s)|OpenAPI Specification (OAS), Arazzo Specification|
9 | |Authors|[Henry Andrews](https://github.com/handrews)|
10 | |Review Manager | TBD |
11 | |Status |Proposal|
12 | |Implementations |n/a|
13 | |Issues | |
14 | |Previous Revisions | |
15 |
16 | ## Change Log
17 |
18 | |Date |Responsible Party |Description |
19 | |---- | ---------------- | ---------- |
20 | |2024-08-01 | @handrews | Initial submission
21 |
22 | ## Introduction
23 |
24 | OpenAPI 3.1 references are treated as identifiers rather than locators. This behavior is inherited from JSON Schema 2020-12, and is made more explicit in the forthcoming OAS 3.1.1 patch release. This separation can support stable, self-assigned identifiers which allow certain sorts of OpenAPI Description refactoring _without_ having to re-write the values of `"$ref"` and similar keywords. However, OAS lacks a mechanism to fully define such identifiers within each document, which substantially limits the benefits of this separation.
25 |
26 | ## Motivation
27 |
28 | One of the main motivations for separating identity (URIs/IRIs) and location (URLs) is to have stable, persistent identifiers regardless of the resource's location. Such identifiers are typically assigned within the resource. There are two varieties:
29 |
30 | * Setting the complete resource's absolute URI, which is also used as the resource's base URI per [RFC3986 §5.1.1](https://www.rfc-editor.org/rfc/rfc3986.html#section-5.1.1) (example: [the Schema Object's `$id`](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#name-the-id-keyword))
31 | * Setting a ["plain name" URI fragment](https://www.w3.org/TR/2012/WD-fragid-best-practices-20121025/#dfn-plain-name-fragid) that does not rely on the JSON/YAML structure of the document (example: [the Schema Object's `$anchor`](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#name-defining-location-independe), and technically also `$dynamicAnchor` although this proposal will not mention `$dynamicAnchor` further as its additional complexities are not relevant here).
32 |
33 | As suggested by the above examples, in OAS 3.1 only the Schema Object can set stable, location-independent identifiers. OpenAPI Description documents as a whole cannot do so, nor can other Objects within the document.
34 |
35 | Note also that due to the recursive structure of schemas, resolving the Schema Object's `$id` keyword can be complex, as each can itself be a relative URI-reference that is resolved against the `$id` in parent schemas. There is no clear use case for such complexity within other parts of an OpenAPI Description.
36 |
37 | ### Use Cases
38 |
39 | There are several use cases for separating identity and location, including:
40 |
41 | * Working around network challenges:
42 | * Restrictive network security policies
43 | * Intermittent connectivity
44 | * High latency / low bandwidth
45 | * Document hosts that [require authentication](https://github.com/OAI/OpenAPI-Specification/issues/3270)
46 | * Abstracting development vs testing vs deployment details
47 | * Allowing `.json` and `.yaml` file extensions during development, as is preferred by most IDEs
48 | * Using extensions in development and HTTP content negotiation in production
49 | * Differing source control repository structure (particularly of shared documents) vs deployment directory and server layouts
50 | * This separation is necessary (although not, on its own, sufficient) to implement [bundling](https://www.openapis.org/blog/2021/08/23/json-schema-bundling-finally-formalised).
51 |
52 | For a more detailed real-world example, see the [OGC example](https://github.com/OAI/sig-moonwalk/discussions/72#user-content-ogc) in the Moonwalk discussion on imports.
53 |
54 | Many of these use cases can be worked around, but only by restricting deployment options or performing error-prone reference target rewriting. Many tools that perform reference rewriting do not take into account the added complexities of referencing in OAS 3.1 compared to 3.0 and earlier.
55 |
56 | ### Prior Art
57 |
58 | Self-identification of resources with identity independent of location is common in the JSON Schema world. This demonstrates that implementation is not just feasible but well-proven, particularly given that JSON Schema's `$id` is more complex to support than this proposal.
59 |
60 | The JSON Schema package used by the [OASComply](https://github.com/OAI/oascomply) project includes a [schema catalog](https://jschon.readthedocs.io/en/latest/tutorial/catalog.html) with [configurable file and network sources](https://jschon.readthedocs.io/en/latest/examples/file_based_schemas.html) to manage the URI-to-URL mapping (local files can be considered `file:` URLs).
61 |
62 | Self-identification is common in other formats as well. Notably, the Atom format pioneered the use of [web links with `rel="self"`](https://www.rfc-editor.org/rfc/rfc4287.html#section-4.2.7.2) for this purpose.
63 |
64 | ## Proposed solution
65 |
66 | The proposal is a simplified analog of JSON Schema's `$id` that appears in exactly one place: a new `self` field in the root OpenAPI Object (OAS) and Arazzo Object (Arazzo). When referencing a document that has a `self` field, the `self` field SHOULD be used in reference values so that reference values remain the same even if the document is moved.
67 |
68 | Placing the `self` field only in the OpenAPI Object or Arazzo Object makes it align with the existing bootstrapping process for parsing:
69 |
70 | 1. Check the `openapi` or `arazzo` field in the root OpenAPI or Arazzo Object to determine the specification version
71 | 1. Check the `jsonSchemaDialect` field for the default Schema Object dialect
72 | 1. Determine the base URI per RFC3986 §5.1.2-5.1.4 (in most cases, use the retrieval URL per §5.1.3)
73 | 1. ***NEW*** Check the `self` field for a base URI per RFC3986 §5.1.1; if it exists, resolve it against the base URI from the previous step and use the result as the document's actual base URI
74 | 1. Continue parsing the remainder of the document as usual
75 |
76 | As [OAS 3.1.1 clarifies](https://github.com/OAI/OpenAPI-Specification/pull/3758), it is already mandatory to separate location and identity for Schema Object support.
77 |
78 | Currently, associating a URI other than the current URL with a document to meet this requirement has to be done externally. Many tools effectively support this by allowing the retrieval URL to be set manually, without verifying that the document actually lives at the given URL. However, this relies on users to make use of a non-standard implementation feature rather than offering well-defined behavior based on the document author's intent.
79 |
80 | With the new `self` field, tools need to be configured to know how to locate documents whose `self` values do not match their locations. The JSON Schema implementation linked under [Prior Art](#prior-art) above demonstrates several ways to accomplish this.
81 |
82 | ## Detailed design
83 |
84 | This is written for the structure of the OAS, but it should be clear how it would be adapted for Arazzo. Some amount of guidance around how to configure tools to resolve `self`-references that do not match locations probably also needs to be added in the sections on reference resolution and base URIs.
85 |
86 | ```MARKDOWN
87 | ## OpenAPI Object
88 |
89 | ### Fixed Fields
90 |
91 | Field Name | Type | Description
92 | ---|:---|:---
93 | self | `URI-reference` (without a fragment) | Sets the URI of this document, which also serves as its base URI in accordance with [RFC 3986 §5.1.1](https://www.rfc-editor.org/rfc/rfc3986#section-5.1.1); the value MUST NOT be the empty string and MUST NOT contain a fragment
94 | ```
95 |
96 | ## Backwards compatibility
97 |
98 | OAS 3.2 and Arazzo 1.1 documents that do not use the `self` field will behave exactly the same as OAS 3.1 and Arazzo 1.0 documents. The change in minor version is sufficient to manage the compatibility issues, as no software that only supports up to 3.1/1.0 should attempt to parse 3.2/1.1 documents.
99 |
100 | ## Alternatives considered
101 |
102 | ### Plain name fragments in every Object
103 |
104 | While including `self` in every Object would produce the same complexity as JSON Schema's nested `$id`, we could just adopt an equivalent of JSON Schema's `$anchor` keyword, which (like HTML/XML's `id` attribute) creates a plain name fragment that is not tied to the location of the Object in the JSON/YAML structure.
105 |
106 | Handling a fragment declaration keyword would require scanning all Objects for the keyword prior to declaring that a reference target with a plain name fragment cannot be resolved. This would likely be done on document load, but could be deferred and done incrementally as-needed when unknown fragments are encountered.
107 |
108 | Support for `$anchor` in JSON Schema demonstrates that this is feasible, and the mental model is familiar to most from HTML. But it would be a bit more work to support.
109 |
110 | While it would be a significant advantage to have completely location-independent referencing support, this is given as an alternative because the `self` field is a pre-requisite, and can be added whether we later support plain name fragments or not.
111 |
--------------------------------------------------------------------------------
/proposals/2024-09-01-Tags-Improvement.md:
--------------------------------------------------------------------------------
1 | # Tags Improvement
2 |
3 |
4 | ## Metadata
5 |
6 | |Tag |Value |
7 | |---- | ---------------- |
8 | |Proposal |[2024-09-01-Tags-Improvement](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/{2024-09-01-Tags-Improvement.md})|
9 | |Authors|[Lorna Mitchell](https://github.com/lornajane)|
10 | |Review Manager | TBD |
11 | |Status |Proposal|
12 | |Implementations | |
13 | |Issues | [1367](https://github.com/OAI/OpenAPI-Specification/issues/1367), [2843](https://github.com/OAI/OpenAPI-Specification/issues/2843), |
14 | |Previous Revisions | None, but see [Moonwalk discussion](https://github.com/OAI/sig-moonwalk/discussions/67)
15 |
16 | ## Change Log
17 |
18 | |Date |Responsible Party |Description |
19 | |---- | ---------------- | ---------- |
20 | | 2024-09-01 | @lornajane | Initial draft |
21 |
22 | ## Introduction
23 |
24 | Evolve the existing `tags` implementation to (optionally) support more use cases, such as giving the tags some grouping/relationships and adding more metadata.
25 |
26 | ## Motivation
27 |
28 | The tags feature hasn't changed since the spec was still called Swagger, but it's one of the most-extended aspects of OpenAPI with most tools supporting some sort of grouping or additional metadata. One motivation for this proposal is to "pave the cowpath" and formalise some of the patterns from those extensions as part of the specification.
29 |
30 | The existing tags implementation is also quite limiting, so users/tools feel they "cannot" use tags, because they are so widely implemented for documentation navigation and required exactly one tag per operation, to be used only for this single purpose or to be opted out using extensions such as `x-traitTag`. The result is that we see lots of extensions that add arbitrary metadata to operations, some of them even become part of the specification officially (looking at you, `deprecated: true`) or being so widely used that we should probably adopt them (`x-internal`, `x-experimental`). The specification does have a way of tagging operations, but it's too limited and the result is that everything has to be added as an extension field.
31 |
32 | On a personal note, I work for a tool vendor and was proposing these changes internally; but the problems affect all OpenAPI users so I brought it to the main project.
33 |
34 | ### Supporting evidence
35 |
36 | There are several examples "in the wild" of where a better tags implementation would have helped. Here is a selection of publicly-accessible examples to illustrate some of the problems this proposal could help with:
37 |
38 | - Grouping of tags is a very common use case, almost everyone uses some sort of extra hierarchy to group the tags themselves, which makes sense as our APIs are only getting more complex, something like [`x-tagGroups`](https://redocly.com/docs/api-reference-docs/specification-extensions/x-tag-groups/) is a good example - and there's a [very active open issue on OpenAPI specification itself](https://github.com/OAI/OpenAPI-Specification/issues/1367)
39 | - Various tag-alike additions exist, sometimes called "badges" or similar; I'd include extensions such as [`x-internal`](https://redocly.com/docs/cli/guides/hide-apis/#step-1-add-x-internal-to-the-api-description) as a tag-alike since they could be tags if more than one tag (or tag type) could be applied.
40 | - Additional display metadata is also in active use in the wild, see [`x-displayName`](https://redocly.com/docs/api-reference-docs/specification-extensions/x-display-name) and this [OpenAPI specification issue](https://github.com/OAI/OpenAPI-Specification/issues/2843)
41 |
42 | ## Proposed solution
43 |
44 | Originally proposed in a [Moonwalk discussion](https://github.com/OAI/sig-moonwalk/discussions/67), I am proposing three backwards-compatible additions to the existing tags feature:
45 |
46 | * Tags get a `summary` alongside `name` and `description`. In keeping with our existing practices: name is the identifier, summary is the short display content, and description is available in contexts where more information is appropriate.
47 | * A `parent` field is added to support a hierarchy without adding either separators or a new data type. Your tag can belong to another tag.
48 | * A `kind` field to explain which family of tags this tag belongs to (previously proposed as `type`). We'd expecting these to be `nav`, `badge`, `internal` and probably some other things that other tooling types would find useful.
49 |
50 | An example could look something like this:
51 |
52 | ```yaml
53 | tags:
54 | - name: deprecated
55 | kind: internal
56 | summary: Deprecated
57 | description: This operation has been deprecated and will be removed in the future. Avoid using items with this tag.
58 | - name: shop
59 | kind: nav
60 | summary: Order Online
61 | description: Operations relating to the retail operations behind the [online shopping site](https://example.com/shopping).
62 | - name: products
63 | kind: nav
64 | parent: shop
65 | summary: Products
66 | description: View and manage the product catalog.
67 | - name: orders
68 | kind: nav
69 | parent: shop
70 | summary: Online Orders
71 | description: Place, fulfil and invoice orders for the online shop.
72 |
73 | ```
74 |
75 | Rather than making an allowed list of kinds, we will instead leave that open for user extension and keep a list of the recommended/expected types in a registry and evolve that as conventions emerge.
76 |
77 | ## Detailed design
78 |
79 | The following section is an updated specification section, for the top-level tags object only (no other changes are needed):
80 |
81 | ---
82 |
83 | #### Tag Object
84 |
85 | Adds metadata to a single tag that is used by the [Operation Object](#operation-object).
86 | Each tag used in the Operation Object instances MAY have a Tag Object defined.
87 |
88 | ##### Fixed Fields
89 |
90 | Field Name | Type | Description
91 | ---|:---:|---
92 | name | `string` | **REQUIRED**. The name of the tag. Use this value in the `tags` array of an Operation.
93 | summary | `string` | A short summary of the tag, used for display purposes.
94 | description | `string` | A description for the tag. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
95 | externalDocs | [External Documentation Object](#external-documentation-object) | Additional external documentation for this tag.
96 | parent | `string` | The `name` of a tag that this tags is nested under. The named tag MUST exist in the API description, and circular references between parent and child tags MUST NOT be used.
97 | kind | `string` | A machine-readable string to categorize what sort of tag it is. Common uses are `nav` for Navigation, `badge` for badges, `internal` for internal APIs, but any string value can be used. A registry of known values is available.
98 |
99 | This object MAY be extended with [Specification Extensions](#specification-extensions).
100 |
101 | ##### Tag Object Example
102 |
103 | ```json
104 | {
105 | "name": "account-updates",
106 | "summary": "Account Updates",
107 | "description": "Account update operations",
108 | "kind": "nav"
109 | },
110 | {
111 | "name": "partner",
112 | "summary": "Partner",
113 | "description": "Operations available to the partners network",
114 | "parent": "external",
115 | "kind": "audience"
116 | },
117 | {
118 | "name": "external",
119 | "summary": "External",
120 | "description": "Operations available to external consumers",
121 | "kind": "audience"
122 | }
123 | ```
124 |
125 | ```yaml
126 | - name: account-updates
127 | summary: Account Updates
128 | description: Account update operations
129 | kind: nav
130 |
131 | - name: partner
132 | summary: Partner
133 | description: Operations available to the partners network
134 | parent: external
135 | kind: audience
136 |
137 | - name: external
138 | summary: External
139 | description: Operations available to external consumers
140 | kind: audience
141 | ```
142 |
143 | ---
144 |
145 | ## Backwards compatibility
146 |
147 | All new fields are optional, so existing API descriptions will remain valid and useful.
148 | Some users may wish to adopt some of the following steps on upgrade:
149 |
150 | - Set `kind: nav` if their existing tags are currently used for navigation entries in documentation tooling.
151 | - Change `x-displayName` in `tag` objects to `summary` instead.
152 | - Add a tag to replace each `x-tagGroups` entry, and set the `parent` field for each of the tags in the groups.
153 | - Change `x-badges` extensions to instead be a tag with `kind: badge`.
154 | - Change features like `x-internal` to be a tag with a specific `kind` set. Similarly some lifecycle use cases such as `x-beta` could be replaced with tags.
155 |
156 | ## Alternatives considered
157 |
158 | - Continue to use tags as-is, and extend the spec for each use case that users need rather than providing an open metadata implementation.
159 | We've been slow to iterate and I would rather "open" the options than try to control them.
160 | The API space evolves quite quickly.
161 |
162 | - Set `children` rather than `parent` on the tags and operate a top-down relationship.
163 | The suggestion of allowing multiple links or a graph approach was also mentioned.
164 | In both cases, there are good ideas in every direction, but our responsibility is to implement a structure that users can easily understand and maintain.
165 |
166 |
--------------------------------------------------------------------------------
/proposals/2025-03-20-URIs-for-Tags.md:
--------------------------------------------------------------------------------
1 | # URIs for Tags
2 |
3 |
4 | ## Metadata
5 |
6 | |Tag |Value |
7 | |---- | ---------------- |
8 | |Proposal |[2025-03-20-URIs-for-Tags](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/{2025-03-20-URIs-for-Tags.md})|
9 | |Authors|[Henry Andrews](https://github.com/handrews)|
10 | |Review Manager | [Lorna Mitchell](https://github.com/lornajane) |
11 | |Status | rejected |
12 | |Implementations | n/a |
13 | |Issues |[#2905 Allow the use of $ref and json pointer in tags](https://github.com/OAI/OpenAPI-Specification/issues/2905), consolidated into [#3853 Consolidated $ref-to-Some Object feature request](https://github.com/OAI/OpenAPI-Specification/issues/3853)|
14 | |Previous Revisions |n/a|
15 |
16 | ## Change Log
17 |
18 | |Date |Responsible Party |Description |
19 | |---- | ---------------- | ---------- |
20 | |2025-03-20 | @handrews | Initial publication |
21 | |2025-03-26 | @handrews | Document rejection |
22 |
23 | ## Introduction
24 |
25 | Tags are the last remaining [implicit connection](https://spec.openapis.org/oas/v3.1.1#resolving-implicit-connections) that do not have a URI-based alternative for deterministic, universal referencing (Security Requirement Objects are fixed in [PR #4388](https://github.com/OAI/OpenAPI-Specification/pull/4388), currently awaiting re-approval after review feedback changes).
26 | This proposal adds such an alternative, giving tags the same capabilities as all other similar mechanisms within the OAS.
27 |
28 | ## Motivation
29 |
30 | ### A user request and proposal
31 |
32 | From @SandroG in issue #2905 (which is only closed because it was consolidated into #3853), which got two further thumbs-ups:
33 |
34 | _**[NOTE:** The mechanism proposed here is **not** the one favored by this proposal, which is explained further down]_
35 |
36 | > I have a large specification, which I need to break down in different files. I use an approach where each file is like a sub-specification that lists all endpoints regarding the same subject and then I include these endpoints in the main openapi file.
37 | > The documentation of a tag is in the same file as the endpoint that uses it.
38 | >
39 | > I'm not able to reuse that tag declaration in the main file, so I'm not able to include the description of the tag.
40 | >
41 | > For example, I have a separate file for customer's endpoints
42 |
43 | `customers.yaml`
44 | ```YAML
45 | info:
46 | ...
47 | tags:
48 | - name: Customer
49 | description: APIs to manage customers. A customer is a representation of ...
50 |
51 | paths:
52 | /customers/{id}/:
53 | parameters:
54 | - name: id
55 | . . .
56 | get:
57 | . . .
58 | /customers/:
59 | . . .
60 | ```
61 | > I need to do this:
62 |
63 | `openapi.yaml`
64 | ```YAML
65 | info:
66 | ...
67 | tags:
68 | - $ref: "./customers.yaml#/tags/0"
69 |
70 | paths:
71 | /customers/{id}/:
72 | $ref: "./customers.yaml#/paths/~customers~1{id}~1"
73 | /customers/:
74 | $ref: "./customers.yaml#/paths/~customers~1"
75 | ```
76 |
77 | ### Proof of confusion over tag to Tag Object resolution
78 |
79 | In the above example, @SandroG proposes using `$ref` for Tag Objects to pull Tag Objects from one [OpenAPI Document](https://spec.openapis.org/oas/v3.1.1#openapi-document) into another, where they can be used by the `tags` field in Operation Objects.
80 | This makes clear that they expect tags to be resolved from the _current document_, which may be a [referenced document rather than the entry document](https://spec.openapis.org/oas/v3.1.1#openapi-description).
81 |
82 | However, in [3.0.4](https://spec.openapis.org/oas/v3.0.4#resolving-implicit-connections) and [3.1.1](https://spec.openapis.org/oas/v3.1.1#resolving-implicit-connections) we RECOMMEND (== SHOULD) that tag names are resolved to Tag Objects in the _entry document_.
83 | This means that there is no way to resolve them from the current document, which is the mirror image of the problem as that encountered by @SandroG.
84 |
85 | In today's TDC call, @lornajane stated that she expects tag names to be resolved from the entry document, and @kevinswiber expressed doubt that anyone implements anything else (sadly @SandroG does not mention their tool, which presumably resolves from the current document or else they would not have explained the issue in this way).
86 |
87 | ### Fragility of JSON Pointers with arrays
88 |
89 | Tag Objects are ordered, and tools MAY treat the ordering as significant for presentation purposes. JSON Pointers include the array index, which will change whenever someone decides to re-order the tag display, breaking any URI references that include a JSON Pointer.
90 | However, the use of the `name` field and the requirement that all Tag Objects in a list have a unique name mean that it is only necessary to identify the OpenAPI Object (or as a simpler proxy, the OpenAPI Document) in which to find the list of Tag Objects.
91 | Once the correct OpenAPI Document is identified, the list can be searched by name as it is now.
92 |
93 | ### Additional scenarios
94 |
95 | Another scenario to consider is a standards group that is publishing OpenAPI Documents that are intended to be used by multiple API providers.
96 | Such standards groups have no control over the entry documents used, so if they wish to provide Tag Objects, they MUST place them in the shared, referenced document.
97 | If the API provider wishes to use those Tag Objects in their entry document, or in their own referenced documents, then they currently cannot do.
98 |
99 | ## Proposed solution
100 |
101 | A new field or fields would be added to identify, with a URI, the OpenAPI Document from which a tag MUST be resolved.
102 | This would bring tags into alignment with other implicitly resolved names (e.g. Schema names in the Discriminator Object and Security Scheme names in the Security Requirement Object), with the variation that only the Document rather than the exact Object is identified.
103 |
104 | ## Detailed design
105 |
106 | In the Tag Object, a `parentDocument` field would be an optional URI qualifier to the `parent` field, and only allowed if `parent` is present.
107 |
108 | In the Operation Object, a `tagRefs` field would be added alongside the `tags` field.
109 | This new field would be a map with a Document URI as the keys, and an array of tags (as in the `tags` field) as the values.
110 | Tags under `tagRefs` would be resolved within the document identified by the key, while tags within `tags` would continue to be RECOMMENDED to resolve from the entry document.
111 |
112 | ## Backwards compatibility
113 |
114 | The proposal is fully backwards compatible.
115 |
116 | ## Alternatives considered
117 |
118 | The option proposed by @SandroG would require the Operation Object's `tags` field to resolve from the current document, which would be a breaking change and therefore not possible in 3.2.
119 |
120 | @baywet proposed a top-level (per-document) association of URIs and tags, to reduce the number of places where it is necessary to look for URIs.
121 | However, this requires duplicating tags that would otherwise only appear in Operation Objects in the top-level field, and does not fully solve the namespacing issue as each tag could only resolve from one place, rather than allowing the same tag name to have different meanings by resolving it to a different Tag Object in a different document.
122 |
123 | @karenetheridge proposed treating tags like `operationId` and resolving within the entire description (a PR to this proposal with more details of this alternative would be welcome).
124 | To me, `operationId` is not a good precedent to follow, as we already have to provide numerous disclaimers regarding collisions in the specification text, and the results are not well-defined.
125 | While we could make collisions an error for this new mechanism, @baywet noted that trying to prevent such collisions is highly burdensome in large organizations (although @karenetheridge similarly pointed to experience of it working).
126 | The fact that `operationRef` had to be included to provide a URI-based alternative to using `operationId` in the Link Object is a strong piece of evidence in favor of a URI-based solution for tags.
127 |
128 | ## Outcome
129 |
130 | Rejected per @lornajane, with concurrence by @ralfhandl:
131 |
132 | > I am not in favour of these additions for the 3.x branch. I wish that we'd implemented tags differently in the first place, and I'm sure that all the constructive discussion around the tags feature will help us a lot in future major releases.
133 | >
134 | > I believe that the limitations of the current tag situation can be overcome with helper tooling and that this change (while solving a narrow but valid use case) adds complexity to the specification that is unnecessary and does not benefit the majority of users. As custodians of a widely-used standard, we have a responsibility to maintain something that is appropriate for its audience, and we should be "reluctant" in all our changes unless we see that they are really needed.
135 | >
136 | > I propose that users would be equally well served by leaving the requirement to resolve tags from the entry document. Organisations can either maintain an extensive list of tags in all OpenAPI documents, and then remove any that aren't used before publishing (tooling exists for this use case), or alternatively if a tool wants to include tags found in the wider context of referenced OpenAPI documents by adding them to the top-level tags array during processing, that would work well too.
137 | >
138 | > The tags array is a list of strings. It isn't an ID like the Operation uses, and it's not a named entry like the security schemes, so it is appropriate to approach the limitations of it differently. My proposal is to offer some advice or documentation on approaching this problem, but not to bring it in scope of the specification for 3.x since other options are available.
139 |
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | * Chuck Heazel [@cmheazel](https://github.com/cmheazel)
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/alternative_schema_object.md:
--------------------------------------------------------------------------------
1 | ## Change: Add the Alternative Schema Object
2 |
3 | The following text is to be inserted after the XML Object section
4 |
5 | ### Alternative Schema Object
6 |
7 | This object makes it possible to reference an external file that contains a schema that does not follow the OAS specification. If tooling does not support the _type_, tooling MUST consider the content valid but SHOULD provide a warning that the alternative schema was not processed.
8 |
9 | ## Fixed Fields
10 |
11 | |Field Name | Type | Description |
12 | |---|:---:|---|
13 | |type | string | **REQUIRED**. The value MUST match one of the values identified in the alternative Schema Registry. |
14 | |location | url | **REQUIRED**. This is a absolute or relative reference to an external resource containing a schema of a known type. This reference may contain a fragment identifier to reference only a subset of an external document. |
15 |
16 | This object MAY be extended with Specification Extensions.
17 |
18 |
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/examples.md:
--------------------------------------------------------------------------------
1 | ## Change: Add Alternative Schema Examples
2 |
3 | The following text is to be inserted after the Alternative Schema Object section.
4 |
5 | ### Alternative Schema Examples
6 |
7 | Minimalist usage of alternative schema:
8 |
9 | schema:
10 | x-oas-draft-alternativeSchema:
11 | type: jsonSchema
12 | location: ./real-jsonschema.json
13 |
14 | Combination of OAS schema and alternative:
15 |
16 | schema:
17 | type: object
18 | nullable: true
19 | x-oas-draft-alternativeSchema:
20 | type: jsonSchema
21 | location: ./real-jsonschema.json
22 |
23 | Multiple different versions of alternative schema:
24 |
25 | schema:
26 | anyOf:
27 | - x-oas-draft-alternativeSchema:
28 | type: jsonSchema
29 | location: ./real-jsonschema-08.json
30 | - x-oas-draft-alternativeSchema:
31 | type: jsonSchema
32 | location: ./real-jsonschema-07.json
33 |
34 | Combined alternative schemas:
35 |
36 | schema:
37 | allOf:
38 | - x-oas-draft-alternativeSchema:
39 | type: xmlSchema
40 | location: ./xmlSchema.xsd
41 | - x-oas-draft-alternativeSchema:
42 | type: schematron
43 | location: ./schema.sch
44 |
45 | Mixed OAS schema and alternative schema:
46 |
47 | schema:
48 | type: array
49 | items:
50 | x-oas-draft-alternativeSchema:
51 | type: jsonSchema
52 | location: ./real-jsonschema.json
53 |
54 |
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/implementations.md:
--------------------------------------------------------------------------------
1 | # Implementations
2 |
3 | ## Overview
4 |
5 | Below is a list of tooling that claims to implement the Alternative Schema proposal. While support for this feature matures, refer to the details of projects listed below for any notes about stability and roadmap. The process to improve the OpenAPI specification includes feedback from end-users and tooling creators. We strongly encourage draft tooling be made available for early users of OAS drafts.
6 |
7 | These tools are not endorsed by the OAI
8 |
9 | ## Implementations:
10 |
11 | #### Low-Level tooling
12 |
13 | | Title | Project Link | Language | Description
14 | | ----------- | ----------- | ----------- | -----------
15 | |TBD |TBD |TBD |TBD |
16 |
17 | #### Editors
18 |
19 | | Title | Project Link | Language |Description |
20 | |----------------|--------------|----------|---------------------|
21 | |TBD |TBD |TBD |TBD |
22 |
23 | #### User Interfaces
24 |
25 | | Title | Project Link | Language |Description |
26 | |----------------|--------------|----------|---------------------|
27 | |TBD |TBD |TBD |TBD |
28 |
29 | #### Mock Servers
30 | | Title | Project Link | Language | Description |
31 | | -------------- | ------------ | -------- | ----------- |
32 | |TBD |TBD |TBD |TBD |
33 |
34 | #### Server Implementations
35 | | Title | Project Link | Language |Description |
36 | |----------------|--------------|----------|---------------------|
37 | |TBD |TBD |TBD |TBD |
38 |
39 | #### Code Generators
40 |
41 | | Title | Project Link | Language |Description |
42 | |----------------|--------------|----------|---------------------|
43 | |TBD |TBD |TBD |TBD |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/schema_object.md:
--------------------------------------------------------------------------------
1 | ## Change: Extend the Schema Object to support Alternative Schemas
2 |
3 | The following content shall be used to replace the Fixed Fields table in the Schema Object section
4 |
5 | #### Fixed Fields
6 |
7 | |Field Name | Type | Description |
8 | |---|:---:|---|
9 | | nullable | `boolean` | Allows sending a `null` value for the defined schema. Default value is `false`.|
10 | | discriminator | [Discriminator Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#discriminatorObject) | Adds support for polymorphism. The discriminator is an object name that is used to differentiate between other schemas which may satisfy the payload description. See [Composition and Inheritance](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#schemaComposition) for more details. |
11 | | readOnly | `boolean` | Relevant only for Schema `"properties"` definitions. Declares the property as "read only". This means that it MAY be sent as part of a response but SHOULD NOT be sent as part of the request. If the property is marked as `readOnly` being `true` and is in the `required` list, the `required` will take effect on the response only. A property MUST NOT be marked as both `readOnly` and `writeOnly` being `true`. Default value is `false`. |
12 | | writeOnly | `boolean` | Relevant only for Schema `"properties"` definitions. Declares the property as "write only". Therefore, it MAY be sent as part of a request but SHOULD NOT be sent as part of the response. If the property is marked as `writeOnly` being `true` and is in the `required` list, the `required` will take effect on the request only. A property MUST NOT be marked as both `readOnly` and `writeOnly` being `true`. Default value is `false`. |
13 | | xml | [XML Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#xmlObject) | This MAY be used only on properties schemas. It has no effect on root schemas. Adds additional metadata to describe the XML representation of this property. |
14 | | externalDocs | [External Documentation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#externalDocumentationObject) | Additional external documentation for this schema.
15 | | example | Any | A free-form property to include an example of an instance for this schema. To represent examples that cannot be naturally represented in JSON or YAML, a string value can be used to contain the example with escaping where necessary.|
16 | | deprecated | `boolean` | Specifies that a schema is deprecated and SHOULD be transitioned out of usage. Default value is `false`.|
17 | |x-oas-draft-alternativeSchema |alternative Schema Object |An external schema that participates in the validation of content along with other schema keywords. |
18 |
--------------------------------------------------------------------------------
/proposals/Overlays/Changes.yml:
--------------------------------------------------------------------------------
1 | # Create update methods (add,replace,merge,delete)? Is merge necessary?
2 | # Multiple additions or updates to the same target is more efficient with merge
3 |
4 | # Different than JSON Patch because is works in JSON and YAML
5 | # Has info object and spec version
6 | # values
7 |
8 | overlay: 1.0.0
9 | info:
10 | title: An example of an overlay that captures changes to an API
11 | version: 1.0.0
12 | updates:
13 | # Add a property to a schema
14 | - target: components.schemas."todo".properties
15 | merge:
16 | createdBy:
17 | type: string
18 | # Add constraints to a schema
19 | - target: components.schemas."todo"
20 | merge:
21 | additionalProperties: false
22 | - target: components.schemas."todo"
23 | merge:
24 | type: ["object","null"]
25 | #Change a schema
26 | - target: components.schemas."todo"
27 | replace:
28 | type: integer
29 | # Add multiple constraints to a schema using merge
30 | - target: components.schemas."todo"
31 | merge:
32 | additionalProperties: false
33 | type: ["object","null"]
34 | # Add multiple constraints to a schema using merge
35 | - target: components.schemas."todo"
36 | merge:
37 | additionalProperties: false
38 | type: ["object","null"]
39 | properties:
40 | someprop:
41 | type: string
42 | # Add an operation
43 | - target: paths."/foo"
44 | add:
45 | delete:
46 | description: delete a foo
47 | responses:
48 | 200:
49 | description: ok
50 | # Add a path
51 | - target: paths
52 | add:
53 | "/items":
54 | get:
55 | responses:
56 | 200:
57 | description: ok
58 | # Add an optional query parameter
59 | - target: paths."/bar".parameters
60 | add:
61 | name: skip
62 | in: query
63 | type: string
64 | # Mark an operation as deprecated
65 |
66 | # Change the value of a JSON schema constraint
67 | # Update the version of the API
68 | # Change the license of an API
69 | # Add support for a new request media type
70 | # Add support for a new response media type
71 |
--------------------------------------------------------------------------------
/proposals/Overlays/MergePatch.yml:
--------------------------------------------------------------------------------
1 | overlay: 1.0.0
2 | info:
3 | title: An example of an overlay that performs a Merge Patch
4 | version: 1.0.0
5 | updates:
6 | - target: "@"
7 | merge:
8 | openapi: 3.0.3
9 | paths: {}
10 |
11 |
--------------------------------------------------------------------------------
/scripts/adjust-release-branch.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Author: @ralfhandl
4 |
5 | # Run this script from the root of the repo. It is designed to be run manually in a release branch.
6 |
7 | branch=$(git branch --show-current)
8 |
9 | if [[ ! $branch =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rel$ ]]; then
10 | echo "This script is intended to be run from a release branch, e.g. v3.1.2-rel"
11 | exit 1
12 | fi
13 |
14 | vVersion=$(basename "$branch" "-rel")
15 | version=${vVersion:1}
16 | echo Prepare release of $version
17 |
18 | cp EDITORS.md versions/$version-editors.md
19 | mv src/oas.md versions/$version.md
20 | rm -r src/schemas
21 | rm -r tests/schema
22 |
--------------------------------------------------------------------------------
/scripts/close-no-recent.ps1:
--------------------------------------------------------------------------------
1 | $inactivityDelay = [timespan]::FromDays([int]::Parse($Env:NO_RECENT_ACTIVITY_DURATION_CLOSE_IN_DAYS))
2 | $oldIssues = gh issue list --label "$Env:NO_RECENT_ACTIVITY_LABEL" --state open --limit 100 --json number,author,createdAt,labels | ConvertFrom-Json | Where-Object {$_.labels.name -notcontains $Env:NEEDS_ATTENTION_LABEL }
3 | foreach($oldIssue in $oldIssues) {
4 | $lastComment = gh issue view $oldIssue.number --json comments | ConvertFrom-Json | Select-Object -ExpandProperty comments | Where-Object {$_.author.login -eq $oldIssue.author.login} | Select-Object -Last 1
5 | if($null -eq $lastComment) {
6 | $lastCommentDate = [Nullable[datetime]]$null
7 | } else {
8 | $lastCommentDate = $lastComment.createdAt #powershell already parses the date for us with the json conversion
9 | }
10 | $lastLabelEvent = gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" "/repos/$($Env:ORG_NAME)/$($Env:REPO_NAME)/issues/$($oldIssue.number)/events?per_page=100" | ConvertFrom-Json | Where-Object {$_.event -eq "labeled" -and $_.label.name -eq "$Env:NO_RECENT_ACTIVITY_LABEL"} | Select-Object -Last 1
11 | $lastLabelEventDate = $lastLabelEvent.created_at
12 | if ($null -ne $lastCommentDate -and $lastCommentDate -gt $lastLabelEventDate) {
13 | gh issue edit $oldIssue.number --remove-label "$Env:NO_RECENT_ACTIVITY_LABEL" --remove-label "$Env:NEEDS_AUTHOR_FEEDBACK_LABEL" --add-label "$Env:NEEDS_ATTENTION_LABEL"
14 | } elseif (([datetime]::UtcNow - $lastLabelEventDate) -ge $inactivityDelay) {
15 | gh issue close $oldIssue.number -r "not planned"
16 | }
17 | }
--------------------------------------------------------------------------------
/scripts/fwdabort.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Aborts a fwdport.sh run cleanly
4 |
5 | # Author: @MikeRalphson
6 |
7 | git am -i --abort
8 | rm -f *.mbox *.patch *.rej
9 | git checkout main
10 |
11 |
--------------------------------------------------------------------------------
/scripts/fwdport.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Forward ports changes from the spec file of a source branch to the spec file of a target branch
4 | # For example: porting interim changes made in v3.1.x patch releases to the v3.2.0 branch
5 |
6 | # This script is designed to be run once per branch, when interim changes need merging in
7 | # before another branch is released. It is not intended to be run multiple times to keep
8 | # two branches in sync.
9 |
10 | # Author: @MikeRalphson
11 | # Issues: https://github.com/OAI/OpenAPI-Specification/pull/2163
12 |
13 | mainbranch=main
14 | myremote=origin
15 | upstream=upstream
16 |
17 | source=$1
18 | target=$2
19 |
20 | if [ -z "$source" ]; then
21 | echo You must specify a source and target branch
22 | exit 1
23 | fi
24 | if [ -z "$target" ]; then
25 | echo You must specify a source and target branch
26 | exit 1
27 | fi
28 |
29 | echo Checking working dir...
30 | status=`git ls-files -m`
31 | if [ -z "$status" ]; then
32 | echo All clear
33 | else
34 | echo You have a dirty working tree, aborting
35 | echo ${status}
36 | exit 1
37 | fi
38 |
39 | cruft=`ls -1 *.patch *.rej *.mbox 2>/dev/null`
40 | if [ -z "$cruft" ]; then
41 | echo No .patch, .rej or .mbox files found, continuing
42 | else
43 | echo .patch / .rej / .mbox files found, aborting
44 | exit 1
45 | fi
46 |
47 | tmpbranch=forward-port-${source}
48 | existing=`git branch | grep ${tmpbranch}`
49 | if [ -z "$existing" ]; then
50 | echo No matching temp branch found, continuing
51 | else
52 | echo Temp branch ${tmpbranch} already exists, aborting
53 | exit 1
54 | fi
55 |
56 | srcver=`echo $source | sed s/-dev//g | sed s/v//g`.md
57 | tgtver=`echo $target | sed s/-dev//g | sed s/v//g`.md
58 |
59 | echo Forward-porting changes from ${source}:versions/${srcver} to ${target}:${tgtver}
60 | echo You may use the commands \'git fwdskip\' and \'git fwdcont\' to skip patches, or to continue after manually fixing.
61 | echo Use `fwdabort.sh` to abort cleanly.
62 | echo
63 | echo Due to a bug in \`git am\`, git v2.22.1+ is required, you\'re running:
64 | git --version
65 | echo
66 | echo Press a key to continue...
67 | read
68 |
69 | git config --add rerere.enabled true
70 | git config alias.fwdskip '!git am -i --skip'
71 | git config alias.fwdcont '!git am -i --continue'
72 |
73 | git checkout ${source}
74 | git pull ${upstream} ${source}
75 |
76 | # look at using git merge-base as an alternative? say if we branched 3.1.0 part way through 3.0.2's life
77 |
78 | firstsrc=`git log --abbrev-commit --format=format:%H -n 1 --reverse -- versions/${srcver}`
79 | lastsrc=`git log --abbrev-commit --format=format:%H -- versions/${srcver} | tail -n 1`
80 | changes=`git log --format=format:%H --reverse versions/${srcver}`
81 |
82 | echo Applying changes from ${firstsrc} to ${lastsrc}
83 |
84 | # remove first (creation) commit and uniq without sorting
85 | oIFS="$IFS"
86 | IFS=' '
87 | changes=`echo ${changes} | tail -n +2 | awk '!x[$0]++'`
88 | IFS="$oIFS"
89 |
90 | for c in ${changes}; do
91 | git format-patch --stdout -1 $c | sed s/${srcver}/${tgtver}/g > $c.patch
92 | done
93 |
94 | git checkout ${target}
95 | git pull ${upstream} ${target}
96 | git checkout -b ${tmpbranch}
97 | cat *.patch > fwdport.mbox
98 | rm -f *.patch
99 | git am -3 --interactive --ignore-whitespace -s fwdport.mbox
100 |
101 |
--------------------------------------------------------------------------------
/scripts/label-no-recent.ps1:
--------------------------------------------------------------------------------
1 | $inactivityDelay = [timespan]::FromDays([int]::Parse($Env:NO_RECENT_ACTIVITY_DURATION_IN_DAYS))
2 | $oldIssues = gh issue list --label "$Env:NEEDS_AUTHOR_FEEDBACK_LABEL" --state open --limit 100 --json number,author,createdAt,labels | ConvertFrom-Json | Where-Object {$_.labels.name -notcontains $Env:NO_RECENT_ACTIVITY_LABEL }
3 | foreach($oldIssue in $oldIssues) {
4 | $lastComment = gh issue view $oldIssue.number --json comments | ConvertFrom-Json | Select-Object -ExpandProperty comments | Where-Object {$_.author.login -eq $oldIssue.author.login} | Select-Object -Last 1
5 | if($null -eq $lastComment) {
6 | $lastCommentDate = [Nullable[datetime]]$null
7 | } else {
8 | $lastCommentDate = $lastComment.createdAt #powershell already parses the date for us with the json conversion
9 | }
10 | $lastLabelEvent = gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" "/repos/$($Env:ORG_NAME)/$($Env:REPO_NAME)/issues/$($oldIssue.number)/events?per_page=100" | ConvertFrom-Json | Where-Object {$_.event -eq "labeled" -and $_.label.name -eq "$Env:NEEDS_AUTHOR_FEEDBACK_LABEL"} | Select-Object -Last 1
11 | $lastLabelEventDate = $lastLabelEvent.created_at
12 | if ($null -ne $lastCommentDate -and $lastCommentDate -gt $lastLabelEventDate) {
13 | gh issue edit $oldIssue.number --remove-label "$Env:NO_RECENT_ACTIVITY_LABEL" --remove-label "$Env:NEEDS_AUTHOR_FEEDBACK_LABEL" --add-label "$Env:NEEDS_ATTENTION_LABEL"
14 | } elseif (([datetime]::UtcNow - $lastLabelEventDate) -ge $inactivityDelay) {
15 | gh issue edit $oldIssue.number --add-label "$Env:NO_RECENT_ACTIVITY_LABEL" --remove-label "$Env:NEEDS_ATTENTION_LABEL"
16 | gh issue comment $oldIssue.number -b "$Env:NO_RECENT_ACTIVITY_COMMENT"
17 | }
18 | }
--------------------------------------------------------------------------------
/scripts/md2html/.gitignore:
--------------------------------------------------------------------------------
1 | *.err
2 | input.bs
3 |
--------------------------------------------------------------------------------
/scripts/md2html/analytics/google.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/scripts/md2html/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Author: @MikeRalphson
4 |
5 | # run this script from the root of the repo
6 | # It is designed to be run by a GitHub workflow
7 |
8 | # Usage: build.sh [version | "latest" | "src"]
9 | # When run with no arguments, it builds artifacts for all published specification versions.
10 | # It may also be run with a specific version argument, such as "3.1.1" or "latest"
11 | # Finally, it may be run with "src" to build "src/oas.md"
12 | #
13 | # It contains bashisms
14 |
15 | if [ "$1" = "src" ]; then
16 | deploydir="deploy-preview"
17 | else
18 | deploydir="deploy/oas"
19 | fi
20 |
21 | mkdir -p $deploydir/js
22 | mkdir -p $deploydir/temp
23 | cp -p node_modules/respec/builds/respec-w3c.* $deploydir/js/
24 |
25 | latest=$(git describe --abbrev=0 --tags)
26 |
27 | allVersions=$(ls -1 versions/[23456789].*.md | grep -v -e "\-editors" | sort -r)
28 |
29 | if [ -z "$1" ]; then
30 | specifications=$allVersions
31 | elif [ "$1" = "latest" ]; then
32 | specifications=$(ls -1 versions/$latest.md)
33 | elif [ "$1" = "src" ]; then
34 | specifications="src/oas.md"
35 | else
36 | specifications=$(ls -1 versions/$1.md)
37 | fi
38 |
39 | latestCopied="none"
40 | lastMinor="-"
41 |
42 | for specification in $specifications; do
43 | version=$(basename $specification .md)
44 |
45 | if [ "$1" = "src" ]; then
46 | destination="$deploydir/$version.html"
47 | maintainers="EDITORS.md"
48 | else
49 | destination="$deploydir/v$version.html"
50 | maintainers="$(dirname $specification)/$version-editors.md"
51 | fi
52 |
53 | minorVersion=${version:0:3}
54 | tempfile="$deploydir/temp/$version.html"
55 | tempfile2="$deploydir/temp/$version-2.html"
56 |
57 | echo === Building $version to $destination
58 |
59 | node scripts/md2html/md2html.js --maintainers $maintainers $specification "$allVersions" > $tempfile
60 | npx respec --no-sandbox --use-local --src $tempfile --out $tempfile2
61 | # remove unwanted Google Tag Manager and Google Analytics scripts
62 | sed -e 's/
4 |
10 |
11 | OpenAPI Specification v30.0.1 | Introduction, Definitions, & More
12 |
13 |
14 | OpenAPI Specification v30.0.1
Copyright © 3001 the Linux Foundation
What is the OpenAPI Specification?
The OpenAPI Specification (OAS) defines a standard, programming language-agnostic interface description for HTTP APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, the OpenAPI Specification removes guesswork in calling a service.Status of This Document
The source-of-truth for this specification is the HTML file referenced above as This version.
15 | Heading 1
16 | Text for first chapter
17 | Heading 2
20 | Text for first section
21 | Broken anchor
22 | Heading 3
23 | Text for first subsection
24 |
25 |
26 |
27 | Version |
28 | Date |
29 |
30 |
31 |
32 |
33 | 30.0.1 |
34 | 3001-04-01 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/tests/md2html/fixtures/basic-old.maintainers:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Foo Bar [@foobar](https://github.com/foobar)
3 |
--------------------------------------------------------------------------------
/tests/md2html/fixtures/basic-old.md:
--------------------------------------------------------------------------------
1 | # Heading 1
2 |
3 | Text for first chapter
4 |
5 | #### Version 30.0.1
6 |
7 | This is the conformance section
8 |
9 | ## Table of Contents
10 |
11 | Will be removed
12 |
13 | ## Heading 2
14 |
15 | Text for first section
16 |
17 | Broken anchor
18 |
19 | ### Heading 3
20 |
21 | Text for first subsection
22 |
23 |
24 | Version | Date
25 | --------|-----------
26 | 30.0.1 | 3001-04-01
27 |
--------------------------------------------------------------------------------
/tests/md2html/md2html.test.mjs:
--------------------------------------------------------------------------------
1 | import { readdirSync, readFileSync } from "node:fs";
2 | import { execFile } from "node:child_process";
3 | import { resolve } from "node:path";
4 | import { describe, test, expect } from "vitest";
5 | import assert from "node:assert";
6 |
7 | const folder = "./tests/md2html/fixtures/";
8 | describe("md2html", async () => {
9 | readdirSync(folder, { withFileTypes: true })
10 | .filter((entry) => entry.isFile() && /\.md$/.test(entry.name))
11 | .forEach((entry) => {
12 | test(entry.name, async () => {
13 | const expected = readFileSync(
14 | folder + entry.name.replace(".md", ".html"),
15 | "utf8",
16 | );
17 | const output = await md2html(
18 | [
19 | "--maintainers",
20 | entry.name.replace(".md", ".maintainers"),
21 | entry.name,
22 | "path/31.0.0.md\npath/30.0.1.md\npath/30.0.0.md",
23 | ],
24 | folder,
25 | );
26 | expect(output.stdout).to.equal(expected);
27 | });
28 | });
29 | });
30 |
31 | function md2html(args, cwd) {
32 | return new Promise((res) => {
33 | execFile(
34 | "node",
35 | [`${resolve("./scripts/md2html/md2html.js")}`, ...args],
36 | { cwd },
37 | (error, stdout, stderr) => {
38 | res({
39 | code: error?.code || 0,
40 | error,
41 | stdout,
42 | stderr,
43 | });
44 | },
45 | );
46 | });
47 | }
48 |
--------------------------------------------------------------------------------
/versions/2.0-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
3 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
4 | * Ron Ratovsky [@webron](https://github.com/webron)
5 | * Tony Tam [@fehguy](https://github.com/fehguy)
6 |
--------------------------------------------------------------------------------
/versions/3.0.0-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
3 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
4 | * Ron Ratovsky [@webron](https://github.com/webron)
5 | * Tony Tam [@fehguy](https://github.com/fehguy)
6 |
7 | ## Emeritus
8 | * Jason Harmon [@jharmn](https://github.com/jharmn)
9 |
--------------------------------------------------------------------------------
/versions/3.0.1-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
3 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
4 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
5 | * Ron Ratovsky [@webron](https://github.com/webron)
6 |
7 | ## Emeritus
8 | * Jason Harmon [@jharmn](https://github.com/jharmn)
9 | * Tony Tam [@fehguy](https://github.com/fehguy)
10 |
--------------------------------------------------------------------------------
/versions/3.0.2-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
3 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
4 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
5 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
6 | * Ron Ratovsky [@webron](https://github.com/webron)
7 | * Uri Sarid [@usarid](https://github.com/usarid)
8 |
9 | ## Emeritus
10 | * Jason Harmon [@jharmn](https://github.com/jharmn)
11 | * Tony Tam [@fehguy](https://github.com/fehguy)
12 |
--------------------------------------------------------------------------------
/versions/3.0.3-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
3 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
4 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
5 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
6 | * Ron Ratovsky [@webron](https://github.com/webron)
7 | * Uri Sarid [@usarid](https://github.com/usarid)
8 |
9 | ## Emeritus
10 | * Jason Harmon [@jharmn](https://github.com/jharmn)
11 | * Tony Tam [@fehguy](https://github.com/fehguy)
12 |
--------------------------------------------------------------------------------
/versions/3.0.4-editors.md:
--------------------------------------------------------------------------------
1 | # OpenAPI Specification Editors
2 |
3 | ## Active
4 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
5 | * Henry Andrews [@handrews](https://github.com/handrews)
6 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
7 | * Lorna Mitchell [@lornajane](https://github.com/lornajane)
8 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
9 | * Miguel Quintero [@miqui](https://github.com/miqui)
10 | * Mike Kistler [@mikekistler](https://github.com/mikekistler)
11 | * Ralf Handl [@ralfhandl](https://github.com/ralfhandl)
12 | * Ron Ratovsky [@webron](https://github.com/webron)
13 |
14 | ## Emeritus
15 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
16 | * Uri Sarid [@usarid](https://github.com/usarid)
17 | * Jason Harmon [@jharmn](https://github.com/jharmn)
18 | * Tony Tam [@fehguy](https://github.com/fehguy)
19 |
--------------------------------------------------------------------------------
/versions/3.1.0-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
3 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
4 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
5 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
6 | * Ron Ratovsky [@webron](https://github.com/webron)
7 | * Uri Sarid [@usarid](https://github.com/usarid)
8 |
9 | ## Emeritus
10 | * Jason Harmon [@jharmn](https://github.com/jharmn)
11 | * Tony Tam [@fehguy](https://github.com/fehguy)
12 |
--------------------------------------------------------------------------------
/versions/3.1.1-editors.md:
--------------------------------------------------------------------------------
1 | # OpenAPI Specification Editors
2 |
3 | ## Active
4 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
5 | * Henry Andrews [@handrews](https://github.com/handrews)
6 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
7 | * Lorna Mitchell [@lornajane](https://github.com/lornajane)
8 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
9 | * Miguel Quintero [@miqui](https://github.com/miqui)
10 | * Mike Kistler [@mikekistler](https://github.com/mikekistler)
11 | * Ralf Handl [@ralfhandl](https://github.com/ralfhandl)
12 | * Ron Ratovsky [@webron](https://github.com/webron)
13 |
14 | ## Emeritus
15 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
16 | * Uri Sarid [@usarid](https://github.com/usarid)
17 | * Jason Harmon [@jharmn](https://github.com/jharmn)
18 | * Tony Tam [@fehguy](https://github.com/fehguy)
19 |
--------------------------------------------------------------------------------
/vitest.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vitest/config'
2 |
3 | export default defineConfig({
4 | test: {
5 | forceRerunTriggers: ['**/scripts/**', '**/tests/**'],
6 | },
7 | })
--------------------------------------------------------------------------------