Skip to content

Commit d84aba0

Browse files
authored
Merge branch 'v3.3-dev' into 3.3-test-unevaluatedProperrties
2 parents 0cf186d + b50b1ed commit d84aba0

File tree

9 files changed

+492
-489
lines changed

9 files changed

+492
-489
lines changed

.github/workflows/sync-dev-to-vX.Y-dev.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ jobs:
6363
--body "Merge relevant changes from \`$HEAD\` into \`$BASE\`.")
6464
echo ""
6565
echo "PR to sync $BASE with $HEAD: $PR"
66-
sleep 10 # allow status checks to be triggered
66+
sleep 60 # allow status checks to be triggered
6767
6868
gh pr checks $PR --watch --required || continue
6969
gh pr merge $PR --merge --admin

CONTRIBUTING.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,19 @@ Schemas are updated in and directly published from the `vX.Y-dev` branches.
257257

258258
As part of the publishing process, the YAML source files are converted to JSON, renamed to the relevant last-changed dates, and `WORK-IN-PROGRESS` placeholders are replaced with these dates as appropriate. This is usually done by the [`schema-publish` workflow](https://github.com/OAI/OpenAPI-Specification/blob/main/.github/workflows/schema-publish.yaml) which detects changes on each `vX.Y-dev` branch, which generates a pull request for publishing the new schema iterations to the [spec site](https://spec.openapis.org). The workflow can also be run manually if required.
259259

260+
#### Schemas and OAS Requirements
261+
262+
The schemas published by the OpenAPI Initiative _only_ validate mandatory
263+
OAS requirements. This means that a field value or combination with another
264+
field is only forbidden in a schema if there is a corresponding MUST / MUST NOT /
265+
SHALL / SHALL NOT requirement that prevents it.
266+
267+
Schemas that apply further restrictions to enforce desired usage are outside
268+
of the scope of the OpenAPI Initiative. When opening an issue or PR for
269+
schema changes, please ensure that the changes are backed by clear OAS
270+
requirements. Otherwise, the issue or PR will be closed with a note pointing
271+
to this section.
272+
260273
## Release Process and Scope
261274

262275
This section relates to the 3.x versions only.

package-lock.json

Lines changed: 385 additions & 441 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@
2020
"validate-markdown": "npx markdownlint-cli2 --config spec.markdownlint.yaml src/oas.md && npx markdownlint-cli2 *.md && npx linkspector check"
2121
},
2222
"dependencies": {
23-
"cheerio": "^1.1.2",
23+
"cheerio": "^1.2.0",
2424
"highlight.js": "^11.11.1",
2525
"markdown-it": "^14.1.0",
26-
"respec": "35.6.1",
26+
"respec": "35.8.0",
2727
"yargs": "^18.0.0"
2828
},
2929
"devDependencies": {
3030
"@hyperjump/json-schema-coverage": "^1.2.1",
3131
"@umbrelladocs/linkspector": "^0.4.7",
32-
"@vitest/coverage-v8": "^4.0.17",
33-
"c8": "^10.1.3",
34-
"markdownlint-cli2": "^0.20.0",
32+
"@vitest/coverage-v8": "^4.0.18",
33+
"c8": "^11.0.0",
34+
"markdownlint-cli2": "^0.21.0",
3535
"vitest": "^4.0.1",
3636
"yaml": "^2.8.2"
3737
},

scripts/schema-publish.sh

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,27 @@ publish_schema() {
4242

4343
# rename or create the jekyll lander markdown file for this iteration
4444
if [ ! -z "$jekyllLander" ]; then
45-
mv $jekyllLander $target.md
46-
echo " * $newestCommitDate: $schema & jekyll lander $(basename $jekyllLander)"
45+
if [ "$jekyllLander" = "$target.md" ]; then
46+
echo " * $base did not change since $date"
47+
else
48+
mv $jekyllLander $target.md
49+
echo " * $base: $date added & jekyll lander moved from $(basename $jekyllLander)"
50+
fi
4751
else
4852
# find the most recent preceding version
4953
local lastdir=""; for fn in $(dirname $deploydir)/?.?; do test "$fn" "<" "$deploydir" && lastdir="$fn"; done
5054
local lastVersion=$(basename $lastdir)
5155
# find the jekyll lander markdown file for the preceding version
52-
local lastLander=$(find "$lastdir/$base" -maxdepth 1 -name "*.md")
56+
local lastLander=$(find "$lastdir/$base" -maxdepth 1 -name "*.md" 2>/dev/null)
5357

5458
if [ ! -z "$lastLander" ]; then
5559
# copy and adjust the lander file from the preceding version
5660
sed "s/$lastVersion/$version/g" $lastLander > $target.md
57-
echo " * $newestCommitDate: $schema & jekyll lander $(basename $lastLander) of $lastVersion"
61+
echo " * $base: $date added & jekyll lander copied from $(basename $lastLander) of $lastVersion"
5862
else
59-
echo " * $newestCommitDate: $schema"
63+
echo " * $base: $date added"
6064
fi
6165
fi
62-
6366
}
6467

