Skip to content

Instantly share code, notes, and snippets.

@jhunterkohler
Last active January 31, 2022 21:30
Show Gist options
  • Save jhunterkohler/cc43a241a8920cb76e4a08c22d887617 to your computer and use it in GitHub Desktop.
Save jhunterkohler/cc43a241a8920cb76e4a08c22d887617 to your computer and use it in GitHub Desktop.
Relatively good; hand written Types for OpenAPI 3.1
/**
* Copyright (C) 2021 Hunter Kohler <[email protected]>
*/
type Dict<T> = { [P: string]: T | undefined };
export type SpecificationExtension = any;
export type OpenAPI = {
components?: Components;
externalDocs?: ExternalDocumentation;
info: Info;
jsonSchemaDialect?: string;
openapi: string;
paths?: Paths;
security?: SecurityRequirement[];
servers?: Server[];
tags?: Tag[];
webhooks?: Dict<PathItem | Reference<PathItem>>;
[P: `x-${string}`]: any;
};
export type Info = {
contact?: Contact;
description?: string;
license?: License;
summary?: string;
termsOfService?: string;
title: string;
version: string;
[P: `x-${string}`]: any;
};
export type Contact = {
email?: string;
name?: string;
url?: string;
[P: `x-${string}`]: any;
};
export type License = {
identifier?: string;
name?: string;
url?: string;
[P: `x-${string}`]: any;
};
export type Server = {
description?: string;
url: string;
variables?: Dict<ServerVariable>;
[P: `x-${string}`]: any;
};
export type ServerVariable = {
default: string;
description?: string;
enum?: [string, ...string[]];
[P: `x-${string}`]: any;
};
export type SecurityRequirement = {
[P: string]: string[] | undefined;
[P: `x-${string}`]: any;
};
export type Tag = {
description?: string;
externalDocs?: ExternalDocumentation;
name: string;
[P: `x-${string}`]: any;
};
export type ExternalDocumentation = {
description?: string;
url: string;
[P: `x-${string}`]: any;
};
export type RequestBody = {
content: Content;
description?: string;
required?: boolean;
[P: `x-${string}`]: any;
};
export type Content = {
[P: string]: MediaType | undefined;
};
export type Encoding = {
allowReserved?: boolean;
contentType?: string;
explode?: boolean;
headers?: Dict<Header | Reference<Header>>;
style?: StyleType;
[P: `x-${string}`]: any;
};
export type Paths = {
[P: `/${string}`]: PathItem;
[P: `x-${string}`]: any;
};
export type PathItem = {
// $ref should be embedded here
description?: string;
parameters?: (Parameter | Reference<Parameter>)[];
server?: Server[];
summary?: string;
delete?: Operation;
get?: Operation;
head?: Operation;
options?: Operation;
patch?: Operation;
post?: Operation;
put?: Operation;
trace?: Operation;
[P: `x-${string}`]: any;
};
/**
* @template T Symbol representation of what the reference points to.
*/
export type Reference<T> = {
$ref?: string;
description?: string;
summary?: string;
[P: `x-${string}`]: any;
};
export type Operation = {
callbacks?: Dict<Callback | Reference<Callback>>;
deprecated?: boolean;
description?: string;
externalDocs?: ExternalDocumentation;
operationId?: string;
parameters?: (Parameter | Reference<Parameter>)[];
requestBody?: (RequestBody | Reference<Parameter>)[];
responses?: Responses;
security?: SecurityRequirement[];
servers?: Server[];
summary?: string;
tags?: string[];
[P: `x-${string}`]: any;
};
export type ParameterLocation = "query" | "header" | "path" | "cookie";
export type StyleType =
| "matrix"
| "label"
| "form"
| "simple"
| "spaceDelimited"
| "pipeDelimited"
| "deepObject";
export type Parameter = {
allowEmptyValue?: boolean;
allowReserved?: boolean;
content?: Dict<MediaType>;
deprecated?: boolean;
description?: string;
example?: any;
examples?: Dict<Example | Reference<Example>>;
explode?: boolean;
in: ParameterLocation;
name: string;
required?: boolean;
schema?: Schema;
style?: StyleType;
[P: `x-${string}`]: any;
};
export type Header = Omit<Parameter, "in" | "name">;
export type MediaType = {
encoding?: Dict<Encoding>;
example?: any;
examples?: Dict<Example | Reference<Example>>;
schema?: Schema;
[P: `x-${string}`]: any;
};
export type Example = {
description?: string;
externalValue?: string;
summary?: string;
value?: any;
[P: `x-${string}`]: any;
};
export type Link = {
description?: string;
operationId?: string;
operationRef?: string;
parameters?: Dict<any>;
requestBody?: any;
server?: Server;
[P: `x-${string}`]: any;
};
export type Discriminator = {
mapping?: Dict<string>;
propertyName: string;
[P: `x-${string}`]: any;
};
export type XML = {
attribute?: boolean;
name?: string;
namespace?: string;
prefix?: string;
wrapped?: boolean;
[P: `x-${string}`]: any;
};
export type OAuthFlow = {
authorizationUrl: string;
refreshUrl?: string;
scopes: Dict<string>;
tokenUrl: string;
[P: `x-${string}`]: any;
};
export type OAuthFlows = {
authorizationCode?: OAuthFlow;
clientCredentials?: OAuthFlow;
implicit?: OAuthFlow;
password?: OAuthFlow;
[P: `x-${string}`]: any;
};
export type Callback = {
[P: string]: PathItem | Reference<PathItem> | undefined;
[P: `x-${string}`]: any;
};
export type Components = {
callbacks?: Dict<Callback | Reference<Callback>>;
examples?: Dict<Example | Reference<Example>>;
links?: Dict<Link | Reference<Link>>;
parameters?: Dict<Parameter | Reference<Parameter>>;
pathItems?: Dict<PathItem | Reference<PathItem>>;
requestBodies?: Dict<RequestBody | Reference<RequestBody>>;
responses?: Dict<Response | Reference<Response>>;
schemas?: Dict<Schema>;
securitySchemes?: Dict<SecurityScheme | Reference<SecurityScheme>>;
[P: `x-${string}`]: any;
};
type SecuritySchemeType =
| "apiKey"
| "http"
| "mutualTLS"
| "oauth2"
| "openIdConnect";
type HTTPSecuritySchemeType =
| "Basic"
| "Bearer"
| "Digest"
| "HOBA"
| "Mutual"
| "Negotiate"
| "OAuth"
| "SCRAM-SHA-1"
| "SCRAM-SHA-256"
| "vapid";
export type SecurityScheme = {
bearerFormat?: string;
description?: string;
flows?: OAuthFlows;
in?: "query" | "header" | "cookie";
name?: string;
openIdConnectUrl?: string;
scheme?: HTTPSecuritySchemeType;
type: SecuritySchemeType;
[P: `x-${string}`]: any;
};
/**
* References:
* https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
* https://datatracker.ietf.org/doc/html/rfc7231
*/ // prettier-ignore
export type HTTPStatusCode =
| "100" | "101" | "102" | "103" | "200" | "201" | "202" | "203" | "204"
| "205" | "206" | "207" | "208" | "226" | "300" | "301" | "302" | "303"
| "304" | "305" | "307" | "308" | "400" | "401" | "402" | "403" | "404"
| "405" | "406" | "407" | "408" | "409" | "410" | "411" | "412" | "413"
| "414" | "415" | "416" | "417" | "421" | "422" | "423" | "424" | "425"
| "426" | "428" | "429" | "431" | "451" | "500" | "501" | "502" | "503"
| "504" | "505" | "506" | "507" | "508" | "511";
export type Responses = {
[P in "default" | HTTPStatusCode]: Response | Reference<Response>;
};
export type Response = {
content?: Dict<MediaType>;
description: string;
headers?: Dict<Header | Reference<Header>>;
links?: Dict<Link | Reference<Link>>;
[P: `x-${string}`]: any;
};
export type Schema = {
discriminator?: Discriminator;
externalDocs?: ExternalDocumentation;
xml?: XML;
[P: string]: any;
[P: `x-${string}`]: any;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment