express-zod-api 22.0.0-beta.1 → 22.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ import { ListenOptions } from 'node:net';
12
12
  import * as qs from 'qs';
13
13
  import * as express_serve_static_core from 'express-serve-static-core';
14
14
  import http from 'node:http';
15
- import { SchemaObject, ReferenceObject, OpenApiBuilder, SecuritySchemeType, SecuritySchemeObject } from 'openapi3-ts/oas31';
15
+ import { SchemaObject, ReferenceObject, TagObject, OpenApiBuilder, SecuritySchemeType, SecuritySchemeObject } from 'openapi3-ts/oas31';
16
16
  import * as node_mocks_http from 'node-mocks-http';
17
17
  import { RequestOptions, ResponseOptions } from 'node-mocks-http';
18
18
  import ts from 'typescript';
@@ -78,6 +78,11 @@ declare class BuiltinLogger implements AbstractLogger {
78
78
  warn(message: string, meta?: unknown): void;
79
79
  error(message: string, meta?: unknown): void;
80
80
  child(ctx: Context): BuiltinLogger;
81
+ /**
82
+ * @desc The argument used for instance created by .child() method
83
+ * @see ChildLoggerProvider
84
+ * */
85
+ get ctx(): Context;
81
86
  /** @desc Measures the duration until you invoke the returned callback */
82
87
  profile(message: string): () => void;
83
88
  profile(options: ProfilerOptions): () => void;
@@ -442,15 +447,11 @@ type HeadersProvider = (params: {
442
447
  endpoint: AbstractEndpoint;
443
448
  logger: ActualLogger;
444
449
  }) => Headers | Promise<Headers>;
445
- type TagsConfig<TAG extends string> = Record<TAG, string | {
446
- description: string;
447
- url?: string;
448
- }>;
449
450
  type ChildLoggerProvider = (params: {
450
451
  request: Request;
451
452
  parent: ActualLogger;
452
453
  }) => ActualLogger | Promise<ActualLogger>;
453
- interface CommonConfig<TAG extends string = string> {
454
+ interface CommonConfig {
454
455
  /**
455
456
  * @desc Enables cross-origin resource sharing.
456
457
  * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
@@ -486,11 +487,6 @@ interface CommonConfig<TAG extends string = string> {
486
487
  * @see defaultInputSources
487
488
  */
488
489
  inputSources?: Partial<InputSources>;
489
- /**
490
- * @desc Optional endpoints tagging configuration.
491
- * @example: { users: "Everything about the users" }
492
- */
493
- tags?: TagsConfig<TAG>;
494
490
  }
495
491
  type BeforeUpload = (params: {
496
492
  request: Request;
@@ -538,7 +534,7 @@ interface HttpsConfig extends HttpConfig {
538
534
  /** @desc At least "cert" and "key" options required. */
539
535
  options: ServerOptions;
540
536
  }
541
- interface ServerConfig<TAG extends string = string> extends CommonConfig<TAG> {
537
+ interface ServerConfig extends CommonConfig {
542
538
  /** @desc HTTP server configuration. */
543
539
  http?: HttpConfig;
544
540
  /** @desc HTTPS server configuration. */
@@ -581,17 +577,27 @@ interface ServerConfig<TAG extends string = string> extends CommonConfig<TAG> {
581
577
  * */
582
578
  gracefulShutdown?: boolean | GracefulOptions;
583
579
  }
584
- interface AppConfig<TAG extends string = string> extends CommonConfig<TAG> {
580
+ interface AppConfig extends CommonConfig {
585
581
  /** @desc Your custom express app or express router instead. */
586
582
  app: IRouter;
587
583
  }
588
- declare function createConfig<TAG extends string>(config: ServerConfig<TAG>): ServerConfig<TAG>;
589
- declare function createConfig<TAG extends string>(config: AppConfig<TAG>): AppConfig<TAG>;
584
+ declare function createConfig(config: ServerConfig): ServerConfig;
585
+ declare function createConfig(config: AppConfig): AppConfig;
590
586
 
591
587
  /** @desc this type does not allow props assignment, but it works for reading them when merged with another interface */
592
588
  type EmptyObject = Record<string, never>;
593
589
  type EmptySchema = z.ZodObject<EmptyObject, "strip">;
594
590
  type FlatObject = Record<string, unknown>;
591
+ /** @link https://stackoverflow.com/a/65492934 */
592
+ type NoNever<T, F> = [T] extends [never] ? F : T;
593
+ /**
594
+ * @desc Using module augmentation approach you can specify tags as the keys of this interface
595
+ * @example declare module "express-zod-api" { interface TagOverrides { users: unknown } }
596
+ * @link https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
597
+ * */
598
+ interface TagOverrides {
599
+ }
600
+ type Tag = NoNever<keyof TagOverrides, string>;
595
601
  declare const getMessageFromError: (error: Error) => string;
596
602
  declare const getExamples: <T extends z.ZodTypeAny, V extends "original" | "parsed" | undefined>({ schema, variant, validate, }: {
597
603
  schema: T;
@@ -655,7 +661,7 @@ declare module "zod" {
655
661
  }
656
662
  }
657
663
 
658
- interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN extends IOSchema<"strip">, OPT extends FlatObject, SCO extends string, TAG extends string> {
664
+ interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN extends IOSchema<"strip">, OPT extends FlatObject, SCO extends string> {
659
665
  input?: IN;
660
666
  output: OUT;
661
667
  handler: Handler<z.output<z.ZodIntersection<MIN, IN>>, z.input<OUT>, OPT>;
@@ -664,37 +670,31 @@ interface BuildProps<IN extends IOSchema, OUT extends IOSchema | z.ZodVoid, MIN
664
670
  operationId?: string | ((method: Method) => string);
665
671
  method?: Method | [Method, ...Method[]];
666
672
  scope?: SCO | SCO[];
667
- tag?: TAG | TAG[];
673
+ tag?: Tag | Tag[];
668
674
  }
669
- declare class EndpointsFactory<IN extends IOSchema<"strip"> = EmptySchema, OUT extends FlatObject = EmptyObject, SCO extends string = string, TAG extends string = string> {
675
+ declare class EndpointsFactory<IN extends IOSchema<"strip"> = EmptySchema, OUT extends FlatObject = EmptyObject, SCO extends string = string> {
670
676
  #private;
671
677
  protected resultHandler: AbstractResultHandler;
672
678
  protected middlewares: AbstractMiddleware[];
673
- /** @desc Consider using the "config" prop with the "tags" option to enforce constraints on tagging the endpoints */
674
679
  constructor(resultHandler: AbstractResultHandler);
675
- /** @todo consider migrating tags into augmentation approach in v22 */
676
- constructor(params: {
677
- resultHandler: AbstractResultHandler;
678
- config?: CommonConfig<TAG>;
679
- });
680
- addMiddleware<AOUT extends FlatObject, ASCO extends string, AIN extends IOSchema<"strip"> = EmptySchema>(subject: Middleware<OUT, AOUT, ASCO, AIN> | ConstructorParameters<typeof Middleware<OUT, AOUT, ASCO, AIN>>[0]): EndpointsFactory<z.ZodIntersection<IN, AIN>, OUT & AOUT, SCO & ASCO, TAG>;
680
+ addMiddleware<AOUT extends FlatObject, ASCO extends string, AIN extends IOSchema<"strip"> = EmptySchema>(subject: Middleware<OUT, AOUT, ASCO, AIN> | ConstructorParameters<typeof Middleware<OUT, AOUT, ASCO, AIN>>[0]): EndpointsFactory<z.ZodIntersection<IN, AIN>, OUT & AOUT, SCO & ASCO>;
681
681
  use: <R extends Request, S extends Response, AOUT extends FlatObject = EmptyObject>(nativeMw: (request: R, response: S, next: express.NextFunction) => void | Promise<void>, params_1?: {
682
682
  provider?: ((request: R, response: S) => AOUT | Promise<AOUT>) | undefined;
683
683
  transformer?: (err: Error) => Error;
684
- } | undefined) => EndpointsFactory<IN, OUT & AOUT, SCO, TAG>;
685
- addExpressMiddleware<R extends Request, S extends Response, AOUT extends FlatObject = EmptyObject>(...params: ConstructorParameters<typeof ExpressMiddleware<R, S, AOUT>>): EndpointsFactory<IN, OUT & AOUT, SCO, TAG>;
686
- addOptions<AOUT extends FlatObject>(getOptions: () => Promise<AOUT>): EndpointsFactory<IN, OUT & AOUT, SCO, TAG>;
687
- build<BOUT extends IOSchema, BIN extends IOSchema = EmptySchema>({ input, handler, output: outputSchema, description, shortDescription, operationId, scope, tag, method, }: BuildProps<BIN, BOUT, IN, OUT, SCO, TAG>): Endpoint<z.ZodIntersection<IN, BIN>, BOUT, OUT>;
684
+ } | undefined) => EndpointsFactory<IN, OUT & AOUT, SCO>;
685
+ addExpressMiddleware<R extends Request, S extends Response, AOUT extends FlatObject = EmptyObject>(...params: ConstructorParameters<typeof ExpressMiddleware<R, S, AOUT>>): EndpointsFactory<IN, OUT & AOUT, SCO>;
686
+ addOptions<AOUT extends FlatObject>(getOptions: () => Promise<AOUT>): EndpointsFactory<IN, OUT & AOUT, SCO>;
687
+ build<BOUT extends IOSchema, BIN extends IOSchema = EmptySchema>({ input, handler, output: outputSchema, description, shortDescription, operationId, scope, tag, method, }: BuildProps<BIN, BOUT, IN, OUT, SCO>): Endpoint<z.ZodIntersection<IN, BIN>, BOUT, OUT>;
688
688
  /** @desc shorthand for returning {} while having output schema z.object({}) */
689
- buildVoid<BIN extends IOSchema = EmptySchema>({ handler, ...rest }: Omit<BuildProps<BIN, z.ZodVoid, IN, OUT, SCO, TAG>, "output">): Endpoint<z.ZodIntersection<IN, BIN>, z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>, OUT>;
689
+ buildVoid<BIN extends IOSchema = EmptySchema>({ handler, ...rest }: Omit<BuildProps<BIN, z.ZodVoid, IN, OUT, SCO>, "output">): Endpoint<z.ZodIntersection<IN, BIN>, z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>, OUT>;
690
690
  }
691
- declare const defaultEndpointsFactory: EndpointsFactory<EmptySchema, EmptyObject, string, string>;
691
+ declare const defaultEndpointsFactory: EndpointsFactory<EmptySchema, EmptyObject, string>;
692
692
  /**
693
693
  * @deprecated Resist the urge of using it: this factory is designed only to simplify the migration of legacy APIs.
694
694
  * @desc Responding with array is a bad practice keeping your endpoints from evolving without breaking changes.
695
695
  * @desc The result handler of this factory expects your endpoint to have the property 'items' in the output schema
696
696
  */
697
- declare const arrayEndpointsFactory: EndpointsFactory<EmptySchema, EmptyObject, string, string>;
697
+ declare const arrayEndpointsFactory: EndpointsFactory<EmptySchema, EmptyObject, string>;
698
698
 
699
699
  declare const attachRouting: (config: AppConfig, routing: Routing) => {
700
700
  notFoundHandler: express__default.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
@@ -752,6 +752,10 @@ interface OpenAPIContext extends FlatObject {
752
752
  method: Method;
753
753
  }
754
754
  type Depicter = SchemaHandler<SchemaObject | ReferenceObject, OpenAPIContext>;
755
+ declare const depictTags: (tags: Partial<Record<Tag, string | {
756
+ description: string;
757
+ url?: string;
758
+ }>>) => TagObject[];
755
759
 
756
760
  type Component = "positiveResponse" | "negativeResponse" | "requestParameter" | "requestBody";
757
761
  /** @desc user defined function that creates a component description from its properties */
@@ -781,6 +785,12 @@ interface DocumentationParams {
781
785
  * @example { MyBrand: ( schema: typeof myBrandSchema, { next } ) => ({ type: "object" })
782
786
  */
783
787
  brandHandling?: HandlingRules<SchemaObject | ReferenceObject, OpenAPIContext>;
788
+ /**
789
+ * @desc Extended description of tags used in endpoints. For enforcing constraints:
790
+ * @see TagOverrides
791
+ * @example { users: "About users", files: { description: "About files", url: "https://example.com" } }
792
+ * */
793
+ tags?: Parameters<typeof depictTags>[0];
784
794
  }
785
795
  declare class Documentation extends OpenApiBuilder {
786
796
  protected lastSecuritySchemaIds: Map<SecuritySchemeType, number>;
@@ -789,7 +799,7 @@ declare class Documentation extends OpenApiBuilder {
789
799
  protected makeRef(schema: z.ZodTypeAny, subject: SchemaObject | ReferenceObject | (() => SchemaObject | ReferenceObject), name?: string | undefined): ReferenceObject;
790
800
  protected ensureUniqOperationId(path: string, method: Method, userDefined?: string): string;
791
801
  protected ensureUniqSecuritySchemaName(subject: SecuritySchemeObject): string;
792
- constructor({ routing, config, title, version, serverUrl, descriptions, brandHandling, hasSummaryFromDescription, composition, }: DocumentationParams);
802
+ constructor({ routing, config, title, version, serverUrl, descriptions, brandHandling, tags, hasSummaryFromDescription, composition, }: DocumentationParams);
793
803
  }
794
804
 
795
805
  /** @desc An error related to the wrong Routing declaration */
@@ -899,9 +909,70 @@ declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOption
899
909
  output: FlatObject;
900
910
  }>;
901
911
 
912
+ type IOKind = "input" | "response" | ResponseVariant | "encoded";
913
+ declare abstract class IntegrationBase {
914
+ private readonly serverUrl;
915
+ protected paths: Set<string>;
916
+ protected tags: Map<string, readonly string[]>;
917
+ protected registry: Map<string, Record<IOKind, ts.TypeNode>>;
918
+ protected ids: {
919
+ pathType: ts.Identifier;
920
+ methodType: ts.Identifier;
921
+ requestType: ts.Identifier;
922
+ inputInterface: ts.Identifier;
923
+ posResponseInterface: ts.Identifier;
924
+ negResponseInterface: ts.Identifier;
925
+ encResponseInterface: ts.Identifier;
926
+ responseInterface: ts.Identifier;
927
+ endpointTagsConst: ts.Identifier;
928
+ implementationType: ts.Identifier;
929
+ clientClass: ts.Identifier;
930
+ keyParameter: ts.Identifier;
931
+ pathParameter: ts.Identifier;
932
+ paramsArgument: ts.Identifier;
933
+ methodParameter: ts.Identifier;
934
+ requestParameter: ts.Identifier;
935
+ parseRequestFn: ts.Identifier;
936
+ substituteFn: ts.Identifier;
937
+ provideMethod: ts.Identifier;
938
+ implementationArgument: ts.Identifier;
939
+ headersProperty: ts.Identifier;
940
+ hasBodyConst: ts.Identifier;
941
+ undefinedValue: ts.Identifier;
942
+ bodyProperty: ts.Identifier;
943
+ responseConst: ts.Identifier;
944
+ restConst: ts.Identifier;
945
+ searchParamsConst: ts.Identifier;
946
+ exampleImplementationConst: ts.Identifier;
947
+ clientConst: ts.Identifier;
948
+ contentTypeConst: ts.Identifier;
949
+ isJsonConst: ts.Identifier;
950
+ };
951
+ protected interfaces: Array<{
952
+ id: ts.Identifier;
953
+ kind: IOKind;
954
+ }>;
955
+ protected methodType: ts.TypeAliasDeclaration;
956
+ protected someOfType: ts.TypeAliasDeclaration;
957
+ protected requestType: ts.TypeAliasDeclaration;
958
+ protected constructor(serverUrl: string);
959
+ /** @example SomeOf<_> */
960
+ protected someOf: ({ name }: ts.TypeAliasDeclaration) => ts.TypeReferenceNode;
961
+ protected makePathType: () => ts.TypeAliasDeclaration;
962
+ protected makePublicInterfaces: () => ts.InterfaceDeclaration[];
963
+ protected makeEndpointTags: () => ts.VariableStatement;
964
+ protected makeImplementationType: () => ts.TypeAliasDeclaration;
965
+ protected makeParseRequestFn: () => ts.VariableStatement;
966
+ protected makeSubstituteFn: () => ts.VariableStatement;
967
+ private makeProvider;
968
+ protected makeClientClass: () => ts.ClassDeclaration;
969
+ protected makeExampleImplementation: () => ts.VariableStatement;
970
+ protected makeUsageStatements: () => (ts.VariableStatement | ts.ExpressionStatement)[];
971
+ }
972
+
902
973
  interface ZTSContext extends FlatObject {
903
974
  isResponse: boolean;
904
- makeAlias: (schema: z.ZodTypeAny, produce: () => ts.TypeNode) => ts.TypeReferenceNode;
975
+ makeAlias: (schema: z.ZodTypeAny, produce: () => ts.TypeNode) => ts.TypeNode;
905
976
  optionalPropStyle: {
906
977
  withQuestionMark?: boolean;
907
978
  withUndefined?: boolean;
@@ -909,7 +980,6 @@ interface ZTSContext extends FlatObject {
909
980
  }
910
981
  type Producer = SchemaHandler<ts.TypeNode, ZTSContext>;
911
982
 
912
- type IOKind = "input" | "response" | ResponseVariant | "encoded";
913
983
  interface IntegrationParams {
914
984
  routing: Routing;
915
985
  /**
@@ -962,54 +1032,11 @@ interface FormattedPrintingOptions {
962
1032
  * */
963
1033
  format?: (program: string) => Promise<string>;
964
1034
  }
965
- declare class Integration {
966
- protected someOf: ts.TypeAliasDeclaration;
1035
+ declare class Integration extends IntegrationBase {
967
1036
  protected program: ts.Node[];
968
1037
  protected usage: Array<ts.Node | string>;
969
- protected registry: Map<string, Record<IOKind, ts.TypeNode> & {
970
- tags: ReadonlyArray<string>;
971
- }>;
972
- protected paths: Set<string>;
973
1038
  protected aliases: Map<z.ZodTypeAny, ts.TypeAliasDeclaration>;
974
- protected ids: {
975
- pathType: ts.Identifier;
976
- methodType: ts.Identifier;
977
- requestType: ts.Identifier;
978
- inputInterface: ts.Identifier;
979
- posResponseInterface: ts.Identifier;
980
- negResponseInterface: ts.Identifier;
981
- encResponseInterface: ts.Identifier;
982
- responseInterface: ts.Identifier;
983
- endpointTagsConst: ts.Identifier;
984
- implementationType: ts.Identifier;
985
- clientClass: ts.Identifier;
986
- keyParameter: ts.Identifier;
987
- pathParameter: ts.Identifier;
988
- paramsArgument: ts.Identifier;
989
- methodParameter: ts.Identifier;
990
- requestParameter: ts.Identifier;
991
- accumulator: ts.Identifier;
992
- provideMethod: ts.Identifier;
993
- implementationArgument: ts.Identifier;
994
- headersProperty: ts.Identifier;
995
- hasBodyConst: ts.Identifier;
996
- undefinedValue: ts.Identifier;
997
- bodyProperty: ts.Identifier;
998
- responseConst: ts.Identifier;
999
- searchParamsConst: ts.Identifier;
1000
- exampleImplementationConst: ts.Identifier;
1001
- clientConst: ts.Identifier;
1002
- contentTypeConst: ts.Identifier;
1003
- isJsonConst: ts.Identifier;
1004
- };
1005
- protected interfaces: Array<{
1006
- id: ts.Identifier;
1007
- kind: IOKind;
1008
- props: ts.PropertySignature[];
1009
- }>;
1010
- protected makeAlias(schema: z.ZodTypeAny, produce: () => ts.TypeNode): ts.TypeReferenceNode;
1011
- /** @example SomeOf<_>*/
1012
- protected makeSomeOf: ({ name }: ts.TypeAliasDeclaration) => ts.TypeReferenceNode;
1039
+ protected makeAlias(schema: z.ZodTypeAny, produce: () => ts.TypeNode): ts.TypeNode;
1013
1040
  constructor({ routing, brandHandling, variant, serverUrl, optionalPropStyle, noContent, }: IntegrationParams);
1014
1041
  protected printUsage(printerOptions?: ts.PrinterOptions): string | undefined;
1015
1042
  print(printerOptions?: ts.PrinterOptions): string;
@@ -1023,12 +1050,8 @@ interface Emitter<E extends EventsMap> extends FlatObject {
1023
1050
  /** @desc Sends an event to the stream accordin to the declared schema */
1024
1051
  emit: <K extends keyof E>(event: K, data: z.input<E[K]>) => void;
1025
1052
  }
1026
- /** @desc This feature is in active development and can be changed or removed regardlress of SemVer */
1027
- declare class EventStreamFactory<E extends EventsMap, TAG extends string> extends EndpointsFactory<EmptySchema, Emitter<E>, string, TAG> {
1028
- constructor({ events, config }: {
1029
- events: E;
1030
- config?: CommonConfig<TAG>;
1031
- });
1053
+ declare class EventStreamFactory<E extends EventsMap> extends EndpointsFactory<EmptySchema, Emitter<E>> {
1054
+ constructor(events: E);
1032
1055
  }
1033
1056
 
1034
- export { type ApiResponse, type AppConfig, type BasicSecurity, type BearerSecurity, BuiltinLogger, type CommonConfig, type CookieSecurity, type CustomHeaderSecurity, DependsOnMethod, type Depicter, Documentation, DocumentationError, EndpointsFactory, EventStreamFactory, type FlatObject, type IOSchema, type InputSecurity, InputValidationError, Integration, type LoggerOverrides, type Method, Middleware, MissingPeerError, type NormalizedResponse, type OAuth2Security, type OpenIdSecurity, OutputValidationError, type Producer, ResultHandler, type Routing, RoutingError, ServeStatic, type ServerConfig, arrayEndpointsFactory, arrayResultHandler, attachRouting, createConfig, createServer, defaultEndpointsFactory, defaultResultHandler, ensureHttpError, ez, getExamples, getMessageFromError, testEndpoint, testMiddleware };
1057
+ export { type ApiResponse, type AppConfig, type BasicSecurity, type BearerSecurity, BuiltinLogger, type CommonConfig, type CookieSecurity, type CustomHeaderSecurity, DependsOnMethod, type Depicter, Documentation, DocumentationError, EndpointsFactory, EventStreamFactory, type FlatObject, type IOSchema, type InputSecurity, InputValidationError, Integration, type LoggerOverrides, type Method, Middleware, MissingPeerError, type NormalizedResponse, type OAuth2Security, type OpenIdSecurity, OutputValidationError, type Producer, ResultHandler, type Routing, RoutingError, ServeStatic, type ServerConfig, type TagOverrides, arrayEndpointsFactory, arrayResultHandler, attachRouting, createConfig, createServer, defaultEndpointsFactory, defaultResultHandler, ensureHttpError, ez, getExamples, getMessageFromError, testEndpoint, testMiddleware };