diff --git a/plugins/openapi-router/api-report.md b/plugins/openapi-router/api-report.md index 5c09d0432d..28a32cd4af 100644 --- a/plugins/openapi-router/api-report.md +++ b/plugins/openapi-router/api-report.md @@ -8,10 +8,12 @@ import core from 'express-serve-static-core'; import { FromSchema } from 'json-schema-to-ts'; import { JSONSchema7 } from 'json-schema-to-ts'; import type { OpenAPIObject } from 'openapi3-ts'; +import type { ParameterObject } from 'openapi3-ts'; import type { ReferenceObject } from 'openapi3-ts'; import type { RequestBodyObject } from 'openapi3-ts'; import type { ResponseObject } from 'openapi3-ts'; import { Router } from 'express'; +import type { SchemaObject } from 'openapi3-ts'; // @public export interface ApiRouter extends Router { @@ -62,6 +64,27 @@ export type ConvertAll = []> = T extends [ ? ConvertAll]> : R; +// @public (undocumented) +export interface CookieObject extends ParameterObject { + // (undocumented) + in: 'cookie'; + // (undocumented) + style?: 'form'; +} + +// @public (undocumented) +export type CookieSchema< + Doc extends RequiredDoc, + Path extends PathTemplate>, + Method extends DocPathMethod, +> = ParametersSchema, Method, ImmutableCookieObject>; + +// @public (undocumented) +export type DiscriminateUnion = Extract< + T, + Record +>; + // @public (undocumented) export type DocOperation< Doc extends RequiredDoc, @@ -69,6 +92,41 @@ export type DocOperation< Method extends keyof Doc['paths'][Path], > = Doc['paths'][Path][Method]; +// @public (undocumented) +export type DocParameter< + Doc extends RequiredDoc, + Path extends Extract, + Method extends keyof Doc['paths'][Path], + Parameter extends keyof Doc['paths'][Path][Method]['parameters'], +> = DocOperation< + Doc, + Path, + Method +>['parameters'][Parameter] extends ImmutableReferenceObject + ? 'parameters' extends ComponentTypes + ? ComponentRef< + Doc, + 'parameters', + DocOperation['parameters'][Parameter] + > + : never + : DocOperation['parameters'][Parameter]; + +// @public (undocumented) +export type DocParameters< + Doc extends RequiredDoc, + Path extends Extract, + Method extends keyof Doc['paths'][Path], +> = DocOperation['parameters'] extends ReadonlyArray + ? { + [Index in keyof DocOperation< + Doc, + Path, + Method + >['parameters']]: DocParameter; + } + : never; + // @public export type DocPath< Doc extends PathDoc, @@ -97,10 +155,10 @@ export type DocRequestHandler< Path extends DocPathTemplate, Method extends keyof Doc['paths'][Path], > = core.RequestHandler< - core.ParamsDictionary, + PathSchema, ResponseBodyToJsonSchema, RequestBodyToJsonSchema, - ParsedQs, + QuerySchema, Record >; @@ -110,10 +168,10 @@ export type DocRequestHandlerParams< Path extends DocPathTemplate, Method extends keyof Doc['paths'][Path], > = core.RequestHandlerParams< - core.ParamsDictionary, + PathSchema, ResponseBodyToJsonSchema, RequestBodyToJsonSchema, - ParsedQs, + QuerySchema, Record >; @@ -143,6 +201,31 @@ export interface DocRequestMatcher< ): T; } +// @public (undocumented) +export type Filter = T extends U ? T : never; + +// @public (undocumented) +export type FullMap< + T extends { + [key: string]: any; + }, +> = RequiredMap & OptionalMap; + +// @public (undocumented) +export interface HeaderObject extends ParameterObject { + // (undocumented) + in: 'header'; + // (undocumented) + style: 'simple'; +} + +// @public (undocumented) +export type HeaderSchema< + Doc extends RequiredDoc, + Path extends PathTemplate>, + Method extends DocPathMethod, +> = ParametersSchema, Method, ImmutableHeaderObject>; + // @public export type Immutable = T extends | Function @@ -163,6 +246,12 @@ export type Immutable = T extends // @public (undocumented) export type ImmutableContentObject = ImmutableObject; +// @public (undocumented) +export type ImmutableCookieObject = ImmutableObject; + +// @public (undocumented) +export type ImmutableHeaderObject = ImmutableObject; + // @public (undocumented) export type ImmutableObject = { readonly [K in keyof T]: Immutable; @@ -171,12 +260,24 @@ export type ImmutableObject = { // @public (undocumented) export type ImmutableOpenAPIObject = ImmutableObject; +// @public (undocumented) +export type ImmutableParameterObject = ImmutableObject; + +// @public (undocumented) +export type ImmutablePathObject = ImmutableObject; + +// @public (undocumented) +export type ImmutableQueryObject = ImmutableObject; + // @public (undocumented) export type ImmutableReferenceObject = ImmutableObject; // @public (undocumented) export type ImmutableRequestBodyObject = ImmutableObject; +// @public (undocumented) +export type ImmutableSchemaObject = ImmutableObject; + // @public (undocumented) export type LastOf = UnionToIntersection< T extends any ? () => T : never @@ -184,6 +285,24 @@ export type LastOf = UnionToIntersection< ? R : never; +// @public (undocumented) +export type MapDiscriminatedUnion< + T extends Record, + K extends keyof T, +> = { + [V in T[K]]: DiscriminateUnion; +}; + +// @public (undocumented) +export type MapToSchema< + Doc extends RequiredDoc, + T extends Record, +> = { + [V in keyof T]: NonNullable extends ImmutableParameterObject + ? ParameterSchema['schema']> + : never; +}; + // @public (undocumented) export type MethodAwareDocPath< Doc extends PathDoc, @@ -210,6 +329,45 @@ export type ObjectWithContentSchema< ? SchemaRef : never; +// @public (undocumented) +export type OptionalMap< + T extends { + [key: string]: any; + }, +> = { + [P in Exclude, undefined>]?: NonNullable; +}; + +// @public (undocumented) +export type ParameterSchema< + Doc extends RequiredDoc, + Schema extends ImmutableParameterObject['schema'], +> = ResolveDocParameterSchema extends infer R + ? R extends ImmutableSchemaObject + ? R extends JSONSchema7 + ? FromSchema + : never + : never + : never; + +// @public (undocumented) +export type ParametersSchema< + Doc extends RequiredDoc, + Path extends Extract, + Method extends keyof Doc['paths'][Path], + FilterType extends ImmutableParameterObject, +> = number extends keyof DocParameters + ? MapToSchema< + Doc, + FullMap< + MapDiscriminatedUnion< + Filter[number], FilterType>, + 'name' + > + > + > + : never; + // @public export interface ParsedQs { // (undocumented) @@ -219,15 +377,63 @@ export interface ParsedQs { // @public (undocumented) export type PathDoc = Pick; +// @public (undocumented) +export interface PathObject extends ParameterObject { + // (undocumented) + in: 'path'; + // (undocumented) + style?: 'simple' | 'label' | 'matrix'; +} + +// @public (undocumented) +export type PathSchema< + Doc extends RequiredDoc, + Path extends PathTemplate>, + Method extends DocPathMethod, +> = ParametersSchema, Method, ImmutablePathObject>; + // @public export type PathTemplate = - Path extends `${infer Prefix}{${string}}${infer Suffix}` - ? `${Prefix}${string}${PathTemplate}` + Path extends `${infer Prefix}{${infer PathName}}${infer Suffix}` + ? `${Prefix}:${PathName}${PathTemplate}` : Path; +// @public (undocumented) +export type PickOptionalKeys< + T extends { + [key: string]: any; + }, +> = { + [K in keyof T]: true extends T[K]['required'] ? never : K; +}[keyof T]; + +// @public (undocumented) +export type PickRequiredKeys< + T extends { + [key: string]: any; + }, +> = { + [K in keyof T]: true extends T[K]['required'] ? K : never; +}[keyof T]; + // @public (undocumented) export type Push = [...T, V]; +// @public (undocumented) +export interface QueryObject extends ParameterObject { + // (undocumented) + in: 'query'; + // (undocumented) + style?: 'form' | 'deepObject' | 'pipeDelimited' | 'spaceDelimited'; +} + +// @public (undocumented) +export type QuerySchema< + Doc extends RequiredDoc, + Path extends PathTemplate>, + Method extends DocPathMethod, +> = ParametersSchema, Method, ImmutableQueryObject>; + // @public (undocumented) export type RequestBody< Doc extends RequiredDoc, @@ -270,6 +476,25 @@ export type RequestBodyToJsonSchema< // @public export type RequiredDoc = Pick; +// @public (undocumented) +export type RequiredMap< + T extends { + [key: string]: any; + }, +> = { + [P in Exclude, undefined>]: NonNullable; +}; + +// @public (undocumented) +export type ResolveDocParameterSchema< + Doc extends RequiredDoc, + Schema extends ImmutableParameterObject['schema'], +> = Schema extends ImmutableReferenceObject + ? 'parameters' extends ComponentTypes + ? ComponentRef + : never + : Schema; + // @public (undocumented) type Response_2< Doc extends RequiredDoc, diff --git a/plugins/openapi-router/src/example.ts b/plugins/openapi-router/src/example.ts index af9871993a..9aa3047b28 100644 --- a/plugins/openapi-router/src/example.ts +++ b/plugins/openapi-router/src/example.ts @@ -26,7 +26,7 @@ export async function createRouter( console.log(options); const router = Router() as ApiRouter; - router.get('/pets/:uid', (_, res) => { + router.get('/pets/:petId', (_, res) => { res.json({ id: 1, name: 'test', diff --git a/plugins/openapi-router/src/types/common.ts b/plugins/openapi-router/src/types/common.ts index d1171257ed..50ed6e03cd 100644 --- a/plugins/openapi-router/src/types/common.ts +++ b/plugins/openapi-router/src/types/common.ts @@ -58,8 +58,8 @@ export type ValueOf = T[keyof T]; * @public */ export type PathTemplate = - Path extends `${infer Prefix}{${string}}${infer Suffix}` - ? `${Prefix}${string}${PathTemplate}` + Path extends `${infer Prefix}{${infer PathName}}${infer Suffix}` + ? `${Prefix}:${PathName}${PathTemplate}` : Path; /** @@ -231,11 +231,17 @@ export type UnknownIfNever

