UNPKG

@samchon/openapi

Version:

OpenAPI definitions and converters for 'typia' and 'nestia'.

976 lines (975 loc) 35 kB
import { OpenApiV3 } from "./OpenApiV3"; import { OpenApiV3_1 } from "./OpenApiV3_1"; import { SwaggerV2 } from "./SwaggerV2"; import { IJsonSchemaAttribute } from "./structures/IJsonSchemaAttribute"; /** * Emended OpenAPI v3.1 definition used by `typia` and `nestia`. * * `OpenApi` is a namespace containing functions and interfaces for emended * OpenAPI v3.1 specification. The keyword "emended" means that `OpenApi` is * not a direct OpenAPI v3.1 specification ({@link OpenApiV3_1}), but a little * bit shrunk to remove ambiguous and duplicated expressions of OpenAPI v3.1 * for the convenience of `typia` and `nestia`. * * For example, when representing nullable type, OpenAPI v3.1 supports three ways. * In that case, `OpenApi` remains only the third way, so that makes `typia` and * `nestia` (especially `@nestia/editor`) to be simple and easy to implement. * * 1. `{ type: ["string", "null"] }` * 2. `{ type: "string", nullable: true }` * 3. `{ oneOf: [{ type: "string" }, { type: "null" }] }` * * Here is the entire list of differences between OpenAPI v3.1 and emended `OpenApi`. * * - Operation * - Merge {@link OpenApiV3_1.IPath.parameters} to {@link OpenApi.IOperation.parameters} * - Resolve {@link OpenApi.IJsonSchema.IReference references} of {@link OpenApiV3_1.IOperation} members * - Escape references of {@link OpenApiV3_1.IComponents.examples} * - JSON Schema * - Decompose mixed type: {@link OpenApiV3_1.IJsonSchema.IMixed} * - Resolve nullable property: {@link OpenApiV3_1.IJsonSchema.__ISignificant.nullable} * - Array type utilizes only single {@link OpenApi.IJsonSchema.IArray.items} * - Tuple type utilizes only {@link OpenApi.IJsonSchema.ITuple.prefixItems} * - Merge {@link OpenApiV3_1.IJsonSchema.IAllOf} to {@link OpenApi.IJsonSchema.IObject} * - Merge {@link OpenApiV3_1.IJsonSchema.IAnyOf} to {@link OpenApi.IJsonSchema.IOneOf} * - Merge {@link OpenApiV3_1.IJsonSchema.IRecursiveReference} to {@link OpenApi.IJsonSchema.IReference} * * @author Jeongho Nam - https://github.com/samchon */ export declare namespace OpenApi { /** * Method of the operation. */ type Method = "get" | "post" | "put" | "delete" | "options" | "head" | "patch" | "trace"; /** * Convert Swagger or OpenAPI document into emended OpenAPI v3.1 document. * * @param input Swagger or OpenAPI document to convert * @returns Emended OpenAPI v3.1 document */ function convert(input: SwaggerV2.IDocument | OpenApiV3.IDocument | OpenApiV3_1.IDocument | OpenApi.IDocument): IDocument; /** * Downgrade to Swagger v2.0 document. * * Downgrade the given document (emeneded OpenAPI v3.1) into Swagger v2.0. * * @param document Emended OpenAPI v3.1 document to downgrade * @param version Version to downgrade * @returns Swagger v2.0 document */ function downgrade(document: IDocument, version: "2.0"): SwaggerV2.IDocument; /** * Downgrade to OpenAPI v3.0 document. * * Downgrade the given document (emeneded OpenAPI v3.1) into OpenAPI v3.0. * * @param document Emended OpenAPI v3.1 document to downgrade * @param version Version to downgrade * @returns OpenAPI v3.0 document */ function downgrade(document: IDocument, version: "3.0"): OpenApiV3.IDocument; /** * OpenAPI document. * * `OpenApi.IDocument` represents an OpenAPI document of emended OpenAPI v3.1. * * In other words, `OpenApi.IDocument` is a structure of `swagger.json` file of * OpenAPI v3.1 specification, but a little bit shrunk to remove ambiguous and * duplicated expressions of OpenAPI v3.1 for the convenience and clarity. */ interface IDocument { /** * OpenAPI version number. */ openapi: `3.1.${number}`; /** * List of servers that provide the API. */ servers?: IServer[]; /** * Information about the API. */ info?: IDocument.IInfo; /** * An object to hold reusable data structures. * * It stores both DTO schemas and security schemes. * * For reference, `nestia` defines every object and alias types as reusable DTO * schemas. The alias type means that defined by `type` keyword in TypeScript. */ components: IComponents; /** * The available paths and operations for the API. * * The 1st key is the path, and the 2nd key is the HTTP method. */ paths?: Record<string, IPath>; /** * An object to hold Webhooks. * * Its structure is same with {@link paths}, so that the 1st key is the path, * and the 2nd key is the HTTP method. */ webhooks?: Record<string, IPath>; /** * A declaration of which security mechanisms can be used across the API. * * When this property be configured, it would be overwritten in every API routes. * * For reference, key means the name of security scheme and value means the `scopes`. * The `scopes` can be used only when target security scheme is `oauth2` type, * especially for {@link ISwaggerSecurityScheme.IOAuth2.IFlow.scopes} property. */ security?: Record<string, string[]>[]; /** * List of tag names with description. * * It is possible to omit this property or skip some tag name even if * the tag name is used in the API routes. In that case, the tag name * would be displayed (in Swagger-UI) without description. */ tags?: IDocument.ITag[]; /** * Flag for indicating this document is emended by `@samchon/openapi` v4. */ "x-samchon-emended-v4": true; } namespace IDocument { /** * Information about the API. */ interface IInfo { /** * The title of the API. */ title: string; /** * A short summary of the API. */ summary?: string; /** * A full description of the API. */ description?: string; /** * A URL to the Terms of Service for the API. */ termsOfService?: string; /** * The contact information for the exposed API. */ contact?: IContact; /** * The license information for the exposed API. */ license?: ILicense; /** * Version of the API. */ version: string; } /** * OpenAPI tag information. * * It is possible to skip composing this structure, even if some * tag names are registered in the API routes ({@link OpenApi.IOperation.tags}). * In that case, the tag name would be displayed in Swagger-UI without * description. * * However, if you want to describe the tag name, you can compose this * structure and describe the tag name in the {@link description} property. */ interface ITag { /** * The name of the tag. */ name: string; /** * An optional string describing the tag. */ description?: string; } /** * Contact information for the exposed API. */ interface IContact { /** * The identifying name of the contact person/organization. */ name?: string; /** * The URL pointing to the contact information. */ url?: string; /** * The email address of the contact person/organization. * * @format email */ email?: string; } /** * License information for the exposed API. */ interface ILicense { /** * The license name used for the API. */ name: string; /** * Identifier for the license used for the API. * * example: MIT */ identifier?: string; /** * A URL to the license used for the API. */ url?: string; } } /** * The remote server that provides the API. */ interface IServer { /** * A URL to the target host. */ url: string; /** * An optional string describing the target server. */ description?: string; /** * A map between a variable name and its value. * * When the server {@link url} is a type of template, this property * would be utilized to fill the template with actual values. */ variables?: Record<string, IServer.IVariable>; } namespace IServer { /** * A variable for the server URL template. */ interface IVariable { /** * Default value to use for substitution. */ default: string; /** * List of available values for the variable. */ enum?: string[]; /** * An optional description for the server variable. */ description?: string; } } /** * Path item. * * `OpenApi.IPath` represents a path item of emended OpenAPI v3.1, * collecting multiple method operations in a single path. */ interface IPath extends Partial<Record<Method, IOperation>> { /** * Servers that provide the path operations. */ servers?: IServer[]; /** * Summary of the path. */ summary?: string; /** * Description of the path. */ description?: string; } /** * Remote operation info. * * `OpenApi.IOperation` represents an Restful API operation provided by the * remote server. */ interface IOperation { /** * Unique string used to identify the operation. */ operationId?: string; /** * List of parameters that are applicable for this operation. */ parameters?: IOperation.IParameter[]; /** * The request body applicable for this operation. */ requestBody?: IOperation.IRequestBody; /** * The list of possible responses as they are returned from executing this * operation. Its key is the HTTP status code, and the value is the metadata of * the response in the HTTP status code. */ responses?: Record<string, IOperation.IResponse>; /** * A list of servers providing this API operation. */ servers?: IServer[]; /** * A short summary of what the operation does. */ summary?: string; /** * A verbose explanation of the operation behavior. */ description?: string; /** * List of securities and their scopes that are required for execution. * * When this property be configured, the Restful API operation requires * the matched security value for execution. Its key means security key * matched with {@link OpenApi.IDocument.security}. * * The value means scopes required for the security key when the security * type is {@link OpenApi.ISecurityScheme.IOAuth2}. Otherwise the target * security type is not {@link OpenApi.ISecurityScheme.IOAuth2}, the value * would be empty array. */ security?: Record<string, string[]>[]; /** * Tags for API documentation control. */ tags?: string[]; /** * Flag for indicating this operation is deprecated. */ deprecated?: boolean; /** * Flag for indicating this operation is human-only. * * If this property value is `true`, {@link HttpLlm.application} * function will not convert this operation schema into the LLM function * calling schema that is represented by the {@link IHttpLlmFunction} * interface. */ "x-samchon-human"?: boolean; /** * Accessor of the operation. * * If you configure this property, the assigned value would be used as * {@link IHttpMigrateRoute.accessor}. Also, it also can be used as the * {@link IHttpLlmFunction.name} by joininig with `.` character in the * LLM function calling application. * * Note that, the `x-samchon-accessor` value must be unique in the entire * OpenAPI document operations. If there're duplicated `x-samchon-accessor` * values, {@link IHttpMigrateRoute.accessor} will ignore every duplicated * `x-samchon-accessor` values and generate the * {@link IHttpMigrateRoute.accessor} by itself. */ "x-samchon-accessor"?: string[]; /** * Controller of the operation. * * If you configure this property, the assigned value would be utilized * as the controller name in the OpenAPI generator library like * [`@nestia/editor`](https://nestia.io/docs/editor/) and * [`@nestia/migrate`](https://nestia.io/docs/migrate/). * * Also, if {@link x-samchon-accessor} has been configured, its last * element would be used as the controller method (function) name. * Of course, the OpenAPI document generator `@nestia/sdk` fills both of * them. */ "x-samchon-controller"?: string; } namespace IOperation { /** * Parameter of the operation. */ interface IParameter { /** * Representative name of the parameter. * * In the most case, the `name` is equivalent to parameter variable name. * Therefore, the `name` must be filled with the significant variable name * of the parameter. * * By the way, only when the {@link in} property is `path`, the `name` * can be omitted. In that case, the `name` is automatically deduced from * the URL path's positional template argument analyzing. */ name?: string; /** * Location of the parameter. * * The `in` property is a string that determines the location of the parameter. * * - `path`: parameter is part of the path of the URL. * - `query`: parameter is part of the query string. * - `header`: parameter is part of the header. * - `cookie`: parameter is part of the cookie. */ in: "path" | "query" | "header" | "cookie"; /** * Type info of the parameter. */ schema: IJsonSchema; /** * Whether the parameter is required for execution or not. * * If the parameter is required, the value must be filled. Otherwise, * it is possible to skip the parameter when executing the APi operation. * * For reference, the `required` property must be always `true` when the * {@link in} property is `path`. Otherwise, the `required` property can * be anything of them; `true`, `false` and `undefined`. */ required?: boolean; /** * Short title of the parameter. */ title?: string; /** * Verbose explanation of the parameter. */ description?: string; /** * Example value of the parameter. */ example?: any; /** * Collection of example values of the parameter with keys. */ examples?: Record<string, IExample>; } /** * Request body of the operation. */ interface IRequestBody { content?: IContent; description?: string; required?: boolean; "x-nestia-encrypted"?: boolean; } /** * Response of the operation. */ interface IResponse { headers?: Record<string, IOperation.IParameter>; content?: IContent; description?: string; "x-nestia-encrypted"?: boolean; } /** * List of content types supported in request/response body. */ interface IContent extends Partial<Record<ContentType, IMediaType>> { } /** * Media type of a request/response body. */ interface IMediaType { schema?: IJsonSchema; example?: any; examples?: Record<string, IExample>; } /** * List of supported content media types. */ type ContentType = "text/plain" | "application/json" | "application/x-www-form-url-encoded" | "multipart/form-data" | "*/*" | (string & {}); } /** * Example of the operation parameter or response. */ interface IExample { summary?: string; description?: string; value?: any; externalValue?: string; } /** * Reusable components in OpenAPI. * * A storage of reusable components in OpenAPI document. * * In other words, it is a storage of named DTO schemas and security schemes. */ interface IComponents { /** * An object to hold reusable DTO schemas. * * In other words, a collection of named JSON schemas. */ schemas?: Record<string, IJsonSchema>; /** * An object to hold reusable security schemes. * * In other words, a collection of named security schemes. */ securitySchemes?: Record<string, ISecurityScheme>; } /** * Type schema info. * * `OpenApi.IJsonSchema` is a type schema info of the OpenAPI. * * `OpenApi.IJsonSchema` basically follows the JSON schema definition of * OpenAPI v3.1, but a little bit shrunk to remove ambiguous and duplicated * expressions of OpenAPI v3.1 for the convenience and clarity. * * - Decompose mixed type: {@link OpenApiV3_1.IJsonSchema.IMixed} * - Resolve nullable property: {@link OpenApiV3_1.IJsonSchema.__ISignificant.nullable} * - Array type utilizes only single {@link OpenAPI.IJsonSchema.IArray.items} * - Tuple type utilizes only {@link OpenApi.IJsonSchema.ITuple.prefixItems} * - Merge {@link OpenApiV3_1.IJsonSchema.IAllOf} to {@link OpenApi.IJsonSchema.IObject} * - Merge {@link OpenApiV3_1.IJsonSchema.IAnyOf} to {@link OpenApi.IJsonSchema.IOneOf} * - Merge {@link OpenApiV3_1.IJsonSchema.IRecursiveReference} to {@link OpenApi.IJsonSchema.IReference} */ type IJsonSchema = IJsonSchema.IConstant | IJsonSchema.IBoolean | IJsonSchema.IInteger | IJsonSchema.INumber | IJsonSchema.IString | IJsonSchema.IArray | IJsonSchema.ITuple | IJsonSchema.IObject | IJsonSchema.IReference | IJsonSchema.IOneOf | IJsonSchema.INull | IJsonSchema.IUnknown; namespace IJsonSchema { /** * Constant value type. */ interface IConstant extends IJsonSchemaAttribute { /** * The constant value. */ const: boolean | number | string; } /** * Boolean type info. */ interface IBoolean extends IJsonSchemaAttribute.IBoolean { /** * The default value of the boolean type. */ default?: boolean; } /** * Integer type info. */ interface IInteger extends IJsonSchemaAttribute.IInteger { /** * Default value of the integer type. * * @type int64 */ default?: number; /** * Minimum value restriction. * * @type int64 */ minimum?: number; /** * Maximum value restriction. * * @type int64 */ maximum?: number; /** * Exclusive minimum value restriction. */ exclusiveMinimum?: number; /** * Exclusive maximum value restriction. */ exclusiveMaximum?: number; /** * Multiple of value restriction. * * @type uint64 * @exclusiveMinimum 0 */ multipleOf?: number; } /** * Number (double) type info. */ interface INumber extends IJsonSchemaAttribute.INumber { /** * Default value of the number type. */ default?: number; /** * Minimum value restriction. */ minimum?: number; /** * Maximum value restriction. */ maximum?: number; /** * Exclusive minimum value restriction. */ exclusiveMinimum?: number; /** * Exclusive maximum value restriction. */ exclusiveMaximum?: number; /** * Multiple of value restriction. * * @exclusiveMinimum 0 */ multipleOf?: number; } /** * String type info. */ interface IString extends IJsonSchemaAttribute.IString { /** * Default value of the string type. */ default?: string; /** * Format restriction. */ 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 restriction. */ pattern?: string; /** * Content media type restriction. */ contentMediaType?: string; /** * Minimum length restriction. * * @type uint64 */ minLength?: number; /** * Maximum length restriction. * * @type uint64 */ maxLength?: number; } /** * Array type info. */ interface IArray extends IJsonSchemaAttribute.IArray { /** * Items type info. * * The `items` means the type of the array elements. In other words, it is * the type schema info of the `T` in the TypeScript array type `Array<T>`. */ items: IJsonSchema; /** * Unique items restriction. * * If this property value is `true`, target array must have unique items. */ uniqueItems?: boolean; /** * Minimum items restriction. * * Restriction of minimum number of items in the array. * * @type uint64 */ minItems?: number; /** * Maximum items restriction. * * Restriction of maximum number of items in the array. * * @type uint64 */ maxItems?: number; } /** * Tuple type info. */ interface ITuple extends IJsonSchemaAttribute { /** * Discriminator value of the type. * * Note that, the tuple type cannot be distinguished with * {@link IArray} type just by this `discriminator` property. * * To check whether the type is tuple or array, you have to check * the existence of {@link IArray.items} or {@link ITuple.prefixItems} * properties. */ type: "array"; /** * Prefix items. * * The `prefixItems` means the type schema info of the prefix items in the * tuple type. In the TypeScript, it is expressed as `[T1, T2]`. * * If you want to express `[T1, T2, ...TO[]]` type, you can configure the * `...TO[]` through the {@link additionalItems} property. */ prefixItems: IJsonSchema[]; /** * Additional items. * * The `additionalItems` means the type schema info of the additional items * after the {@link prefixItems}. In the TypeScript, if there's a type * `[T1, T2, ...TO[]]`, the `...TO[]` is represented by the `additionalItems`. * * By the way, if you configure the `additionalItems` as `true`, it means * the additional items are not restricted. They can be any type, so that * it is equivalent to the TypeScript type `[T1, T2, ...any[]]`. * * Otherwise configure the `additionalItems` as the {@link IJsonSchema}, * it means the additional items must follow the type schema info. * Therefore, it is equivalent to the TypeScript type `[T1, T2, ...TO[]]`. */ additionalItems?: boolean | IJsonSchema; /** * Unique items restriction. * * If this property value is `true`, target tuple must have unique items. */ uniqueItems?: boolean; /** * Minimum items restriction. * * Restriction of minimum number of items in the tuple. * * @type uint64 */ minItems?: number; /** * Maximum items restriction. * * Restriction of maximum number of items in the tuple. * * @type uint64 */ maxItems?: number; } /** * Object type info. */ interface IObject extends IJsonSchemaAttribute.IObject { /** * Properties of the object. * * The `properties` means a list of key-value pairs of the object's * regular properties. The key is the name of the regular property, * and the value is the type schema info. * * If you need additional properties that is represented by dynamic key, * you can use the {@link additionalProperties} instead. */ properties?: Record<string, IJsonSchema>; /** * Additional properties' info. * * The `additionalProperties` means the type schema info of the additional * properties that are not listed in the {@link properties}. * * If the value is `true`, it means that the additional properties are not * restricted. They can be any type. Otherwise, if the value is * {@link IOpenAiSchema} type, it means that the additional properties must * follow the type schema info. * * - `true`: `Record<string, any>` * - `IOpenAiSchema`: `Record<string, T>` */ additionalProperties?: boolean | IJsonSchema; /** * List of key values of the required properties. * * The `required` means a list of the key values of the required * {@link properties}. If some property key is not listed in the `required` * list, it means that property is optional. Otherwise some property key * exists in the `required` list, it means that the property must be filled. * * Below is an example of the {@link properties} and `required`. * * ```typescript * interface SomeObject { * id: string; * email: string; * name?: string; * } * ``` * * As you can see, `id` and `email` {@link properties} are {@link required}, * so that they are listed in the `required` list. * * ```json * { * "type": "object", * "properties": { * "id": { "type": "string" }, * "email": { "type": "string" }, * "name": { "type": "string" } * }, * "required": ["id", "email"] * } * ``` */ required?: string[]; } /** * Reference type directing named schema. */ interface IReference<Key = string> extends IJsonSchemaAttribute { /** * Reference to the named schema. * * The `ref` is a reference to the named schema. Format of the `$ref` is * following the JSON Pointer specification. In the OpenAPI, the `$ref` * starts with `#/components/schemas/` which means the type is stored in * the {@link OpenApi.IComponents.schemas} object. * * - `#/components/schemas/SomeObject` * - `#/components/schemas/AnotherObject` */ $ref: Key; } /** * Union type. * * IOneOf` represents an union type of the TypeScript (`A | B | C`). * * For reference, even though your Swagger (or OpenAPI) document has * defined `anyOf` instead of the `oneOf`, {@link OpenApi} forcibly * converts it to `oneOf` type. */ interface IOneOf extends IJsonSchemaAttribute { /** * List of the union types. */ oneOf: Exclude<IJsonSchema, IJsonSchema.IOneOf>[]; /** * Discriminator info of the union type. */ discriminator?: IOneOf.IDiscriminator; } namespace IOneOf { /** * Discriminator info of the union type. */ interface IDiscriminator { /** * Property name for the discriminator. */ propertyName: string; /** * Mapping of the discriminator value to the schema name. * * This property is valid only for {@link IReference} typed * {@link IOneOf.oneof} elements. Therefore, `key` of `mapping` is * the discriminator value, and `value` of `mapping` is the * schema name like `#/components/schemas/SomeObject`. */ mapping?: Record<string, string>; } } /** * Null type. */ interface INull extends IJsonSchemaAttribute.INull { /** * Default value of the `null` type. */ default?: null; } /** * Unknown, the `any` type. */ interface IUnknown extends IJsonSchemaAttribute.IUnknown { /** * Default value of the `any` type. */ default?: any; } /** * Significant attributes that can be applied to the most types. * * @deprecated * @hidden */ interface __ISignificant<Type extends string> extends IJsonSchemaAttribute { /** * Discriminator value of the type. */ type: Type; } /** * Common attributes that can be applied to all types. * * @deprecated * @hidden */ type __IAttribute = IJsonSchemaAttribute; } /** * Security scheme of Swagger Documents. * * `OpenApi.ISecurityScheme` is a data structure representing content of * `securitySchemes` in `swagger.json` file. It is composed with 5 types of * security schemes as an union type like below. * * @reference https://swagger.io/specification/#security-scheme-object */ type ISecurityScheme = ISecurityScheme.IApiKey | ISecurityScheme.IHttpBasic | ISecurityScheme.IHttpBearer | ISecurityScheme.IOAuth2 | ISecurityScheme.IOpenId; namespace ISecurityScheme { /** * Normal API key type. */ interface IApiKey { type: "apiKey"; in?: "header" | "query" | "cookie"; name?: string; description?: string; } /** * HTTP basic authentication type. */ interface IHttpBasic { type: "http"; scheme: "basic"; description?: string; } /** * HTTP bearer authentication type. */ interface IHttpBearer { type: "http"; scheme: "bearer"; bearerFormat?: string; description?: string; } /** * OAuth2 authentication type. */ interface IOAuth2 { type: "oauth2"; flows: IOAuth2.IFlowSet; description?: string; } interface IOpenId { type: "openIdConnect"; openIdConnectUrl: string; description?: string; } namespace IOAuth2 { interface IFlowSet { authorizationCode?: IFlow; implicit?: Omit<IFlow, "tokenUrl">; password?: Omit<IFlow, "authorizationUrl">; clientCredentials?: Omit<IFlow, "authorizationUrl">; } interface IFlow { authorizationUrl?: string; tokenUrl?: string; refreshUrl?: string; scopes?: Record<string, string>; } } } }