From 330d43c8735b6011c97fb3e1a085f7c2dccda3a9 Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Mon, 8 Apr 2024 05:38:19 +0900 Subject: [PATCH] OpenAPI v3.1 --- .gitignore | 1 + package.json | 10 +- src/OpenApiV3.ts | 91 +++++++++---- src/OpenApiV3_1.ts | 326 +++++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 1 + 5 files changed, 402 insertions(+), 27 deletions(-) create mode 100644 src/OpenApiV3_1.ts diff --git a/.gitignore b/.gitignore index a089263..dc87db4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +lib/ node_modules/ package-lock.json diff --git a/package.json b/package.json index d771019..f812fef 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,19 @@ "main": "./lib/index.js", "typings": "./lib/index.d.ts", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "rimraf lib && tsc" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "prettier": "^3.2.5", + "rimraf": "^5.0.5", "typescript": "^5.4.3" - } + }, + "files": [ + "lib", + "src", + "README.md" + ] } diff --git a/src/OpenApiV3.ts b/src/OpenApiV3.ts index 6787fd1..c7c574c 100644 --- a/src/OpenApiV3.ts +++ b/src/OpenApiV3.ts @@ -1,26 +1,27 @@ export namespace OpenApiV3 { + export type Method = + | "get" + | "post" + | "put" + | "delete" + | "options" + | "head" + | "patch" + | "trace"; + + /* ----------------------------------------------------------- + DOCUMENTS + ----------------------------------------------------------- */ export interface IDocument { openapi: `3.0.${number}`; - servers?: IDocument.IServer[]; - info: IDocument.IInfo; + servers?: IServer[]; + info?: IDocument.IInfo; components?: IComponents; - paths: Record>; + paths?: Record; security?: Record[]; tags?: IDocument.ITag[]; } export namespace IDocument { - export interface IServer { - /** @format uri */ url: string; - description?: string; - variables?: Record; - } - export namespace IServer { - export interface IVariable { - default: string; - enum?: string[]; - description?: string; - } - } export interface IInfo { title: string; description?: string; @@ -44,26 +45,55 @@ export namespace OpenApiV3 { } } - export interface IRoute { + export interface IServer { + /** @format uri */ url: string; + description?: string; + variables?: Record; + } + export namespace IServer { + export interface IVariable { + default: string; + enum?: string[]; + description?: string; + } + } + + /* ----------------------------------------------------------- + PATH ITEMS + ----------------------------------------------------------- */ + export type IPathItem = { + parameters?: Array< + | IOperation.IParameter + | IJsonSchema.IReference<`#/components/headers/${string}`> + | IJsonSchema.IReference<`#/components/parameters/${string}`> + >; + servers?: IServer[]; + summary?: string; + description?: string; + } & Partial>; + + export interface IOperation { + operationId?: string; parameters?: Array< - | IRoute.IParameter + | IOperation.IParameter | IJsonSchema.IReference<`#/components/headers/${string}`> | IJsonSchema.IReference<`#/components/parameters/${string}`> >; requestBody?: - | IRoute.IRequestBody + | IOperation.IRequestBody | IJsonSchema.IReference<`#/components/requestBodies/${string}`>; responses?: Record< string, - | IRoute.IResponse + | IOperation.IResponse | IJsonSchema.IReference<`#/components/responses/${string}`> >; + servers?: IServer[]; summary?: string; description?: string; security?: Record; tags?: string[]; } - export namespace IRoute { + export namespace IOperation { export interface IParameter { name?: string; in: "path" | "query" | "header" | "cookie"; @@ -78,6 +108,11 @@ export namespace OpenApiV3 { } export interface IResponse { content?: Record; + headers?: Record< + string, + | IOperation.IParameter + | IJsonSchema.IReference<`#/components/headers/${string}`> + >; description?: string; } export interface IMediaType { @@ -85,14 +120,18 @@ export namespace OpenApiV3 { } } + /* ----------------------------------------------------------- + SCHEMA DEFINITIONS + ----------------------------------------------------------- */ export interface IComponents { schemas?: Record; - responses?: Record; - parameters?: Record; - requestBodies?: Record; + responses?: Record; + parameters?: Record; + requestBodies?: Record; securitySchemes?: Record; - headers?: Record; + headers?: Record; } + export type IJsonSchema = | IJsonSchema.IBoolean | IJsonSchema.IInteger @@ -130,7 +169,6 @@ export namespace OpenApiV3 { multipleOf?: number; } export interface IString extends __ISignificant<"string"> { - contentMediaType?: string; default?: string; enum?: string[]; format?: @@ -173,6 +211,8 @@ export namespace OpenApiV3 { properties: Record; required?: string[]; additionalProperties?: boolean | IJsonSchema; + maxProperties?: number; + minProperties?: number; } export interface IReference extends __IAttribute { $ref: Key; @@ -204,6 +244,7 @@ export namespace OpenApiV3 { deprecated?: boolean; } } + export type ISecurityScheme = | ISecurityScheme.IApiKey | ISecurityScheme.IHttpBasic diff --git a/src/OpenApiV3_1.ts b/src/OpenApiV3_1.ts new file mode 100644 index 0000000..5e631ad --- /dev/null +++ b/src/OpenApiV3_1.ts @@ -0,0 +1,326 @@ +export namespace OpenApiV3_1 { + export type Method = + | "get" + | "post" + | "put" + | "delete" + | "options" + | "head" + | "patch" + | "trace"; + + /* ----------------------------------------------------------- + DOCUMENTS + ----------------------------------------------------------- */ + export interface IDocument { + openapi: `3.1.${number}`; + servers?: IServer[]; + info?: IDocument.IInfo; + components?: IComponents; + paths?: Record; + webhooks?: Record< + string, + IJsonSchema.IReference<`#/components/pathItems/${string}`> | IPathItem + >; + security?: Record[]; + tags?: IDocument.ITag[]; + } + export namespace IDocument { + export interface IInfo { + title: string; + summary?: string; + description?: string; + termsOfService?: string; + contact?: IContact; + license?: ILicense; + version: string; + } + export interface ITag { + name: string; + description?: string; + } + export interface IContact { + name?: string; + /** @format uri */ url?: string; + /** @format email */ email?: string; + } + export interface ILicense { + name: string; + identifier?: string; + /** @format email */ url?: string; + } + } + + export interface IServer { + /** @format uri */ url: string; + description?: string; + variables?: Record; + } + export namespace IServer { + export interface IVariable { + default: string; + /** @minItems 1 */ enum?: string[]; + description?: string; + } + } + + /* ----------------------------------------------------------- + PATH ITEMS + ----------------------------------------------------------- */ + export type IPathItem = { + parameters?: Array< + | IOperation.IParameter + | IJsonSchema.IReference<`#/components/headers/${string}`> + | IJsonSchema.IReference<`#/components/parameters/${string}`> + >; + servers?: IServer[]; + summary?: string; + description?: string; + } & Partial>; + + export interface IOperation { + operationId?: string; + parameters?: Array< + | IOperation.IParameter + | IJsonSchema.IReference<`#/components/headers/${string}`> + | IJsonSchema.IReference<`#/components/parameters/${string}`> + >; + requestBody?: + | IOperation.IRequestBody + | IJsonSchema.IReference<`#/components/requestBodies/${string}`>; + responses?: Record< + string, + | IOperation.IResponse + | IJsonSchema.IReference<`#/components/responses/${string}`> + >; + servers?: IServer[]; + summary?: string; + description?: string; + security?: Record; + tags?: string[]; + } + export namespace IOperation { + export interface IParameter { + name?: string; + in: "path" | "query" | "header" | "cookie"; + schema: IJsonSchema; + required?: boolean; + description?: string; + } + export interface IRequestBody { + description?: string; + required?: boolean; + content?: Record; + } + export interface IResponse { + content?: Record; + headers?: Record< + string, + | IOperation.IParameter + | IJsonSchema.IReference<`#/components/headers/${string}`> + >; + description?: string; + } + export interface IMediaType { + schema: IJsonSchema; + } + } + + /* ----------------------------------------------------------- + SCHEMA DEFINITIONS + ----------------------------------------------------------- */ + export interface IComponents { + schemas?: Record; + pathItems?: Record; + responses?: Record; + parameters?: Record; + requestBodies?: Record; + securitySchemes?: Record; + headers?: Record; + } + + export type IJsonSchema = + | IJsonSchema.IMixed + | IJsonSchema.IConstant + | IJsonSchema.IBoolean + | IJsonSchema.IInteger + | IJsonSchema.INumber + | IJsonSchema.IString + | IJsonSchema.IArray + | IJsonSchema.IObject + | IJsonSchema.IReference + | IJsonSchema.IUnknown + | IJsonSchema.INullOnly + | IJsonSchema.IAllOf + | IJsonSchema.IAnyOf + | IJsonSchema.IOneOf; + export namespace IJsonSchema { + export interface IMixed + extends IConstant, + Omit, + Omit, + Omit, + Omit, + Omit, + IOneOf, + IAnyOf, + IAllOf { + type: Array< + "boolean" | "integer" | "number" | "string" | "array" | "object" + >; + default?: any[]; + enum?: any[]; + } + + export interface IConstant extends __IAttribute { + constant: boolean | number | string; + } + export interface IBoolean extends __ISignificant<"boolean"> { + default?: boolean; + enum?: boolean[]; + } + export interface IInteger extends __ISignificant<"integer"> { + /** @type int */ default?: number; + /** @type int */ enum?: number[]; + /** @type int */ minimum?: number; + /** @type int */ maximum?: number; + /** @type int */ exclusiveMinimum?: number | boolean; + /** @type int */ exclusiveMaximum?: number | boolean; + /** @type uint */ multipleOf?: number; + } + export interface INumber extends __ISignificant<"number"> { + default?: number; + enum?: number[]; + minimum?: number; + maximum?: number; + exclusiveMinimum?: number | boolean; + exclusiveMaximum?: number | boolean; + multipleOf?: number; + } + export interface IString extends __ISignificant<"string"> { + contentMediaType?: string; + default?: string; + enum?: string[]; + format?: + | "binary" + | "byte" + | "password" + | "regex" + | "uuid" + | "email" + | "hostname" + | "idn-email" + | "idn-hostname" + | "iri" + | "iri-reference" + | "ipv4" + | "ipv6" + | "uri" + | "uri-reference" + | "uri-template" + | "url" + | "date-time" + | "date" + | "time" + | "duration" + | "json-pointer" + | "relative-json-pointer" + | (string & {}); + pattern?: string; + /** @type uint */ minLength?: number; + /** @type uint */ maxLength?: number; + } + + export interface IUnknown extends __IAttribute { + type?: undefined; + } + export interface INullOnly extends __ISignificant<"null"> {} + export interface IAllOf extends __IAttribute { + allOf: IJsonSchema[]; + } + export interface IAnyOf extends __IAttribute { + anyOf: IJsonSchema[]; + } + export interface IOneOf extends __IAttribute { + oneOf: IJsonSchema[]; + } + + export interface IArray extends __ISignificant<"array"> { + item: IJsonSchema; + prefixItems?: IJsonSchema[]; + /** @type uint */ minItems?: number; + /** @type uint */ maxItems?: number; + unevaluatedItems?: boolean | IJsonSchema; + uniqueItems?: boolean; + } + export interface IObject extends __ISignificant<"object"> { + properties: Record; + required?: string[]; + additionalProperties?: boolean | IJsonSchema; + maxProperties?: number; + minProperties?: number; + } + export interface IReference extends __IAttribute { + $ref: Key; + } + + export interface __ISignificant extends __IAttribute { + type: Type; + } + export interface __IAttribute { + title?: string; + description?: string; + deprecated?: boolean; + } + } + + export type ISecurityScheme = + | ISecurityScheme.IApiKey + | ISecurityScheme.IHttpBasic + | ISecurityScheme.IHttpBearer + | ISecurityScheme.IOAuth2 + | ISecurityScheme.IOpenId; + export namespace ISecurityScheme { + export interface IApiKey { + type: "apiKey"; + in?: "header" | "query" | "cookie"; + name?: string; + description?: string; + } + export interface IHttpBasic { + type: "http"; + schema: "basic"; + description?: string; + } + export interface IHttpBearer { + type: "http"; + schema: "bearer"; + bearerFormat?: string; + description?: string; + } + export interface IOAuth2 { + type: "oauth2"; + flows: IOAuth2.IFlowSet; + description?: string; + } + export interface IOpenId { + type: "openIdConnect"; + /** @format uri */ openIdConnectUrl: string; + description?: string; + } + export namespace IOAuth2 { + export interface IFlowSet { + authorizationCode?: IFlow; + implicit?: Omit; + password?: Omit; + clientCredentials?: Omit; + } + export interface IFlow { + authorizationUrl: string; + /** @format uri */ tokenUrl?: string; + /** @format uri */ refreshUrl?: string; + scopes?: Record; + } + } + } +} diff --git a/src/index.ts b/src/index.ts index 4b6b51c..57b76ed 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ export * from "./OpenApiV3"; +export * from "./OpenApiV3_1";