= [P] extends [never] ? unknown : P; */ export type ToTypeSafe = UnknownIfNever>[number]>; -type DiscriminateUnion = Extract< +/** + * @public + */ +export type DiscriminateUnion = Extract< T, Record >; +/** + * @public + */ export type MapDiscriminatedUnion< T extends Record, K extends keyof T, @@ -243,23 +249,41 @@ export type MapDiscriminatedUnion< [V in T[K]]: DiscriminateUnion; }; +/** + * @public + */ export type PickOptionalKeys = { [K in keyof T]: true extends T[K]['required'] ? never : K; }[keyof T]; +/** + * @public + */ export type PickRequiredKeys = { [K in keyof T]: true extends T[K]['required'] ? K : never; }[keyof T]; +/** + * @public + */ export type OptionalMap = { [P in Exclude, undefined>]?: NonNullable; }; +/** + * @public + */ export type RequiredMap = { [P in Exclude, undefined>]: NonNullable; }; +/** + * @public + */ export type FullMap = RequiredMap & OptionalMap; +/** + * @public + */ export type Filter = T extends U ? T : never; diff --git a/plugins/openapi-router/src/types/immutable.ts b/plugins/openapi-router/src/types/immutable.ts index dc6e20c827..880a081ba0 100644 --- a/plugins/openapi-router/src/types/immutable.ts +++ b/plugins/openapi-router/src/types/immutable.ts @@ -71,34 +71,64 @@ export type ImmutableContentObject = ImmutableObject; */ export type ImmutableRequestBodyObject = ImmutableObject; +/** + * @public + */ export type ImmutableParameterObject = ImmutableObject; +/** + * @public + */ export interface HeaderObject extends ParameterObject { in: 'header'; style: 'simple'; } +/** + * @public + */ export type ImmutableHeaderObject = ImmutableObject; +/** + * @public + */ export interface CookieObject extends ParameterObject { in: 'cookie'; style?: 'form'; } +/** + * @public + */ export type ImmutableCookieObject = ImmutableObject; +/** + * @public + */ export interface QueryObject extends ParameterObject { in: 'query'; style?: 'form' | 'deepObject' | 'pipeDelimited' | 'spaceDelimited'; } +/** + * @public + */ export type ImmutableQueryObject = ImmutableObject; +/** + * @public + */ export interface PathObject extends ParameterObject { in: 'path'; style?: 'simple' | 'label' | 'matrix'; } +/** + * @public + */ export type ImmutablePathObject = ImmutableObject; +/** + * @public + */ export type ImmutableSchemaObject = ImmutableObject; diff --git a/plugins/openapi-router/src/types/index.ts b/plugins/openapi-router/src/types/index.ts index 1a1f5265bf..e656e1967c 100644 --- a/plugins/openapi-router/src/types/index.ts +++ b/plugins/openapi-router/src/types/index.ts @@ -18,3 +18,4 @@ export * from './express'; export * from './requests'; export * from './responses'; export * from './immutable'; +export * from './params'; diff --git a/plugins/openapi-router/src/types/params.ts b/plugins/openapi-router/src/types/params.ts index 9af1fa6eaa..dce743e6e8 100644 --- a/plugins/openapi-router/src/types/params.ts +++ b/plugins/openapi-router/src/types/params.ts @@ -36,8 +36,10 @@ import { RequiredDoc, } from './common'; import { FromSchema, JSONSchema7 } from 'json-schema-to-ts'; -import spec from '../schema/petstore'; +/** + * @public + */ export type DocParameter< Doc extends RequiredDoc, Path extends Extract, @@ -74,6 +76,9 @@ export type DocParameters< } : never; +/** + * @public + */ export type ResolveDocParameterSchema< Doc extends RequiredDoc, Schema extends ImmutableParameterObject['schema'], @@ -83,6 +88,9 @@ export type ResolveDocParameterSchema< : never : Schema; +/** + * @public + */ export type ParameterSchema< Doc extends RequiredDoc, Schema extends ImmutableParameterObject['schema'], @@ -94,7 +102,10 @@ export type ParameterSchema< : never : never; -type MapToSchema< +/** + * @public + */ +export type MapToSchema< Doc extends RequiredDoc, T extends Record, > = { @@ -103,6 +114,9 @@ type MapToSchema< : never; }; +/** + * @public + */ export type ParametersSchema< Doc extends RequiredDoc, Path extends Extract, @@ -120,24 +134,36 @@ export type ParametersSchema< > : never; +/** + * @public + */ export type HeaderSchema< Doc extends RequiredDoc, Path extends PathTemplate>, Method extends DocPathMethod, > = ParametersSchema, Method, ImmutableHeaderObject>; +/** + * @public + */ export type CookieSchema< Doc extends RequiredDoc, Path extends PathTemplate>, Method extends DocPathMethod, > = ParametersSchema, Method, ImmutableCookieObject>; +/** + * @public + */ export type PathSchema< Doc extends RequiredDoc, Path extends PathTemplate>, Method extends DocPathMethod, > = ParametersSchema, Method, ImmutablePathObject>; +/** + * @public + */ export type QuerySchema< Doc extends RequiredDoc, Path extends PathTemplate>,