6568
echo === Building schemas into $deploydir
@@ -72,7 +75,7 @@ maxDate=""
7275
sedCmds=()
7376
for schema in "${schemas[@]}"; do
7477
if [ -f "$schemaDir/$schema" ]; then
75-
newestCommitDate=$(git log -1 --format="%ad" --date=short "$schemaDir/$schema")
78+
newestCommitDate=$(git log -1 --format="%cd" --date=short "$schemaDir/$schema")
7679

7780
# the newest date across a schema and all its dependencies is its date stamp
7881
if [ "$newestCommitDate" \> "$maxDate" ]; then

src/oas.md

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ The path itself is still exposed to the documentation viewer but they will not k
607607
| <a name="path-item-head"></a>head | [Operation Object](#operation-object) | A definition of a HEAD operation on this path. |
608608
| <a name="path-item-patch"></a>patch | [Operation Object](#operation-object) | A definition of a PATCH operation on this path. |
609609
| <a name="path-item-trace"></a>trace | [Operation Object](#operation-object) | A definition of a TRACE operation on this path. |
610-
| <a name="path-item-query"></a>query | [Operation Object](#operation-object) | A definition of a QUERY operation, as defined in the most recent IETF draft ([draft-ietf-httpbis-safe-method-w-body-08](https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-11.html) as of this writing) or its RFC successor, on this path. |
610+
| <a name="path-item-query"></a>query | [Operation Object](#operation-object) | A definition of a QUERY operation, as defined in the most recent IETF draft ([draft-ietf-httpbis-safe-method-w-body-14](https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-14.html) as of this writing) or its RFC successor, on this path. |
611611
| <a name="path-item-additional-operations"></a>additionalOperations | Map[`string`, [Operation Object](#operation-object)] | A map of additional operations on this path. The map key is the HTTP method with the same capitalization that is to be sent in the request. This map MUST NOT contain any entry for the methods that can be defined by other fixed fields with Operation Object values (e.g. no `POST` entry, as the `post` field is used for this method). |
612612
| <a name="path-item-servers"></a>servers | [[Server Object](#server-object)] | An alternative `servers` array to service all operations in this path. If a `servers` array is specified at the [OpenAPI Object](#oas-servers) level, it will be overridden by this value. |
613613
| <a name="path-item-parameters"></a>parameters | [[Parameter Object](#parameter-object) \| [Reference Object](#reference-object)] | A list of parameters that are applicable for all the operations described under this path. These parameters can be overridden at the operation level, but cannot be removed there. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a [name](#parameter-name) and [location](#parameter-in). The list can use the [Reference Object](#reference-object) to link to parameters that are defined in the [OpenAPI Object's `components.parameters`](#components-parameters). |
@@ -810,6 +810,9 @@ These fields MUST NOT be used with `in: "querystring"`.
810810
Care is needed for parameters with `schema` that have `in: "header"` or `in: "cookie", style: "cookie"`:
811811

812812
* When serializing these values, URI percent-encoding MUST NOT be applied.
813+
* The Cookie header prohibits unencoded commas (see
814+
[RFC6265](https://datatracker.ietf.org/doc/html/rfc6265#section-4.2.1) for the complete ABNF),
815+
therefore `"explode": false` is invalid with `"in": "cookie"` (both `"style": "form"` and `"style": "cookie"`).
813816
* When parsing these parameters, any apparent percent-encoding MUST NOT be decoded.
814817
* If using an RFC6570 implementation that automatically performs encoding or decoding steps, the steps MUST be undone before use.
815818

@@ -930,7 +933,7 @@ The following table shows serialized examples, as would be shown with the `seria
930933
| pipeDelimited | false | _n/a_ | _n/a_ | color=blue%7Cblack%7Cbrown | color=R%7C100%7CG%7C200%7CB%7C150 |
931934
| pipeDelimited | true | _n/a_ | _n/a_ | _n/a_ | _n/a_ |
932935
| deepObject | _n/a_ | _n/a_ | _n/a_ | _n/a_ | color%5BR%5D=100&color%5BG%5D=200&color%5BB%5D=150 |
933-
| cookie | false | color= | color=blue | color=blue,black,brown | color=R,100,G,200,B,150 |
936+
| cookie | false | color= | color=blue | _n/a_ | _n/a_ |
934937
| cookie | true | color= | color=blue | color=blue; color=black; color=brown | R=100; G=200; B=150 |
935938

936939
#### Extending Support for Querystring Formats
@@ -984,14 +987,13 @@ schema:
984987
examples:
985988
Object:
986989
description: |
987-
Note that the comma (,) has been pre-percent-encoded
988-
to "%2C" in the data, as it is forbidden in
989-
cookie values. However, the exclamation point (!)
990-
is legal in cookies, so it can be left unencoded.
990+
Note that the comma (,) and space ( ) have been pre-percent-encoded
991+
in the data, as they are forbidden in cookie values. However, the
992+
exclamation point (!) is legal in cookies, so it can be left unencoded.
991993
dataValue:
992-
greeting: Hello%2C world!
994+
greeting: Hello%2C%20world!
993995
code: 42
994-
serializedValue: "greeting=Hello%2C world!; code=42"
996+
serializedValue: "greeting=Hello%2C%20world!; code=42"
995997
```
996998
997999
A cookie parameter relying on the percent-encoding behavior of the default `style: "form"`:
@@ -1603,7 +1605,7 @@ content:
16031605
format: int64
16041606
- properties:
16051607
event:
1606-
const: addJson
1608+
const: addJSON
16071609
data:
16081610
$comment: |
16091611
These content fields indicate
@@ -1829,9 +1831,9 @@ requestBody:
18291831
# image media type(s) in the Encoding Object.
18301832
type: string
18311833
contentEncoding: base64url
1832-
encoding:
1833-
icon:
1834-
contentType: image/png, image/jpeg
1834+
encoding:
1835+
icon:
1836+
contentType: image/png, image/jpeg
18351837
```
18361838
18371839
Given a name of `example` and a solid red 2x2-pixel PNG for `icon`, this
@@ -2338,7 +2340,7 @@ The various fields and types of examples are explained in more detail under [Wor
23382340
| <a name="example-description"></a>description | `string` | Long description for the example. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. |
23392341
| <a name="example-data-value"></a>dataValue | Any | An example of the data structure that MUST be valid according to the relevant [Schema Object](#schema-object). If this field is present, `value` MUST be absent. |
23402342
| <a name="example-serialized-value"></a>serializedValue | `string` | An example of the serialized form of the value, including encoding and escaping as described under [Validating Examples](#validating-examples). If `dataValue` is present, then this field SHOULD contain the serialization of the given data. Otherwise, it SHOULD be the valid serialization of a data value that itself MUST be valid as described for `dataValue`. This field SHOULD NOT be used if the serialization format is JSON, as the data form is easier to work with. If this field is present, `value`, and `externalValue` MUST be absent. |
2341-
| <a name="example-external-value"></a>externalValue | `string` | A URI that identifies the serialized example in a separate document, allowing for values not easily or readably expressed as a Unicode string. If `dataValue` is present, then this field SHOULD identify a serialization of the given data. Otherwise, the value SHOULD be the valid serialization of a data value that itself MUST be valid as described for `dataValue`. If this field is present, `serializedValue` and `value` MUST be absent. See also the rules for resolving [Relative References](#relative-references-in-api-description-uris). |
2343+
| <a name="example-external-value"></a>externalValue | `string` | A URI that identifies the serialized example in a separate document, allowing for values not easily or readably expressed as a Unicode string. If `dataValue` is present, then this field SHOULD identify a serialization of the given data. Otherwise, the value SHOULD identify the valid serialization of a data value that itself MUST be valid as described for `dataValue`. If this field is present, `serializedValue` and `value` MUST be absent. See also the rules for resolving [Relative References](#relative-references-in-api-description-uris). |
23422344
| <a name="example-value"></a>value | Any | Embedded literal example. The `value` field and `externalValue` field are mutually exclusive. To represent examples of media types that cannot naturally be represented in JSON or YAML, use a string value to contain the example, escaping where necessary.<br><br>**Deprecated for non-JSON serialization targets:** Use `dataValue` and/or `serializedValue`, which both have unambiguous syntax and semantics, instead. |
23432345

23442346
This object MAY be extended with [Specification Extensions](#specification-extensions).
@@ -2769,7 +2771,7 @@ components:
27692771
content:
27702772
application/linkset+json:
27712773
schema:
2772-
$ref: '#/components/mediaTypes/CollectionLinks'
2774+
$ref: '#/components/schemas/CollectionLinks'
27732775
```
27742776
27752777
#### Representing the `Set-Cookie` Header
@@ -2847,11 +2849,10 @@ components:
28472849
explode: true
28482850
examples:
28492851
SetCookies:
2850-
dataValue: {
2851-
"lang": "en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT"
2852-
"foo": "bar; Expires=Wed, 09 Jun 2021 10:18:14 GMT"
2853-
"urlSafeData": "Hello%2C%20world%21"
2854-
}
2852+
dataValue:
2853+
lang: "en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT"
2854+
foo: "bar; Expires=Wed, 09 Jun 2021 10:18:14 GMT"
2855+
urlSafeData: "Hello%2C%20world%21"
28552856
serializedValue: |
28562857
lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
28572858
foo=bar; Expires=Wed, 09 Jun 2021 10:18:14 GMT
@@ -3158,7 +3159,7 @@ This means that the data form of this serialization is equivalent to the followi
31583159
```json
31593160
{
31603161
"code": "1234",
3161-
"count": 42
3162+
"count": 42,
31623163
"extra": {
31633164
"info": "abc"
31643165
}
@@ -4320,15 +4321,16 @@ components:
43204321
xml:
43214322
nodeType: cdata
43224323
responses:
4323-
content:
4324-
application/xml:
4325-
schema:
4326-
$ref: "#/components/schemas/Documentation"
4327-
examples:
4328-
docs:
4329-
dataValue:
4330-
content: <html><head><title>Awesome Docs</title></head><body></body><html>
4331-
externalValue: ./examples/docs.xml
4324+
AwesomeDocs:
4325+
content:
4326+
application/xml:
4327+
schema:
4328+
$ref: "#/components/schemas/Documentation"
4329+
examples:
4330+
docs:
4331+
dataValue:
4332+
content: <html><head><title>Awesome Docs</title></head><body></body><html>
4333+
externalValue: ./examples/docs.xml
43324334
```
43334335

43344336
Where `./examples/docs.xml` would be:
@@ -5134,10 +5136,12 @@ For this reason, any data being passed to a header by way of a [Parameter](#para
51345136
While percent-encoding seems more common as an escaping mechanism than the base64 encoding (`contentEncoding`: "base64") recommended by [[RFC6265]], [section 5.6 of draft-ietf-httpbis-rfc6265bis-20](https://www.ietf.org/archive/id/draft-ietf-httpbis-rfc6265bis-20.html#section-5.6), the proposed update to that RFC notes that cookies sent in the `Set-Cookie` response header that appear to be percent-encoded MUST NOT be decoded when stored by the client, which would mean that they are already encoded when retrieved from that storage for use in the `Cookie` request header.
51355137
The behavior of `style: "cookie"` assumes this usage, and _does not_ apply or remove percent-encoding.
51365138

5137-
If automatic percent-encoding is desired, `style: "form"` with a primitive value or with the non-default `explode` value of `false` provides this behavior.
5139+
If automatic percent-encoding is desired, `style: "form"` with a primitive value provides this behavior (note that the non-default `explode` value of `false` produces cookie values containing a comma (`,`), which are invalid).
5140+
51385141
However, note that the default value of `explode: true` for `style: "form"` with non-primitive values uses the wrong delimiter for cookies (`&` instead of `;` followed by a single space) to set multiple cookie values.
51395142
Using `style: "form"` with `in: "cookie"` via an RFC6570 implementation requires stripping the `?` prefix, as when producing `application/x-www-form-urlencoded` message bodies.
5140-
To allow the full use of `style: "form"` with `in: "cookie"`, use the `allowReserved` field.
5143+
To allow the full use of `style: "form"` with `in: "cookie"`, use the `allowReserved` field, taking
5144+
care to still escape the characters that are invalid in the Cookie header (see [RFC6265](https://datatracker.ietf.org/doc/html/rfc6265#section-4.2.1) for the complete ABNF).
51415145

51425146
## Appendix E: Percent-Encoding and Form Media Types
51435147

@@ -5332,7 +5336,7 @@ components:
53325336
content:
53335337
application/json:
53345338
schema:
5335-
$ref: "#/components/api/schemas/Foo"
5339+
$ref: "#/components/schemas/Foo"
53365340
schemas:
53375341
Foo:
53385342
properties:
@@ -5453,7 +5457,7 @@ components:
54535457
```
54545458

54555459
In this example, all of the `$self` and `$id` values are relative URI references consisting of an absolute path.
5456-
This allows the retrieval URI to set the host (and scheme), in this case `https://staging.example.com`, resulting in the first document's `$self` being `https://staging.example.com/openapi`, and the second document's `$self` being `https://staging.example.com/api/shared/foo`, with `$id` values of `https://staging.example.com/api/schemas/foo` and `https://staging.example.com/api/schemas/bar`.
5460+
This allows the retrieval URI to set the host (and scheme), in this case `https://staging.example.com`, resulting in the first document's `$self` being `https://staging.example.com/api/openapi`, and the second document's `$self` being `https://staging.example.com/api/shared/foo`, with `$id` values of `https://staging.example.com/api/schemas/foo` and `https://staging.example.com/api/schemas/bar`.
54575461
Relative `$self` and `$id` values of this sort allow the same set of documents to work when deployed to other hosts, e.g. `https://example.com` (production) or `https://localhost:8080` (local development).
54585462

54595463
## Appendix G: Parsing and Resolution Guidance

src/schemas/validation/schema.yaml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ $defs:
243243
$ref: '#/$defs/operation'
244244
propertyNames:
245245
$comment: RFC9110 restricts methods to "1*tchar" in ABNF
246-
pattern: "^[a-zA-Z0-9!#$%&'*+.^_`|~-]+$"
246+
$ref: '#/$defs/token'
247247
not:
248248
enum:
249249
- GET
@@ -414,6 +414,14 @@ $defs:
414414
then:
415415
required:
416416
- content
417+
- if:
418+
properties:
419+
in:
420+
const: header
421+
then:
422+
properties:
423+
name:
424+
$ref: '#/$defs/token'
417425
dependentSchemas:
418426
schema:
419427
properties:
@@ -600,10 +608,12 @@ $defs:
600608
type: object
601609
properties:
602610
contentType:
611+
$comment: one or more comma-separated media-ranges
603612
type: string
604-
format: media-range
605613
headers:
606614
type: object
615+
propertyNames:
616+
$ref: '#/$defs/token'
607617
additionalProperties:
608618
$ref: '#/$defs/header-or-reference'
609619
style:
@@ -679,6 +689,8 @@ $defs:
679689
type: string
680690
headers:
681691
type: object
692+
propertyNames:
693+
$ref: '#/$defs/token'
682694
additionalProperties:
683695
$ref: '#/$defs/header-or-reference'
684696
content:
@@ -1149,3 +1161,8 @@ $defs:
11491161
properties:
11501162
explode:
11511163
default: false
1164+
1165+
token:
1166+
$comment: see https://www.rfc-editor.org/rfc/rfc9110.html#section-5.6.2
1167+
type: string
1168+
pattern: ^[0-9A-Za-z!#$%&'*+.^_`|~-]+$
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
openapi: 3.3.0
2+
info:
3+
title: the header name, as used in serialization, has a constrained syntax
4+
version: 1.0.0
5+
paths:
6+
/foo:
7+
get:
8+
responses:
9+
default:
10+
headers:
11+
'Bad=Header':
12+
schema: {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
openapi: 3.3.0
2+
info:
3+
title: header name has a constrained syntax
4+
version: 1.0.0
5+
components:
6+
parameters:
7+
BadHeader:
8+
name: 'Bad[Header]'
9+
in: header
10+
schema: {}

0 commit comments

Comments
 (0)