Repository: RobinTail/express-zod-api
Pull request #208 (2021-11-27 18:19:18)

Breaking: Using config within OpenAPI generator
Starting version 2.8.0 `inputSources` can be configured.
This should be taken into account in OpenAPI generator.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d828a1c..28ff4911 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,19 @@
 # Changelog
 
+## Version 4
+
+### v4.0.0
+
+- The deprecated parameter `type` of `EndpointsFactory::build({...})` has been removed.
+- The OpenAPI generator now requires `config` parameter to be supplied in `new OpenAPI({...})`.
+- The OpenAPI generator takes into account possibly customized `inputSources` from `config`.
+
 ## Version 3
 
 ### v3.2.0
 
 - Feature #204. Detecting usage of `z.upload()` within Endpoint's input schema automatically.
-  - There is no longer need to specify `type: "upload"` for `endpointsFactory.build({...})`.
+  - There is no longer need to specify `type: "upload"` for `EndpointsFactory::build({...})`.
   - In case you are using `z.upload()` in endpoint's input schema, inputs will be parsed by the
     `multipart/form-data` parser.
   - The optional parameter `type?: "json" | "upload"` of `build({...})` is deprecated.
diff --git a/README.md b/README.md
index e934e154..a68d1dbc 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,7 @@ Start your API server with I/O schema validation and custom middlewares in minut
 6. [Your input to my output](#your-input-to-my-output)
 
 You can find the release notes in [Changelog](CHANGELOG.md). Along with recommendations for migrating from
-[from v2](CHANGELOG.md#v300-beta1) and [from v1](CHANGELOG.md#v200-beta1).
+[v3](CHANGELOG.md#v400), [v2](CHANGELOG.md#v300-beta1) and [v1](CHANGELOG.md#v200-beta1).
 
 # Why and what is it for
 
@@ -585,7 +585,8 @@ You can generate the specification of your API and write it to a `.yaml` file, t
 import { OpenAPI } from "express-zod-api";
 
 const yamlString = new OpenAPI({
-  routing,
+  routing, // the same routing and config that you use to start the server
+  config,
   version: "1.2.3",
   title: "Example API",
   serverUrl: "https://example.com",
diff --git a/example/config.ts b/example/config.ts
new file mode 100644
index 00000000..0db87ebf
--- /dev/null
+++ b/example/config.ts
@@ -0,0 +1,13 @@
+import { createConfig } from "../src";
+
+export const config = createConfig({
+  server: {
+    listen: 8090,
+    upload: true,
+  },
+  cors: true,
+  logger: {
+    level: "debug",
+    color: true,
+  },
+});
diff --git a/example/generate-open-api-schema.ts b/example/generate-open-api-schema.ts
index f7ad0b01..bb67e629 100644
--- a/example/generate-open-api-schema.ts
+++ b/example/generate-open-api-schema.ts
@@ -1,10 +1,12 @@
 import { OpenAPI } from "../src";
+import { config } from "./config";
 import { routing } from "./routing";
 import manifest from "../package.json";
 
 console.log(
   new OpenAPI({
     routing,
+    config,
     version: manifest.version,
     title: "Example API",
     serverUrl: "http://example.com",
diff --git a/example/index.ts b/example/index.ts
index efbadd88..766111b7 100644
--- a/example/index.ts
+++ b/example/index.ts
@@ -1,16 +1,5 @@
-import { createConfig, createServer } from "../src";
+import { createServer } from "../src";
+import { config } from "./config";
 import { routing } from "./routing";
 
-const config = createConfig({
-  server: {
-    listen: 8090,
-    upload: true,
-  },
-  cors: true,
-  logger: {
-    level: "debug",
-    color: true,
-  },
-});
-
 createServer(config, routing);
diff --git a/src/common-helpers.ts b/src/common-helpers.ts
index a3b54ae2..b5b106b0 100644
--- a/src/common-helpers.ts
+++ b/src/common-helpers.ts
@@ -119,7 +119,7 @@ function areFilesAvailable(request: Request) {
   return "files" in request && isMultipart;
 }
 
-const defaultInputSources: InputSources = {
+export const defaultInputSources: InputSources = {
   get: ["query", "params"],
   post: ["body", "params", "files"],
   put: ["body", "params"],
diff --git a/src/endpoints-factory.ts b/src/endpoints-factory.ts
index f7f728f0..cfbba249 100644
--- a/src/endpoints-factory.ts
+++ b/src/endpoints-factory.ts
@@ -21,8 +21,6 @@ type BuildProps<
   output: OUT;
   handler: Handler<z.output<Merge<IN, MwIN>>, z.input<OUT>, MwOUT>;
   description?: string;
-  /** @deprecated the factory automatically detects the usage of z.upload() within the input schema */
-  type?: "json" | "upload"; // @todo remove in v4
 } & MethodsDefinition<M>;
 
 export class EndpointsFactory<
@@ -67,7 +65,6 @@ export class EndpointsFactory<
     output,
     handler,
     description,
-    type, // @todo remove in v4
     ...rest
   }: BuildProps<IN, OUT, MwIN, MwOUT, M>) {
     return new Endpoint<IN, OUT, MwIN, MwOUT, M, POS, NEG>({
diff --git a/src/open-api-helpers.ts b/src/open-api-helpers.ts
index 7cd6e062..df3806e7 100644
--- a/src/open-api-helpers.ts
+++ b/src/open-api-helpers.ts
@@ -19,6 +19,7 @@ import {
   IOSchema,
   routePathParamsRegex,
 } from "./common-helpers";
+import { InputSources } from "./config-type";
 import { AbstractEndpoint } from "./endpoint";
 import { OpenAPIError } from "./errors";
 import { ZodFile, ZodFileDef } from "./file-schema";
@@ -28,7 +29,6 @@ import { omit } from "ramda";
 
 type MediaExamples = Pick<MediaTypeObject, "examples">;
 
-// @todo export and test them separately
 type DepictHelper<T extends z.ZodType<any>> = (params: {
   schema: T;
   initial?: SchemaObject;
@@ -50,11 +50,10 @@ interface ReqResDepictHelperCommonProps {
 
 /* eslint-disable @typescript-eslint/no-use-before-define */
 
-export function reformatParamsInPath(path: string): string {
-  return path.replace(routePathParamsRegex, (param) => `{${param.slice(1)}}`);
-}
+export const reformatParamsInPath = (path: string) =>
+  path.replace(routePathParamsRegex, (param) => `{${param.slice(1)}}`);
 
-const depictDefault: DepictHelper<z.ZodDefault<z.ZodTypeAny>> = ({
+export const depictDefault: DepictHelper<z.ZodDefault<z.ZodTypeAny>> = ({
   schema: {
     _def: { innerType, defaultValue },
   },
@@ -66,18 +65,18 @@ const depictDefault: DepictHelper<z.ZodDefault<z.ZodTypeAny>> = ({
   default: defaultValue(),
 });
 
-const depictAny: DepictHelper<z.ZodAny> = ({ initial }) => ({
+export const depictAny: DepictHelper<z.ZodAny> = ({ initial }) => ({
   ...initial,
   format: "any",
 });
 
-const depictUpload: DepictHelper<ZodUpload> = ({ initial }) => ({
+export const depictUpload: DepictHelper<ZodUpload> = ({ initial }) => ({
   ...initial,
   type: "string",
   format: "binary",
 });
 
-const depictFile: DepictHelper<ZodFile> = ({
+export const depictFile: DepictHelper<ZodFile> = ({
   schema: { isBinary, isBase64 },
   initial,
 }) => ({
@@ -86,7 +85,7 @@ const depictFile: DepictHelper<ZodFile> = ({
   format: isBinary ? "binary" : isBase64 ? "byte" : "file",
 });
 
-const depictUnion: DepictHelper<
+export const depictUnion: DepictHelper<
   z.ZodUnion<[z.ZodTypeAny, ...z.ZodTypeAny[]]>
 > = ({
   schema: {
@@ -99,7 +98,7 @@ const depictUnion: DepictHelper<
   oneOf: options.map((option) => depictSchema({ schema: option, isResponse })),
 });
 
-const depictIntersection: DepictHelper<
+export const depictIntersection: DepictHelper<
   z.ZodIntersection<z.ZodTypeAny, z.ZodTypeAny>
 > = ({
   schema: {
@@ -115,14 +114,16 @@ const depictIntersection: DepictHelper<
   ],
 });
 
-const depictOptionalOrNullable: DepictHelper<
+export const depictOptionalOrNullable: DepictHelper<
   z.ZodOptional<any> | z.ZodNullable<any>
 > = ({ schema, initial, isResponse }) => ({
   ...initial,
   ...depictSchema({ schema: schema.unwrap(), isResponse }),
 });
 
-const depictEnum: DepictHelper<z.ZodEnum<any> | z.ZodNativeEnum<any>> = ({
+export const depictEnum: DepictHelper<
+  z.ZodEnum<any> | z.ZodNativeEnum<any>
+> = ({
   schema: {
     _def: { values },
   },
@@ -133,7 +134,7 @@ const depictEnum: DepictHelper<z.ZodEnum<any> | z.ZodNativeEnum<any>> = ({
   enum: Object.values(values),
 });
 
-const depictLiteral: DepictHelper<z.ZodLiteral<any>> = ({
+export const depictLiteral: DepictHelper<z.ZodLiteral<any>> = ({
   schema: {
     _def: { value },
   },
@@ -144,7 +145,7 @@ const depictLiteral: DepictHelper<z.ZodLiteral<any>> = ({
   enum: [value],
 });
 
-const depictObject: DepictHelper<z.AnyZodObject> = ({
+export const depictObject: DepictHelper<z.AnyZodObject> = ({
   schema,
   initial,
   isResponse,
@@ -158,31 +159,31 @@ const depictObject: DepictHelper<z.AnyZodObject> = ({
 });
 
 /** @see https://swagger.io/docs/specification/data-models/data-types/ */
-const depictNull: DepictHelper<z.ZodNull> = ({ initial }) => ({
+export const depictNull: DepictHelper<z.ZodNull> = ({ initial }) => ({
   ...initial,
   type: "string",
   nullable: true,
   format: "null",
 });
 
-const depictDate: DepictHelper<z.ZodDate> = ({ initial }) => ({
+export const depictDate: DepictHelper<z.ZodDate> = ({ initial }) => ({
   ...initial,
   type: "string",
   format: "date",
 });
 
-const depictBoolean: DepictHelper<z.ZodBoolean> = ({ initial }) => ({
+export const depictBoolean: DepictHelper<z.ZodBoolean> = ({ initial }) => ({
   ...initial,
   type: "boolean",
 });
 
-const depictBigInt: DepictHelper<z.ZodBigInt> = ({ initial }) => ({
+export const depictBigInt: DepictHelper<z.ZodBigInt> = ({ initial }) => ({
   ...initial,
   type: "integer",
   format: "bigint",
 });
 
-const depictRecord: DepictHelper<z.ZodRecord<z.ZodTypeAny>> = ({
+export const depictRecord: DepictHelper<z.ZodRecord<z.ZodTypeAny>> = ({
   schema: { _def: def },
   initial,
   isResponse,
@@ -256,7 +257,7 @@ const depictRecord: DepictHelper<z.ZodRecord<z.ZodTypeAny>> = ({
   };
 };
 
-const depictArray: DepictHelper<z.ZodArray<z.ZodTypeAny>> = ({
+export const depictArray: DepictHelper<z.ZodArray<z.ZodTypeAny>> = ({
   schema: { _def: def },
   initial,
   isResponse,
@@ -269,7 +270,7 @@ const depictArray: DepictHelper<z.ZodArray<z.ZodTypeAny>> = ({
 });
 
 /** @todo improve it when OpenAPI 3.1.0 will be released */
-const depictTuple: DepictHelper<z.ZodTuple> = ({
+export const depictTuple: DepictHelper<z.ZodTuple> = ({
   schema: { items },
   initial,
   isResponse,
@@ -294,7 +295,7 @@ const depictTuple: DepictHelper<z.ZodTuple> = ({
   };
 };
 
-const depictString: DepictHelper<z.ZodString> = ({
+export const depictString: DepictHelper<z.ZodString> = ({
   schema: {
     _def: { checks },
   },
@@ -328,7 +329,10 @@ const depictString: DepictHelper<z.ZodString> = ({
   };
 };
 
-const depictNumber: DepictHelper<z.ZodNumber> = ({ schema, initial }) => {
+export const depictNumber: DepictHelper<z.ZodNumber> = ({
+  schema,
+  initial,
+}) => {
   const minCheck = schema._def.checks.find(({ kind }) => kind === "min") as
     | Extract<ArrayElement<z.ZodNumberDef["checks"]>, { kind: "min" }>
     | undefined;
@@ -358,7 +362,7 @@ const depictNumber: DepictHelper<z.ZodNumber> = ({ schema, initial }) => {
   };
 };
 
-const depictObjectProperties = ({
+export const depictObjectProperties = ({
   schema: { shape },
   isResponse,
 }: Parameters<DepictHelper<z.AnyZodObject>>[0]) => {
@@ -371,7 +375,7 @@ const depictObjectProperties = ({
   );
 };
 
-const depictEffect: DepictHelper<z.ZodEffects<z.ZodTypeAny>> = ({
+export const depictEffect: DepictHelper<z.ZodEffects<z.ZodTypeAny>> = ({
   schema,
   initial,
   isResponse,
@@ -420,7 +424,7 @@ const depictEffect: DepictHelper<z.ZodEffects<z.ZodTypeAny>> = ({
   return { ...initial, ...input };
 };
 
-const depictIOExamples = <T extends IOSchema>(
+export const depictIOExamples = <T extends IOSchema>(
   schema: T,
   isResponse: boolean,
   omitProps: string[] = []
@@ -442,7 +446,7 @@ const depictIOExamples = <T extends IOSchema>(
   };
 };
 
-const depictIOParamExamples = <T extends IOSchema>(
+export const depictIOParamExamples = <T extends IOSchema>(
   schema: T,
   isResponse: boolean,
   param: string
@@ -471,18 +475,22 @@ export const depictRequestParams = ({
   path,
   method,
   endpoint,
-}: ReqResDepictHelperCommonProps): ParameterObject[] => {
+  inputSources,
+}: ReqResDepictHelperCommonProps & {
+  inputSources: InputSources[Method];
+}): ParameterObject[] => {
   const schema = endpoint.getInputSchema();
   const shape = extractObjectSchema(schema).shape;
   const pathParams = getRoutePathParams(path);
+  const isQueryEnabled = inputSources.includes("query");
+  const isParamsEnabled = inputSources.includes("params");
+  const isPathParam = (name: string) =>
+    isParamsEnabled && pathParams.includes(name);
   return Object.keys(shape)
-    .filter(
-      // @todo involve config/inputSources in v4
-      (name) => ["get", "delete"].includes(method) || pathParams.includes(name)
-    )
+    .filter((name) => isQueryEnabled || isPathParam(name))
     .map((name) => ({
       name,
-      in: pathParams.includes(name) ? "path" : "query",
+      in: isPathParam(name) ? "path" : "query",
       required: !shape[name].isOptional(),
       schema: {
         description: `${method.toUpperCase()} ${path} parameter`,
@@ -579,8 +587,9 @@ export const excludeParamsFromDepiction = (
   );
 };
 
-const excludeExampleFromDepiction = (depicted: SchemaObject): SchemaObject =>
-  omit(["example"], depicted);
+export const excludeExampleFromDepiction = (
+  depicted: SchemaObject
+): SchemaObject => omit(["example"], depicted);
 
 export const depictResponse = ({
   method,
diff --git a/src/open-api.ts b/src/open-api.ts
index 53f38e48..181f8054 100644
--- a/src/open-api.ts
+++ b/src/open-api.ts
@@ -1,4 +1,6 @@
 import { OpenApiBuilder, OperationObject } from "openapi3-ts";
+import { defaultInputSources } from "./common-helpers";
+import { CommonConfig } from "./config-type";
 import { Method } from "./method";
 import {
   depictRequestParams,
@@ -13,6 +15,7 @@ interface GeneratorParams {
   version: string;
   serverUrl: string;
   routing: Routing;
+  config: CommonConfig;
   successfulResponseDescription?: string;
   errorResponseDescription?: string;
 }
@@ -20,6 +23,7 @@ interface GeneratorParams {
 export class OpenAPI extends OpenApiBuilder {
   public constructor({
     routing,
+    config,
     title,
     version,
     serverUrl,
@@ -31,7 +35,12 @@ export class OpenAPI extends OpenApiBuilder {
     const cb: RoutingCycleParams["cb"] = (endpoint, path, _method) => {
       const method = _method as Method;
       const commonParams = { path, method, endpoint };
-      const depictedParams = depictRequestParams(commonParams);
+      const inputSources =
+        config.inputSources?.[method] || defaultInputSources[method];
+      const depictedParams = depictRequestParams({
+        ...commonParams,
+        inputSources,
+      });
       const operation: OperationObject = {
         responses: {
           "200": depictResponse({
@@ -52,8 +61,7 @@ export class OpenAPI extends OpenApiBuilder {
       if (depictedParams.length > 0) {
         operation.parameters = depictedParams;
       }
-      if (method !== "get") {
-        // @todo involve config/inputSources in v4
+      if (inputSources.includes("body")) {
         operation.requestBody = depictRequest(commonParams);
       }
       const swaggerCompatiblePath = reformatParamsInPath(path);


Test patch:
diff --git a/tests/unit/__snapshots__/common-helpers.spec.ts.snap b/tests/unit/__snapshots__/common-helpers.spec.ts.snap
index 033867ed..8d9dce4b 100644
--- a/tests/unit/__snapshots__/common-helpers.spec.ts.snap
+++ b/tests/unit/__snapshots__/common-helpers.spec.ts.snap
@@ -119,6 +119,33 @@ Object {
 }
 `;
 
+exports[`Common Helpers defaultInputSources should be declared in a certain way 1`] = `
+Object {
+  "delete": Array [
+    "body",
+    "query",
+    "params",
+  ],
+  "get": Array [
+    "query",
+    "params",
+  ],
+  "patch": Array [
+    "body",
+    "params",
+  ],
+  "post": Array [
+    "body",
+    "params",
+    "files",
+  ],
+  "put": Array [
+    "body",
+    "params",
+  ],
+}
+`;
+
 exports[`Common Helpers extractObjectSchema() should pass the object schema through 1`] = `
 Object {
   "_type": "ZodObject",
diff --git a/tests/unit/__snapshots__/open-api-helpers.spec.ts.snap b/tests/unit/__snapshots__/open-api-helpers.spec.ts.snap
index 6d53b618..35ef3075 100644
--- a/tests/unit/__snapshots__/open-api-helpers.spec.ts.snap
+++ b/tests/unit/__snapshots__/open-api-helpers.spec.ts.snap
@@ -1,5 +1,495 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`Open API helpers depictAny() should depict ZodAny 1`] = `
+Object {
+  "description": "test",
+  "format": "any",
+}
+`;
+
+exports[`Open API helpers depictArray() should depict ZodArray 1`] = `
+Object {
+  "description": "test",
+  "items": Object {
+    "type": "boolean",
+  },
+  "type": "array",
+}
+`;
+
+exports[`Open API helpers depictBigInt() should depict ZodBigInt 1`] = `
+Object {
+  "description": "test",
+  "format": "bigint",
+  "type": "integer",
+}
+`;
+
+exports[`Open API helpers depictBoolean() should depict ZodBoolean 1`] = `
+Object {
+  "description": "test",
+  "type": "boolean",
+}
+`;
+
+exports[`Open API helpers depictDate() should depict ZodDate 1`] = `
+Object {
+  "description": "test",
+  "format": "date",
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictDefault() should depict ZodDefault 1`] = `
+Object {
+  "default": true,
+  "description": "test",
+  "type": "boolean",
+}
+`;
+
+exports[`Open API helpers depictEffect() should depict ZodEffects preprocess in case of request 1`] = `
+Object {
+  "format": "string (preprocessed)",
+}
+`;
+
+exports[`Open API helpers depictEffect() should depict ZodEffects transformation in case of request 1`] = `
+Object {
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictEffect() should depict ZodEffects transformation in case of response 1`] = `
+Object {
+  "type": "number",
+}
+`;
+
+exports[`Open API helpers depictEnum() should depict ZodEnum 1`] = `
+Object {
+  "description": "test",
+  "enum": Array [
+    "one",
+    "two",
+  ],
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictEnum() should depict ZodNativeEnum 1`] = `
+Object {
+  "description": "test",
+  "enum": Array [
+    "ONE",
+    "TWO",
+  ],
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictFile() should depict ZodFile 1`] = `
+Object {
+  "description": "test",
+  "format": "binary",
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictIOExamples() should depict examples in case of request 1`] = `
+Object {
+  "examples": Object {
+    "example1": Object {
+      "value": Object {
+        "one": "test",
+        "two": 123,
+      },
+    },
+    "example2": Object {
+      "value": Object {
+        "one": "test2",
+        "two": 456,
+      },
+    },
+  },
+}
+`;
+
+exports[`Open API helpers depictIOExamples() should depict examples in case of response 1`] = `
+Object {
+  "examples": Object {
+    "example1": Object {
+      "value": Object {
+        "one": 4,
+        "two": "123",
+      },
+    },
+    "example2": Object {
+      "value": Object {
+        "one": 5,
+        "two": "456",
+      },
+    },
+  },
+}
+`;
+
+exports[`Open API helpers depictIOParamExamples() should depict examples in case of request 1`] = `
+Object {
+  "examples": Object {
+    "example1": Object {
+      "value": 123,
+    },
+    "example2": Object {
+      "value": 456,
+    },
+  },
+}
+`;
+
+exports[`Open API helpers depictIOParamExamples() should depict examples in case of response 1`] = `
+Object {
+  "examples": Object {
+    "example1": Object {
+      "value": "123",
+    },
+    "example2": Object {
+      "value": "456",
+    },
+  },
+}
+`;
+
+exports[`Open API helpers depictIntersection() should depict ZodIntersection 1`] = `
+Object {
+  "allOf": Array [
+    Object {
+      "properties": Object {
+        "one": Object {
+          "exclusiveMaximum": false,
+          "exclusiveMinimum": false,
+          "format": "double",
+          "maximum": 1.7976931348623157e+308,
+          "minimum": 5e-324,
+          "type": "number",
+        },
+      },
+      "required": Array [
+        "one",
+      ],
+      "type": "object",
+    },
+    Object {
+      "properties": Object {
+        "two": Object {
+          "exclusiveMaximum": false,
+          "exclusiveMinimum": false,
+          "format": "double",
+          "maximum": 1.7976931348623157e+308,
+          "minimum": 5e-324,
+          "type": "number",
+        },
+      },
+      "required": Array [
+        "two",
+      ],
+      "type": "object",
+    },
+  ],
+  "description": "test",
+}
+`;
+
+exports[`Open API helpers depictLiteral() should depict ZodLiteral 1`] = `
+Object {
+  "description": "test",
+  "enum": Array [
+    "testing",
+  ],
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictNull() should depict ZodNull 1`] = `
+Object {
+  "description": "test",
+  "format": "null",
+  "nullable": true,
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictNumber() should depict ZodNumber with refinements 1`] = `
+Object {
+  "description": "test",
+  "exclusiveMaximum": false,
+  "exclusiveMinimum": false,
+  "format": "int64",
+  "maximum": 20,
+  "minimum": 10,
+  "type": "integer",
+}
+`;
+
+exports[`Open API helpers depictNumber() should depict regular ZodNumber 1`] = `
+Object {
+  "description": "test",
+  "exclusiveMaximum": false,
+  "exclusiveMinimum": false,
+  "format": "double",
+  "maximum": 1.7976931348623157e+308,
+  "minimum": 5e-324,
+  "type": "number",
+}
+`;
+
+exports[`Open API helpers depictObject() should depict ZodObject 1`] = `
+Object {
+  "description": "test",
+  "properties": Object {
+    "one": Object {
+      "exclusiveMaximum": false,
+      "exclusiveMinimum": false,
+      "format": "double",
+      "maximum": 1.7976931348623157e+308,
+      "minimum": 5e-324,
+      "type": "number",
+    },
+    "two": Object {
+      "type": "string",
+    },
+  },
+  "required": Array [
+    "one",
+    "two",
+  ],
+  "type": "object",
+}
+`;
+
+exports[`Open API helpers depictObjectProperties() should depict ZodObject shape 1`] = `
+Object {
+  "one": Object {
+    "type": "string",
+  },
+  "two": Object {
+    "type": "boolean",
+  },
+}
+`;
+
+exports[`Open API helpers depictOptionalOrNullable() should depict ZodNullable 1`] = `
+Object {
+  "description": "test",
+  "nullable": true,
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictOptionalOrNullable() should depict ZodOptional 1`] = `
+Object {
+  "description": "test",
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictRecord() should depict ZodRecord with key schema enum 1`] = `
+Object {
+  "description": "test",
+  "properties": Object {
+    "one": Object {
+      "type": "boolean",
+    },
+    "two": Object {
+      "type": "boolean",
+    },
+  },
+  "required": Array [
+    "one",
+    "two",
+  ],
+  "type": "object",
+}
+`;
+
+exports[`Open API helpers depictRecord() should depict ZodRecord with key schema literal 1`] = `
+Object {
+  "description": "test",
+  "properties": Object {
+    "testing": Object {
+      "type": "boolean",
+    },
+  },
+  "required": Array [
+    "testing",
+  ],
+  "type": "object",
+}
+`;
+
+exports[`Open API helpers depictRecord() should depict ZodRecord with key schema string 1`] = `
+Object {
+  "additionalProperties": Object {
+    "type": "boolean",
+  },
+  "description": "test",
+  "type": "object",
+}
+`;
+
+exports[`Open API helpers depictRecord() should depict ZodRecord with key schema union of literals 1`] = `
+Object {
+  "description": "test",
+  "properties": Object {
+    "one": Object {
+      "type": "boolean",
+    },
+    "two": Object {
+      "type": "boolean",
+    },
+  },
+  "required": Array [
+    "one",
+    "two",
+  ],
+  "type": "object",
+}
+`;
+
+exports[`Open API helpers depictRecord() should depict classic ZodRecord 1`] = `
+Object {
+  "additionalProperties": Object {
+    "type": "boolean",
+  },
+  "description": "test",
+  "type": "object",
+}
+`;
+
+exports[`Open API helpers depictRequestParams() should depict none if both query and params are disabled 1`] = `Array []`;
+
+exports[`Open API helpers depictRequestParams() should depict only path params if query is disabled 1`] = `
+Array [
+  Object {
+    "in": "path",
+    "name": "id",
+    "required": true,
+    "schema": Object {
+      "description": "GET /v1/user/:id parameter",
+      "type": "string",
+    },
+  },
+]
+`;
+
+exports[`Open API helpers depictRequestParams() should depict query and path params 1`] = `
+Array [
+  Object {
+    "in": "path",
+    "name": "id",
+    "required": true,
+    "schema": Object {
+      "description": "GET /v1/user/:id parameter",
+      "type": "string",
+    },
+  },
+  Object {
+    "in": "query",
+    "name": "test",
+    "required": true,
+    "schema": Object {
+      "description": "GET /v1/user/:id parameter",
+      "type": "boolean",
+    },
+  },
+]
+`;
+
+exports[`Open API helpers depictString() should depict ZodString with refinements 1`] = `
+Object {
+  "description": "test",
+  "format": "email",
+  "maxLength": 20,
+  "minLength": 10,
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictString() should depict ZodString with regex 1`] = `
+Object {
+  "description": "test",
+  "pattern": "/^\\\\d+.\\\\d+.\\\\d+$/",
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictString() should depict regular ZodString 1`] = `
+Object {
+  "description": "test",
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers depictTuple() should depict ZodTuple 1`] = `
+Object {
+  "description": "test",
+  "items": Object {
+    "description": "0: boolean, 1: string, 2: string",
+    "format": "tuple",
+    "oneOf": Array [
+      Object {
+        "type": "boolean",
+      },
+      Object {
+        "type": "string",
+      },
+      Object {
+        "enum": Array [
+          "test",
+        ],
+        "type": "string",
+      },
+    ],
+  },
+  "maxItems": 3,
+  "minItems": 3,
+  "type": "array",
+}
+`;
+
+exports[`Open API helpers depictUnion() should depict ZodUnion 1`] = `
+Object {
+  "description": "test",
+  "oneOf": Array [
+    Object {
+      "type": "string",
+    },
+    Object {
+      "exclusiveMaximum": false,
+      "exclusiveMinimum": false,
+      "format": "double",
+      "maximum": 1.7976931348623157e+308,
+      "minimum": 5e-324,
+      "type": "number",
+    },
+  ],
+}
+`;
+
+exports[`Open API helpers depictUpload() should depict ZodUpload 1`] = `
+Object {
+  "description": "test",
+  "format": "binary",
+  "type": "string",
+}
+`;
+
+exports[`Open API helpers excludeExampleFromDepiction() should remove example property of supplied object 1`] = `
+Object {
+  "test": "some",
+}
+`;
+
 exports[`Open API helpers excludeParamsFromDepiction() should handle intersection 1`] = `
 Object {
   "allOf": Array [
diff --git a/tests/unit/common-helpers.spec.ts b/tests/unit/common-helpers.spec.ts
index ea12f5cb..3cd8e2aa 100644
--- a/tests/unit/common-helpers.spec.ts
+++ b/tests/unit/common-helpers.spec.ts
@@ -3,6 +3,7 @@ import { expectType } from "tsd";
 import {
   combinations,
   combineEndpointAndMiddlewareInputSchemas,
+  defaultInputSources,
   extractObjectSchema,
   getExamples,
   getInitialInput,
@@ -245,6 +246,12 @@ describe("Common Helpers", () => {
     });
   });
 
+  describe("defaultInputSources", () => {
+    test("should be declared in a certain way", () => {
+      expect(defaultInputSources).toMatchSnapshot();
+    });
+  });
+
   describe("getInitialInput()", () => {
     test("should return body for POST, PUT and PATCH requests by default", () => {
       expect(
diff --git a/tests/unit/open-api-helpers.spec.ts b/tests/unit/open-api-helpers.spec.ts
index 855f8fb4..39a57276 100644
--- a/tests/unit/open-api-helpers.spec.ts
+++ b/tests/unit/open-api-helpers.spec.ts
@@ -1,6 +1,31 @@
-import { z } from "../../src/index";
+import { defaultEndpointsFactory, withMeta, z } from "../../src/index";
 import {
+  depictAny,
+  depictArray,
+  depictBigInt,
+  depictBoolean,
+  depictDate,
+  depictDefault,
+  depictEffect,
+  depictEnum,
+  depictFile,
+  depictIntersection,
+  depictIOExamples,
+  depictIOParamExamples,
+  depictLiteral,
+  depictNull,
+  depictNumber,
+  depictObject,
+  depictObjectProperties,
+  depictOptionalOrNullable,
+  depictRecord,
+  depictRequestParams,
   depictSchema,
+  depictString,
+  depictTuple,
+  depictUnion,
+  depictUpload,
+  excludeExampleFromDepiction,
   excludeParamsFromDepiction,
   reformatParamsInPath,
 } from "../../src/open-api-helpers";
@@ -63,4 +88,554 @@ describe("Open API helpers", () => {
       );
     });
   });
+
+  describe("depictDefault()", () => {
+    test("should depict ZodDefault", () => {
+      expect(
+        depictDefault({
+          schema: z.boolean().default(true),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictAny()", () => {
+    test("should depict ZodAny", () => {
+      expect(
+        depictAny({
+          schema: z.any(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictUpload()", () => {
+    test("should depict ZodUpload", () => {
+      expect(
+        depictUpload({
+          schema: z.upload(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictFile()", () => {
+    test("should depict ZodFile", () => {
+      expect(
+        depictFile({
+          schema: z.file().binary(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictUnion()", () => {
+    test("should depict ZodUnion", () => {
+      expect(
+        depictUnion({
+          schema: z.string().or(z.number()),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictIntersection()", () => {
+    test("should depict ZodIntersection", () => {
+      expect(
+        depictIntersection({
+          schema: z
+            .object({ one: z.number() })
+            .and(z.object({ two: z.number() })),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictOptionalOrNullable()", () => {
+    test("should depict ZodOptional", () => {
+      expect(
+        depictOptionalOrNullable({
+          schema: z.string().optional(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodNullable", () => {
+      expect(
+        depictOptionalOrNullable({
+          schema: z.string().nullable(),
+          isResponse: false,
+          initial: { description: "test", nullable: true },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictEnum()", () => {
+    test("should depict ZodEnum", () => {
+      expect(
+        depictEnum({
+          schema: z.enum(["one", "two"]),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodNativeEnum", () => {
+      enum Test {
+        one = "ONE",
+        two = "TWO",
+      }
+
+      expect(
+        depictEnum({
+          schema: z.nativeEnum(Test),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictLiteral()", () => {
+    test("should depict ZodLiteral", () => {
+      expect(
+        depictLiteral({
+          schema: z.literal("testing"),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictObject()", () => {
+    test("should depict ZodObject", () => {
+      expect(
+        depictObject({
+          schema: z.object({
+            one: z.number(),
+            two: z.string(),
+          }),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictNull()", () => {
+    test("should depict ZodNull", () => {
+      expect(
+        depictNull({
+          schema: z.null(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictDate()", () => {
+    test("should depict ZodDate", () => {
+      expect(
+        depictDate({
+          schema: z.date(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictBoolean()", () => {
+    test("should depict ZodBoolean", () => {
+      expect(
+        depictBoolean({
+          schema: z.boolean(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictBigInt()", () => {
+    test("should depict ZodBigInt", () => {
+      expect(
+        depictBigInt({
+          schema: z.bigint(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictRecord()", () => {
+    test("should depict classic ZodRecord", () => {
+      expect(
+        depictRecord({
+          schema: z.record(z.boolean()),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodRecord with key schema string", () => {
+      expect(
+        depictRecord({
+          schema: z.record(z.string(), z.boolean()),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodRecord with key schema enum", () => {
+      expect(
+        depictRecord({
+          schema: z.record(z.enum(["one", "two"]), z.boolean()),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodRecord with key schema literal", () => {
+      expect(
+        depictRecord({
+          schema: z.record(z.literal("testing"), z.boolean()),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodRecord with key schema union of literals", () => {
+      expect(
+        depictRecord({
+          schema: z.record(z.literal("one").or(z.literal("two")), z.boolean()),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictArray()", () => {
+    test("should depict ZodArray", () => {
+      expect(
+        depictArray({
+          schema: z.array(z.boolean()),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictTuple()", () => {
+    test("should depict ZodTuple", () => {
+      expect(
+        depictTuple({
+          schema: z.tuple([z.boolean(), z.string(), z.literal("test")]),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictString()", () => {
+    test("should depict regular ZodString", () => {
+      expect(
+        depictString({
+          schema: z.string(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodString with refinements", () => {
+      expect(
+        depictString({
+          schema: z.string().email().min(10).max(20),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodString with regex", () => {
+      expect(
+        depictString({
+          schema: z.string().regex(/^\d+.\d+.\d+$/),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictNumber()", () => {
+    test("should depict regular ZodNumber", () => {
+      expect(
+        depictNumber({
+          schema: z.number(),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodNumber with refinements", () => {
+      expect(
+        depictNumber({
+          schema: z.number().int().min(10).max(20),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictObjectProperties()", () => {
+    test("should depict ZodObject shape", () => {
+      expect(
+        depictObjectProperties({
+          schema: z.object({
+            one: z.string(),
+            two: z.boolean(),
+          }),
+          isResponse: false,
+          initial: { description: "test" },
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictEffect()", () => {
+    test("should depict ZodEffects transformation in case of response", () => {
+      expect(
+        depictEffect({
+          schema: z.string().transform((v) => parseInt(v, 10)),
+          isResponse: true,
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodEffects transformation in case of request", () => {
+      expect(
+        depictEffect({
+          schema: z.string().transform((v) => parseInt(v, 10)),
+          isResponse: false,
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict ZodEffects preprocess in case of request", () => {
+      expect(
+        depictEffect({
+          schema: z.preprocess((v) => parseInt(`${v}`, 10), z.string()),
+          isResponse: false,
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictIOExamples()", () => {
+    test("should depict examples in case of request", () => {
+      expect(
+        depictIOExamples(
+          withMeta(
+            z.object({
+              one: z.string().transform((v) => v.length),
+              two: z.number().transform((v) => `${v}`),
+              three: z.boolean(),
+            })
+          )
+            .example({
+              one: "test",
+              two: 123,
+              three: true,
+            })
+            .example({
+              one: "test2",
+              two: 456,
+              three: false,
+            }),
+          false,
+          ["three"]
+        )
+      ).toMatchSnapshot();
+    });
+
+    test("should depict examples in case of response", () => {
+      expect(
+        depictIOExamples(
+          withMeta(
+            z.object({
+              one: z.string().transform((v) => v.length),
+              two: z.number().transform((v) => `${v}`),
+              three: z.boolean(),
+            })
+          )
+            .example({
+              one: "test",
+              two: 123,
+              three: true,
+            })
+            .example({
+              one: "test2",
+              two: 456,
+              three: false,
+            }),
+          true,
+          ["three"]
+        )
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictIOParamExamples()", () => {
+    test("should depict examples in case of request", () => {
+      expect(
+        depictIOParamExamples(
+          withMeta(
+            z.object({
+              one: z.string().transform((v) => v.length),
+              two: z.number().transform((v) => `${v}`),
+              three: z.boolean(),
+            })
+          )
+            .example({
+              one: "test",
+              two: 123,
+              three: true,
+            })
+            .example({
+              one: "test2",
+              two: 456,
+              three: false,
+            }),
+          false,
+          "two"
+        )
+      ).toMatchSnapshot();
+    });
+
+    test("should depict examples in case of response", () => {
+      expect(
+        depictIOParamExamples(
+          withMeta(
+            z.object({
+              one: z.string().transform((v) => v.length),
+              two: z.number().transform((v) => `${v}`),
+              three: z.boolean(),
+            })
+          )
+            .example({
+              one: "test",
+              two: 123,
+              three: true,
+            })
+            .example({
+              one: "test2",
+              two: 456,
+              three: false,
+            }),
+          true,
+          "two"
+        )
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("depictRequestParams()", () => {
+    test("should depict query and path params", () => {
+      expect(
+        depictRequestParams({
+          path: "/v1/user/:id",
+          method: "get",
+          endpoint: defaultEndpointsFactory.build({
+            methods: ["get", "put", "delete"],
+            input: z.object({
+              id: z.string(),
+              test: z.boolean(),
+            }),
+            output: z.object({}),
+            handler: jest.fn(),
+          }),
+          inputSources: ["query", "params"],
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict only path params if query is disabled", () => {
+      expect(
+        depictRequestParams({
+          path: "/v1/user/:id",
+          method: "get",
+          endpoint: defaultEndpointsFactory.build({
+            methods: ["get", "put", "delete"],
+            input: z.object({
+              id: z.string(),
+              test: z.boolean(),
+            }),
+            output: z.object({}),
+            handler: jest.fn(),
+          }),
+          inputSources: ["body", "params"],
+        })
+      ).toMatchSnapshot();
+    });
+
+    test("should depict none if both query and params are disabled", () => {
+      expect(
+        depictRequestParams({
+          path: "/v1/user/:id",
+          method: "get",
+          endpoint: defaultEndpointsFactory.build({
+            methods: ["get", "put", "delete"],
+            input: z.object({
+              id: z.string(),
+              test: z.boolean(),
+            }),
+            output: z.object({}),
+            handler: jest.fn(),
+          }),
+          inputSources: ["body"],
+        })
+      ).toMatchSnapshot();
+    });
+  });
+
+  describe("excludeExampleFromDepiction()", () => {
+    test("should remove example property of supplied object", () => {
+      expect(
+        excludeExampleFromDepiction({
+          test: "some",
+          example: "test",
+        })
+      ).toMatchSnapshot();
+    });
+  });
 });
diff --git a/tests/unit/open-api.spec.ts b/tests/unit/open-api.spec.ts
index dc8dd2a1..75dd4257 100644
--- a/tests/unit/open-api.spec.ts
+++ b/tests/unit/open-api.spec.ts
@@ -1,12 +1,27 @@
 import { routing } from "../../example/routing";
-import { z, OpenAPI, defaultEndpointsFactory, withMeta } from "../../src";
+import {
+  z,
+  OpenAPI,
+  defaultEndpointsFactory,
+  withMeta,
+  createConfig,
+} from "../../src";
 import { expectType } from "tsd";
 
 describe("Open API generator", () => {
+  const config = createConfig({
+    cors: true,
+    logger: { level: "debug", color: true },
+    server: {
+      listen: 8090,
+    },
+  });
+
   describe("generateOpenApi()", () => {
     test("should generate the correct schema of example routing", () => {
       const spec = new OpenAPI({
         routing,
+        config,
         version: "1.2.3",
         title: "Example API",
         serverUrl: "http://example.com",
@@ -17,6 +32,7 @@ describe("Open API generator", () => {
     test("should generate the correct schema for complex types", () => {
       const literalValue = "something" as const;
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -46,6 +62,7 @@ describe("Open API generator", () => {
 
     test("should generate the correct schema for nullable and optional types", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -74,6 +91,7 @@ describe("Open API generator", () => {
 
     test("should generate the correct schema for intersection type", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -117,6 +135,7 @@ describe("Open API generator", () => {
 
     test("should generate the correct schema for union type", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -151,6 +170,7 @@ describe("Open API generator", () => {
 
     test("should handle transformation schema in output", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -177,6 +197,7 @@ describe("Open API generator", () => {
 
     test("should handle bigint, boolean, date and null", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -204,6 +225,7 @@ describe("Open API generator", () => {
 
     test("should handle record", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -233,6 +255,7 @@ describe("Open API generator", () => {
 
     test("should handle type any", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -256,6 +279,7 @@ describe("Open API generator", () => {
 
     test("should handle different number types", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -287,6 +311,7 @@ describe("Open API generator", () => {
 
     test("should handle different string types", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -324,6 +349,7 @@ describe("Open API generator", () => {
 
     test("should handle tuples", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -353,6 +379,7 @@ describe("Open API generator", () => {
 
     test("should handle enum types", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -384,6 +411,7 @@ describe("Open API generator", () => {
       );
       const boolean = z.preprocess((arg) => !!arg, z.boolean());
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -422,6 +450,7 @@ describe("Open API generator", () => {
         expect(
           () =>
             new OpenAPI({
+              config,
               routing: {
                 v1: {
                   getSomething: defaultEndpointsFactory.build({
@@ -449,6 +478,7 @@ describe("Open API generator", () => {
       // It existed though in Zod v3.6.x:
       // @see https://github.com/colinhacks/zod/blob/v3.6.1/src/types.ts#L1204
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -483,6 +513,7 @@ describe("Open API generator", () => {
       expectType<TestingType>({ id: "string", field2: "string" });
 
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -515,6 +546,7 @@ describe("Open API generator", () => {
   describe("Route Path Params", () => {
     test("should handle route path params for POST request", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             ":name": defaultEndpointsFactory.build({
@@ -537,6 +569,7 @@ describe("Open API generator", () => {
 
     test("should handle route path params for GET request", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             ":name": defaultEndpointsFactory.build({
@@ -561,6 +594,7 @@ describe("Open API generator", () => {
   describe("Metadata", () => {
     test("should pass over the schema description", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -588,6 +622,7 @@ describe("Open API generator", () => {
 
     test("should pass over the example of an individual parameter", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -615,6 +650,7 @@ describe("Open API generator", () => {
 
     test("should pass over examples of each param from the whole IO schema examples (GET)", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -646,6 +682,7 @@ describe("Open API generator", () => {
 
     test("should pass over examples of the whole IO schema (POST)", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory.build({
@@ -677,6 +714,7 @@ describe("Open API generator", () => {
 
     test("should merge endpoint handler examples with its middleware examples", () => {
       const spec = new OpenAPI({
+        config,
         routing: {
           v1: {
             getSomething: defaultEndpointsFactory