Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A collection of modules for working with JSON Schemas.
* Schemas can reference other schemas using a different dialect
* Work directly with schemas on the filesystem or HTTP
* OpenAPI
* Versions: 3.0, 3.1
* Versions: 3.0, 3.1, 3.2
* Validate an OpenAPI document
* Validate values against a schema from an OpenAPI document
* Create custom keywords, vocabularies, and dialects
Expand Down Expand Up @@ -132,22 +132,22 @@ system](https://github.com/hyperjump-io/browser/#uri-schemes) provided by

**OpenAPI**

The OpenAPI 3.0 and 3.1 meta-schemas are pre-loaded and the OpenAPI JSON Schema
The OpenAPI 3.0 and 3.1 and 3.2 meta-schemas are pre-loaded and the OpenAPI JSON Schema
dialects for each of those versions is supported. A document with a Content-Type
of `application/openapi+json` (web) or a file extension of `openapi.json`
(filesystem) is understood as an OpenAPI document.

Use the pattern `@hyperjump/json-schema/*` to import the version you need. The
available versions are `openapi-3-0` for 3.0 and `openapi-3-1` for 3.1.
available versions are `openapi-3-0` for 3.0, `openapi-3-1` for 3.1, and `openapi-3-2` for 3.2.

```javascript
import { validate } from "@hyperjump/json-schema/openapi-3-1";
import { validate } from "@hyperjump/json-schema/openapi-3-2";


// Validate an OpenAPI document
const output = await validate("https://spec.openapis.org/oas/3.1/schema-base", openapi);
// Validate an OpenAPI 3.2 document
const output = await validate("https://spec.openapis.org/oas/3.2/schema-base", openapi);

// Validate an instance against a schema in an OpenAPI document
// Validate an instance against a schema in an OpenAPI 3.2 document
const output = await validate("./example.openapi.json#/components/schemas/foo", 42);
```

Expand Down
12 changes: 6 additions & 6 deletions openapi-3-1/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ type Link = {
parameters?: Record<string, string>;
requestBody?: Json;
description?: string;
body?: Server;
server?: Server;
};

type Header = {
Expand All @@ -259,7 +259,7 @@ type Tag = {
type Reference = {
$ref: string;
summary?: string;
descriptions?: string;
description?: string;
};

type SecurityScheme = {
Expand All @@ -274,10 +274,10 @@ type SecurityScheme = {
};

type OauthFlows = {
implicit: Implicit;
Password: Password;
clientCredentials: ClientCredentials;
authorizationCode: AuthorizationCode;
implicit?: Implicit;
password?: Password;
clientCredentials?: ClientCredentials;
authorizationCode?: AuthorizationCode;
};

type Implicit = {
Expand Down
2 changes: 1 addition & 1 deletion openapi-3-1/schema-draft-2019-09.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default {
"dialect": { "const": "https://json-schema.org/draft/2019-09/schema" },

"schema": {
"$dynamicanchor": "meta",
"$dynamicAnchor": "meta",
"$ref": "https://spec.openapis.org/oas/3.1/dialect/base",
"properties": {
"$schema": { "$ref": "#/$defs/dialect" }
Expand Down
2 changes: 1 addition & 1 deletion openapi-3-1/schema-draft-2020-12.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default {
"dialect": { "const": "https://json-schema.org/draft/2020-12/schema" },

"schema": {
"$dynamicanchor": "meta",
"$dynamicAnchor": "meta",
"$ref": "https://spec.openapis.org/oas/3.1/dialect/base",
"properties": {
"$schema": { "$ref": "#/$defs/dialect" }
Expand Down
4 changes: 2 additions & 2 deletions openapi-3-2/dialect/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ export default {
"$dynamicAnchor": "meta",

"title": "OpenAPI 3.2 Schema Object Dialect",
"description": "A JSON Schema dialect describing schemas found in OpenAPI v3.2 Descriptions",
"description": "A JSON Schema dialect describing schemas found in OpenAPI v3.2.x Descriptions",

"allOf": [
{ "$ref": "https://json-schema.org/draft/2020-12/schema" },
{ "$ref": "https://spec.openapis.org/oas/3.2/meta/base" }
{ "$ref": "https://spec.openapis.org/oas/3.2/meta" }
]
};
258 changes: 256 additions & 2 deletions openapi-3-2/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export type OasSchema32 = boolean | {
type Discriminator = {
propertyName: string;
mappings?: Record<string, string>;
defaultMapping?: string;
};

type ExternalDocs = {
Expand All @@ -78,14 +79,267 @@ type ExternalDocs = {
};

type Xml = {
nodeType?: "element" | "attribute" | "text" | "cdata" | "none";
name?: string;
namespace?: string;
prefix?: string;
attribute?: boolean;
wrapped?: boolean;
};

// TODO: Fill in this type when 3.2 is published
export type OpenApi32 = unknown;
export type OpenApi = {
openapi: string;
$self?: string;
info: Info;
jsonSchemaDialect?: string;
servers?: Server[];
paths?: Record<string, PathItem>;
webhooks?: Record<string, PathItem>;
components?: Components;
security?: SecurityRequirement[];
tags?: Tag[];
externalDocs?: ExternalDocs;
};

type Info = {
title: string;
summary?: string;
description?: string;
termsOfService?: string;
contact?: Contact;
license?: License;
version: string;
};

type Contact = {
name?: string;
url?: string;
email?: string;
};

type License = {
name: string;
identifier?: string;
url?: string;
};

type Server = {
url: string;
description?: string;
name?: string;
variables?: Record<string, ServerVariable>;
};

type ServerVariable = {
enum?: string[];
default: string;
description?: string;
};

type Components = {
schemas?: Record<string, OasSchema32>;
responses?: Record<string, Response | Reference>;
parameters?: Record<string, Parameter | Reference>;
examples?: Record<string, Example | Reference>;
requestBodies?: Record<string, RequestBody | Reference>;
headers?: Record<string, Header | Reference>;
securitySchemes?: Record<string, SecurityScheme | Reference>;
links?: Record<string, Link | Reference>;
callbacks?: Record<string, Callbacks | Reference>;
pathItems?: Record<string, PathItem>;
mediaTypes?: Record<string, MediaType | Reference>;
};

type PathItem = {
$ref?: string;
summary?: string;
description?: string;
get?: Operation;
put?: Operation;
post?: Operation;
delete?: Operation;
options?: Operation;
head?: Operation;
patch?: Operation;
trace?: Operation;
query?: Operation;
additionOperations?: Record<string, Operation>;
servers?: Server[];
parameters?: (Parameter | Reference)[];
};

type Operation = {
tags?: string[];
summary?: string;
description?: string;
externalDocs?: ExternalDocs;
operationId?: string;
parameters?: (Parameter | Reference)[];
requestBody?: RequestBody | Reference;
responses?: Responses;
callbacks?: Record<string, Callbacks | Reference>;
deprecated?: boolean;
security?: SecurityRequirement[];
servers?: Server[];
};

type Parameter = {
name: string;
in: "query" | "querystring" | "header" | "path" | "cookie";
description?: string;
required?: boolean;
deprecated?: boolean;
allowEmptyValue?: boolean;
} & Examples & ({
style?: "matrix" | "label" | "form" | "simple" | "spaceDelimited" | "pipeDelimited" | "deepObject";
explode?: boolean;
schema: OasSchema32;
} | {
content: Record<string, MediaType | Reference>;
});

type RequestBody = {
description?: string;
content: Record<string, MediaType | Reference>;
required?: boolean;
};

type MediaType = {
schema?: OasSchema32;
itemSchema?: OasSchema32;
encoding?: Record<string, Encoding>;
prefixEncoding?: Encoding[];
itemEncoding?: Encoding;
} & Examples;

type Encoding = {
contentType?: string;
headers?: Record<string, Header | Reference>;
encoding?: Record<string, Encoding>;
prefixEncoding?: Encoding[];
itemEncoding?: Encoding;
style?: "form" | "spaceDelimited" | "pipeDelimited" | "deepObject";
explode?: boolean;
allowReserved?: boolean;
};

type Responses = {
default?: Response | Reference;
} & Record<string, Response | Reference>;

type Response = {
summary?: string;
description?: string;
headers?: Record<string, Header | Reference>;
content?: Record<string, MediaType | Reference>;
links?: Record<string, Link | Reference>;
};

type Callbacks = Record<string, PathItem | Reference>;

type Examples = {
example?: Json;
examples?: Record<string, Example | Reference>;
};

type Example = {
summary?: string;
description?: string;
dataValue?: Json;
serializedValue?: string;
externalValue?: string;
value?: Json;
};

type Link = {
operationRef?: string;
operationId?: string;
parameters?: Record<string, string>;
requestBody?: Json;
description?: string;
server?: Server;
};

type Header = {
description?: string;
required?: boolean;
deprecated?: boolean;
} & Examples & ({
style?: "simple";
explode?: boolean;
schema: OasSchema32;
} | {
content: Record<string, MediaType | Reference>;
});

type Tag = {
name: string;
summary?: string;
description?: string;
externalDocs?: ExternalDocs;
parent?: string;
kind?: string;
};

type Reference = {
$ref: string;
summary?: string;
description?: string;
};

type SecurityScheme = {
type: "apiKey" | "http" | "mutualTLS" | "oauth2" | "openIdConnect";
description?: string;
name?: string;
in?: "query" | "header" | "cookie";
scheme?: string;
bearerFormat?: string;
flows?: OauthFlows;
openIdConnectUrl?: string;
oauth2MetadataUrl?: string;
deprecated?: boolean;
};

type OauthFlows = {
implicit?: Implicit;
password?: Password;
clientCredentials?: ClientCredentials;
authorizationCode?: AuthorizationCode;
deviceAuthorization?: DeviceAuthorization;
};

type Implicit = {
authorizationUrl: string;
refreshUrl?: string;
scopes: Record<string, string>;
};

type Password = {
tokenUrl: string;
refreshUrl?: string;
scopes: Record<string, string>;
};

type ClientCredentials = {
tokenUrl: string;
refreshUrl?: string;
scopes: Record<string, string>;
};

type AuthorizationCode = {
authorizationUrl: string;
tokenUrl: string;
refreshUrl?: string;
scopes: Record<string, string>;
};

type DeviceAuthorization = {
deviceAuthorizationUrl: string;
tokenUrl: string;
refreshUrl?: string;
scopes: Record<string, string>;
};

type SecurityRequirement = Record<string, string[]>;

export * from "../lib/index.js";
6 changes: 2 additions & 4 deletions openapi-3-2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@ defineVocabulary("https://spec.openapis.org/oas/3.2/vocab/base", {
"xml": "https://spec.openapis.org/oas/3.0/keyword/xml"
});

registerSchema(vocabularySchema, "https://spec.openapis.org/oas/3.2/meta/base");
registerSchema(dialectSchema, "https://spec.openapis.org/oas/3.2/dialect/base");
registerSchema(vocabularySchema, "https://spec.openapis.org/oas/3.2/meta");
registerSchema(dialectSchema, "https://spec.openapis.org/oas/3.2/dialect");

// Current Schemas
registerSchema(schema, "https://spec.openapis.org/oas/3.2/schema");
registerSchema(schema, "https://spec.openapis.org/oas/3.2/schema/latest");
registerSchema(schemaBase, "https://spec.openapis.org/oas/3.2/schema-base");
registerSchema(schemaBase, "https://spec.openapis.org/oas/3.2/schema-base/latest");

// Alternative dialect schemas
registerSchema(schemaDraft2020, "https://spec.openapis.org/oas/3.2/schema-draft-2020-12");
Expand Down
Loading