@orpc/openapi 1.14.5 → 2.0.0-beta.1

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.
Files changed (48) hide show
  1. package/README.md +75 -109
  2. package/dist/adapters/fetch/index.d.mts +20 -16
  3. package/dist/adapters/fetch/index.d.ts +20 -16
  4. package/dist/adapters/fetch/index.mjs +24 -8
  5. package/dist/adapters/node/index.d.mts +8 -13
  6. package/dist/adapters/node/index.d.ts +8 -13
  7. package/dist/adapters/node/index.mjs +10 -7
  8. package/dist/adapters/standard/index.d.mts +46 -16
  9. package/dist/adapters/standard/index.d.ts +46 -16
  10. package/dist/adapters/standard/index.mjs +9 -6
  11. package/dist/extensions/route.d.mts +43 -0
  12. package/dist/extensions/route.d.ts +43 -0
  13. package/dist/extensions/route.mjs +14 -0
  14. package/dist/helpers/index.d.mts +51 -0
  15. package/dist/helpers/index.d.ts +51 -0
  16. package/dist/helpers/index.mjs +39 -0
  17. package/dist/index.d.mts +92 -111
  18. package/dist/index.d.ts +92 -111
  19. package/dist/index.mjs +894 -34
  20. package/dist/plugins/index.d.mts +55 -51
  21. package/dist/plugins/index.d.ts +55 -51
  22. package/dist/plugins/index.mjs +147 -142
  23. package/dist/shared/openapi.B2SK0ZAr.mjs +359 -0
  24. package/dist/shared/openapi.B9PQzqBn.mjs +49 -0
  25. package/dist/shared/openapi.BQzzr4-4.d.ts +299 -0
  26. package/dist/shared/openapi.BcEtAxQj.d.mts +299 -0
  27. package/dist/shared/openapi.Bt87OzTt.mjs +131 -0
  28. package/dist/shared/openapi.C7m7NAmH.d.mts +142 -0
  29. package/dist/shared/openapi.C7m7NAmH.d.ts +142 -0
  30. package/dist/shared/openapi.C9Olbxd5.d.ts +75 -0
  31. package/dist/shared/openapi.CYgMBSUF.d.mts +18 -0
  32. package/dist/shared/openapi.CYgMBSUF.d.ts +18 -0
  33. package/dist/shared/openapi.CcyUEuTs.mjs +313 -0
  34. package/dist/shared/openapi.DmAa7YPO.mjs +275 -0
  35. package/dist/shared/openapi.Drd1OtzG.d.mts +75 -0
  36. package/package.json +29 -23
  37. package/dist/adapters/aws-lambda/index.d.mts +0 -20
  38. package/dist/adapters/aws-lambda/index.d.ts +0 -20
  39. package/dist/adapters/aws-lambda/index.mjs +0 -18
  40. package/dist/adapters/fastify/index.d.mts +0 -23
  41. package/dist/adapters/fastify/index.d.ts +0 -23
  42. package/dist/adapters/fastify/index.mjs +0 -18
  43. package/dist/shared/openapi.BB-W-NKv.mjs +0 -204
  44. package/dist/shared/openapi.BGy4N6eR.d.mts +0 -120
  45. package/dist/shared/openapi.BGy4N6eR.d.ts +0 -120
  46. package/dist/shared/openapi.BwdtJjDu.mjs +0 -878
  47. package/dist/shared/openapi.DwaweYRb.d.mts +0 -54
  48. package/dist/shared/openapi.DwaweYRb.d.ts +0 -54
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/openapi",
3
3
  "type": "module",
4
- "version": "1.14.5",
4
+ "version": "2.0.0-beta.1",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.dev",
7
7
  "repository": {
@@ -10,15 +10,24 @@
10
10
  "directory": "packages/openapi"
11
11
  },
12
12
  "keywords": [
13
- "orpc"
13
+ "orpc",
14
+ "openapi"
15
+ ],
16
+ "sideEffects": [
17
+ "./dist/extensions/route.mjs"
14
18
  ],
15
- "sideEffects": false,
16
19
  "exports": {
20
+ "./package.json": "./package.json",
17
21
  ".": {
18
22
  "types": "./dist/index.d.mts",
19
23
  "import": "./dist/index.mjs",
20
24
  "default": "./dist/index.mjs"
21
25
  },
26
+ "./helpers": {
27
+ "types": "./dist/helpers/index.d.mts",
28
+ "import": "./dist/helpers/index.mjs",
29
+ "default": "./dist/helpers/index.mjs"
30
+ },
22
31
  "./plugins": {
23
32
  "types": "./dist/plugins/index.d.mts",
24
33
  "import": "./dist/plugins/index.mjs",
@@ -39,38 +48,35 @@
39
48
  "import": "./dist/adapters/node/index.mjs",
40
49
  "default": "./dist/adapters/node/index.mjs"
41
50
  },
42
- "./fastify": {
43
- "types": "./dist/adapters/fastify/index.d.mts",
44
- "import": "./dist/adapters/fastify/index.mjs",
45
- "default": "./dist/adapters/fastify/index.mjs"
46
- },
47
- "./aws-lambda": {
48
- "types": "./dist/adapters/aws-lambda/index.d.mts",
49
- "import": "./dist/adapters/aws-lambda/index.mjs",
50
- "default": "./dist/adapters/aws-lambda/index.mjs"
51
+ "./extensions/route": {
52
+ "types": "./dist/extensions/route.d.mts",
53
+ "import": "./dist/extensions/route.mjs",
54
+ "default": "./dist/extensions/route.mjs"
51
55
  }
52
56
  },
53
57
  "files": [
54
58
  "dist"
55
59
  ],
56
60
  "dependencies": {
57
- "json-schema-typed": "^8.0.2",
61
+ "@hey-api/spec-types": "0.0.0-next-20260408030107",
62
+ "@scalar/api-reference": "^1.57.2",
63
+ "@standardserver/core": "^0.0.24",
64
+ "@standardserver/fetch": "^0.0.24",
65
+ "@types/swagger-ui": "^5.32.0",
58
66
  "rou3": "^0.7.12",
59
- "@orpc/client": "1.14.5",
60
- "@orpc/contract": "1.14.5",
61
- "@orpc/openapi-client": "1.14.5",
62
- "@orpc/server": "1.14.5",
63
- "@orpc/shared": "1.14.5",
64
- "@orpc/interop": "1.14.5",
65
- "@orpc/standard-server": "1.14.5"
67
+ "swagger-ui": "^5.32.6",
68
+ "@orpc/client": "2.0.0-beta.1",
69
+ "@orpc/server": "2.0.0-beta.1",
70
+ "@orpc/shared": "2.0.0-beta.1",
71
+ "@orpc/contract": "2.0.0-beta.1",
72
+ "@orpc/json-schema": "2.0.0-beta.1"
66
73
  },
67
74
  "devDependencies": {
68
- "fastify": "^5.8.3",
69
- "zod": "^4.3.6"
75
+ "fastify": "^5.6.2",
76
+ "zod": "^4.4.3"
70
77
  },
71
78
  "scripts": {
72
79
  "build": "unbuild",
73
- "build:watch": "pnpm run build --watch",
74
80
  "type:check": "tsc -b"
75
81
  }
76
82
  }
@@ -1,20 +0,0 @@
1
- import { Context, Router } from '@orpc/server';
2
- import { AwsLambdaHandler, AwsLambdaHandlerOptions } from '@orpc/server/aws-lambda';
3
- import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.mjs';
4
- import '@orpc/openapi-client/standard';
5
- import '@orpc/server/standard';
6
- import '@orpc/client';
7
- import '@orpc/standard-server';
8
- import '@orpc/shared';
9
-
10
- /**
11
- * OpenAPI Handler for AWS Lambda.
12
- *
13
- * @see {@link https://orpc.dev/docs/openapi/openapi-handler OpenAPI Handler Docs}
14
- * @see {@link https://orpc.dev/docs/adapters/http HTTP Adapter Docs}
15
- */
16
- declare class OpenAPIHandler<T extends Context> extends AwsLambdaHandler<T> {
17
- constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & AwsLambdaHandlerOptions>);
18
- }
19
-
20
- export { OpenAPIHandler };
@@ -1,20 +0,0 @@
1
- import { Context, Router } from '@orpc/server';
2
- import { AwsLambdaHandler, AwsLambdaHandlerOptions } from '@orpc/server/aws-lambda';
3
- import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.js';
4
- import '@orpc/openapi-client/standard';
5
- import '@orpc/server/standard';
6
- import '@orpc/client';
7
- import '@orpc/standard-server';
8
- import '@orpc/shared';
9
-
10
- /**
11
- * OpenAPI Handler for AWS Lambda.
12
- *
13
- * @see {@link https://orpc.dev/docs/openapi/openapi-handler OpenAPI Handler Docs}
14
- * @see {@link https://orpc.dev/docs/adapters/http HTTP Adapter Docs}
15
- */
16
- declare class OpenAPIHandler<T extends Context> extends AwsLambdaHandler<T> {
17
- constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & AwsLambdaHandlerOptions>);
18
- }
19
-
20
- export { OpenAPIHandler };
@@ -1,18 +0,0 @@
1
- import { AwsLambdaHandler } from '@orpc/server/aws-lambda';
2
- import { a as StandardOpenAPIHandler } from '../../shared/openapi.BB-W-NKv.mjs';
3
- import '@orpc/openapi-client/standard';
4
- import '@orpc/server/standard';
5
- import '@orpc/client';
6
- import '@orpc/contract';
7
- import '@orpc/shared';
8
- import '@orpc/client/standard';
9
- import '@orpc/server';
10
- import 'rou3';
11
-
12
- class OpenAPIHandler extends AwsLambdaHandler {
13
- constructor(router, options = {}) {
14
- super(new StandardOpenAPIHandler(router, options), options);
15
- }
16
- }
17
-
18
- export { OpenAPIHandler };
@@ -1,23 +0,0 @@
1
- import { Context, Router } from '@orpc/server';
2
- import { FastifyHandlerOptions, FastifyHandler } from '@orpc/server/fastify';
3
- import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.mjs';
4
- import '@orpc/openapi-client/standard';
5
- import '@orpc/server/standard';
6
- import '@orpc/client';
7
- import '@orpc/standard-server';
8
- import '@orpc/shared';
9
-
10
- interface OpenAPIHandlerOptions<T extends Context> extends FastifyHandlerOptions<T>, StandardOpenAPIHandlerOptions<T> {
11
- }
12
- /**
13
- * OpenAPI Handler for Fastify Server
14
- *
15
- * @see {@link https://orpc.dev/docs/openapi/openapi-handler OpenAPI Handler Docs}
16
- * @see {@link https://orpc.dev/docs/adapters/http HTTP Adapter Docs}
17
- */
18
- declare class OpenAPIHandler<T extends Context> extends FastifyHandler<T> {
19
- constructor(router: Router<any, T>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
20
- }
21
-
22
- export { OpenAPIHandler };
23
- export type { OpenAPIHandlerOptions };
@@ -1,23 +0,0 @@
1
- import { Context, Router } from '@orpc/server';
2
- import { FastifyHandlerOptions, FastifyHandler } from '@orpc/server/fastify';
3
- import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.js';
4
- import '@orpc/openapi-client/standard';
5
- import '@orpc/server/standard';
6
- import '@orpc/client';
7
- import '@orpc/standard-server';
8
- import '@orpc/shared';
9
-
10
- interface OpenAPIHandlerOptions<T extends Context> extends FastifyHandlerOptions<T>, StandardOpenAPIHandlerOptions<T> {
11
- }
12
- /**
13
- * OpenAPI Handler for Fastify Server
14
- *
15
- * @see {@link https://orpc.dev/docs/openapi/openapi-handler OpenAPI Handler Docs}
16
- * @see {@link https://orpc.dev/docs/adapters/http HTTP Adapter Docs}
17
- */
18
- declare class OpenAPIHandler<T extends Context> extends FastifyHandler<T> {
19
- constructor(router: Router<any, T>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
20
- }
21
-
22
- export { OpenAPIHandler };
23
- export type { OpenAPIHandlerOptions };
@@ -1,18 +0,0 @@
1
- import { FastifyHandler } from '@orpc/server/fastify';
2
- import { a as StandardOpenAPIHandler } from '../../shared/openapi.BB-W-NKv.mjs';
3
- import '@orpc/openapi-client/standard';
4
- import '@orpc/server/standard';
5
- import '@orpc/client';
6
- import '@orpc/contract';
7
- import '@orpc/shared';
8
- import '@orpc/client/standard';
9
- import '@orpc/server';
10
- import 'rou3';
11
-
12
- class OpenAPIHandler extends FastifyHandler {
13
- constructor(router, options = {}) {
14
- super(new StandardOpenAPIHandler(router, options), options);
15
- }
16
- }
17
-
18
- export { OpenAPIHandler };
@@ -1,204 +0,0 @@
1
- import { standardizeHTTPPath, StandardOpenAPIJsonSerializer, StandardBracketNotationSerializer, StandardOpenAPISerializer } from '@orpc/openapi-client/standard';
2
- import { StandardHandler } from '@orpc/server/standard';
3
- import { isORPCErrorStatus } from '@orpc/client';
4
- import { fallbackContractConfig } from '@orpc/contract';
5
- import { isObject, stringifyJSON, tryDecodeURIComponent, value } from '@orpc/shared';
6
- import { toHttpPath } from '@orpc/client/standard';
7
- import { traverseContractProcedures, isProcedure, getLazyMeta, unlazy, getRouter, createContractedProcedure } from '@orpc/server';
8
- import { createRouter, addRoute, findRoute } from 'rou3';
9
-
10
- class StandardOpenAPICodec {
11
- constructor(serializer, options = {}) {
12
- this.serializer = serializer;
13
- this.customErrorResponseBodyEncoder = options.customErrorResponseBodyEncoder;
14
- }
15
- customErrorResponseBodyEncoder;
16
- async decode(request, params, procedure) {
17
- const inputStructure = fallbackContractConfig("defaultInputStructure", procedure["~orpc"].route.inputStructure);
18
- if (inputStructure === "compact") {
19
- const data = request.method === "GET" ? this.serializer.deserialize(request.url.searchParams) : this.serializer.deserialize(await request.body());
20
- if (data === void 0) {
21
- return params;
22
- }
23
- if (isObject(data)) {
24
- return {
25
- ...params,
26
- ...data
27
- };
28
- }
29
- return data;
30
- }
31
- const deserializeSearchParams = () => {
32
- return this.serializer.deserialize(request.url.searchParams);
33
- };
34
- return {
35
- params,
36
- get query() {
37
- const value = deserializeSearchParams();
38
- Object.defineProperty(this, "query", { value, writable: true });
39
- return value;
40
- },
41
- set query(value) {
42
- Object.defineProperty(this, "query", { value, writable: true });
43
- },
44
- headers: request.headers,
45
- body: this.serializer.deserialize(await request.body())
46
- };
47
- }
48
- encode(output, procedure) {
49
- const successStatus = fallbackContractConfig("defaultSuccessStatus", procedure["~orpc"].route.successStatus);
50
- const outputStructure = fallbackContractConfig("defaultOutputStructure", procedure["~orpc"].route.outputStructure);
51
- if (outputStructure === "compact") {
52
- if (output instanceof ReadableStream) {
53
- return {
54
- status: successStatus,
55
- headers: {},
56
- body: output
57
- };
58
- }
59
- return {
60
- status: successStatus,
61
- headers: {},
62
- body: this.serializer.serialize(output)
63
- };
64
- }
65
- if (!this.#isDetailedOutput(output)) {
66
- throw new Error(`
67
- Invalid "detailed" output structure:
68
- \u2022 Expected an object with optional properties:
69
- - status (number 200-399)
70
- - headers (Record<string, string | string[]>)
71
- - body (any)
72
- \u2022 No extra keys allowed.
73
-
74
- Actual value:
75
- ${stringifyJSON(output)}
76
- `);
77
- }
78
- if (output.body instanceof ReadableStream) {
79
- return {
80
- status: output.status ?? successStatus,
81
- headers: output.headers ?? {},
82
- body: output.body
83
- };
84
- }
85
- return {
86
- status: output.status ?? successStatus,
87
- headers: output.headers ?? {},
88
- body: this.serializer.serialize(output.body)
89
- };
90
- }
91
- encodeError(error) {
92
- const body = this.customErrorResponseBodyEncoder?.(error) ?? error.toJSON();
93
- return {
94
- status: error.status,
95
- headers: {},
96
- body: this.serializer.serialize(body, { outputFormat: "plain" })
97
- };
98
- }
99
- #isDetailedOutput(output) {
100
- if (!isObject(output)) {
101
- return false;
102
- }
103
- if (output.headers && !isObject(output.headers)) {
104
- return false;
105
- }
106
- if (output.status !== void 0 && (typeof output.status !== "number" || !Number.isInteger(output.status) || isORPCErrorStatus(output.status))) {
107
- return false;
108
- }
109
- return true;
110
- }
111
- }
112
-
113
- function toRou3Pattern(path) {
114
- return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/**:$1").replace(/\/\{([^}]+)\}/g, "/:$1");
115
- }
116
- function decodeParams(params) {
117
- return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, tryDecodeURIComponent(value)]));
118
- }
119
-
120
- class StandardOpenAPIMatcher {
121
- filter;
122
- tree = createRouter();
123
- pendingRouters = [];
124
- constructor(options = {}) {
125
- this.filter = options.filter ?? true;
126
- }
127
- init(router, path = []) {
128
- const laziedOptions = traverseContractProcedures({ router, path }, (traverseOptions) => {
129
- if (!value(this.filter, traverseOptions)) {
130
- return;
131
- }
132
- const { path: path2, contract } = traverseOptions;
133
- const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route.method);
134
- const httpPath = toRou3Pattern(contract["~orpc"].route.path ?? toHttpPath(path2));
135
- if (isProcedure(contract)) {
136
- addRoute(this.tree, method, httpPath, {
137
- path: path2,
138
- contract,
139
- procedure: contract,
140
- // this mean dev not used contract-first so we can used contract as procedure directly
141
- router
142
- });
143
- } else {
144
- addRoute(this.tree, method, httpPath, {
145
- path: path2,
146
- contract,
147
- procedure: void 0,
148
- router
149
- });
150
- }
151
- });
152
- this.pendingRouters.push(...laziedOptions.map((option) => ({
153
- ...option,
154
- httpPathPrefix: toHttpPath(option.path),
155
- laziedPrefix: getLazyMeta(option.router).prefix
156
- })));
157
- }
158
- async match(method, pathname) {
159
- if (this.pendingRouters.length) {
160
- const newPendingRouters = [];
161
- for (const pendingRouter of this.pendingRouters) {
162
- if (!pendingRouter.laziedPrefix || pathname.startsWith(pendingRouter.laziedPrefix) || pathname.startsWith(pendingRouter.httpPathPrefix)) {
163
- const { default: router } = await unlazy(pendingRouter.router);
164
- this.init(router, pendingRouter.path);
165
- } else {
166
- newPendingRouters.push(pendingRouter);
167
- }
168
- }
169
- this.pendingRouters = newPendingRouters;
170
- }
171
- const match = findRoute(this.tree, method, pathname);
172
- if (!match) {
173
- return void 0;
174
- }
175
- if (!match.data.procedure) {
176
- const { default: maybeProcedure } = await unlazy(getRouter(match.data.router, match.data.path));
177
- if (!isProcedure(maybeProcedure)) {
178
- throw new Error(`
179
- [Contract-First] Missing or invalid implementation for procedure at path: ${toHttpPath(match.data.path)}.
180
- Ensure that the procedure is correctly defined and matches the expected contract.
181
- `);
182
- }
183
- match.data.procedure = createContractedProcedure(maybeProcedure, match.data.contract);
184
- }
185
- return {
186
- path: match.data.path,
187
- procedure: match.data.procedure,
188
- params: match.params ? decodeParams(match.params) : void 0
189
- };
190
- }
191
- }
192
-
193
- class StandardOpenAPIHandler extends StandardHandler {
194
- constructor(router, options) {
195
- const jsonSerializer = new StandardOpenAPIJsonSerializer(options);
196
- const bracketNotationSerializer = new StandardBracketNotationSerializer(options);
197
- const serializer = new StandardOpenAPISerializer(jsonSerializer, bracketNotationSerializer);
198
- const matcher = new StandardOpenAPIMatcher(options);
199
- const codec = new StandardOpenAPICodec(serializer, options);
200
- super(router, matcher, codec, options);
201
- }
202
- }
203
-
204
- export { StandardOpenAPICodec as S, StandardOpenAPIHandler as a, StandardOpenAPIMatcher as b, decodeParams as d, toRou3Pattern as t };
@@ -1,120 +0,0 @@
1
- import { AnySchema, OpenAPI, AnyContractProcedure, AnyContractRouter } from '@orpc/contract';
2
- import { StandardOpenAPIJsonSerializerOptions } from '@orpc/openapi-client/standard';
3
- import { AnyProcedure, TraverseContractProcedureCallbackOptions, AnyRouter } from '@orpc/server';
4
- import { Promisable, Value } from '@orpc/shared';
5
- import { JSONSchema } from 'json-schema-typed/draft-2020-12';
6
-
7
- interface SchemaConverterComponent {
8
- allowedStrategies: readonly SchemaConvertOptions['strategy'][];
9
- schema: AnySchema;
10
- required: boolean;
11
- ref: string;
12
- }
13
- interface SchemaConvertOptions {
14
- strategy: 'input' | 'output';
15
- /**
16
- * Common components should use `$ref` to represent themselves if matched.
17
- */
18
- components?: readonly SchemaConverterComponent[];
19
- /**
20
- * Minimum schema structure depth required before using `$ref` for components.
21
- *
22
- * For example, if set to 2, `$ref` will only be used for schemas nested at depth 2 or greater.
23
- *
24
- * @default 0 - No depth limit;
25
- */
26
- minStructureDepthForRef?: number;
27
- }
28
- interface SchemaConverter {
29
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: JSONSchema]>;
30
- }
31
- interface ConditionalSchemaConverter extends SchemaConverter {
32
- condition(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<boolean>;
33
- }
34
- declare class CompositeSchemaConverter implements SchemaConverter {
35
- private readonly converters;
36
- constructor(converters: readonly ConditionalSchemaConverter[]);
37
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promise<[required: boolean, jsonSchema: JSONSchema]>;
38
- }
39
-
40
- interface OpenAPIGeneratorOptions extends StandardOpenAPIJsonSerializerOptions {
41
- schemaConverters?: ConditionalSchemaConverter[];
42
- }
43
- interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPI.Document, 'openapi'>> {
44
- /**
45
- * Exclude procedures from the OpenAPI specification.
46
- *
47
- * @deprecated Use `filter` option instead.
48
- * @default () => false
49
- */
50
- exclude?: (procedure: AnyProcedure | AnyContractProcedure, path: readonly string[]) => boolean;
51
- /**
52
- * Filter procedures. Return `false` to exclude a procedure from the OpenAPI specification.
53
- *
54
- * @default true
55
- */
56
- filter?: Value<boolean, [options: TraverseContractProcedureCallbackOptions]>;
57
- /**
58
- * Common schemas to be used for $ref resolution.
59
- */
60
- commonSchemas?: Record<string, {
61
- /**
62
- * Determines which schema definition to use when input and output schemas differ.
63
- * This is needed because some schemas transform data differently between input and output,
64
- * making it impossible to use a single $ref for both cases.
65
- *
66
- * @example
67
- * ```ts
68
- * // This schema transforms a string input into a number output
69
- * const Schema = z.string()
70
- * .transform(v => Number(v))
71
- * .pipe(z.number())
72
- *
73
- * // Input schema: { type: 'string' }
74
- * // Output schema: { type: 'number' }
75
- * ```
76
- *
77
- * When schemas differ between input and output, you must explicitly choose
78
- * which version to use for the OpenAPI specification.
79
- *
80
- * @default 'input' - Uses the input schema definition by default
81
- */
82
- strategy?: SchemaConvertOptions['strategy'];
83
- schema: AnySchema;
84
- } | {
85
- error: 'UndefinedError';
86
- schema?: never;
87
- }>;
88
- /**
89
- * Define a custom JSON schema for the error response body when using
90
- * type-safe errors. Helps align ORPC error formatting with existing API
91
- * response standards or conventions.
92
- *
93
- * @remarks
94
- * - Return `null | undefined` to use the default error response body shaper.
95
- */
96
- customErrorResponseBodySchema?: Value<JSONSchema | undefined | null, [
97
- definedErrors: [code: string, defaultMessage: string, dataRequired: boolean, dataSchema: JSONSchema][],
98
- status: number
99
- ]>;
100
- }
101
- /**
102
- * The generator that converts oRPC routers/contracts to OpenAPI specifications.
103
- *
104
- * @see {@link https://orpc.dev/docs/openapi/openapi-specification OpenAPI Specification Docs}
105
- */
106
- declare class OpenAPIGenerator {
107
- #private;
108
- private readonly serializer;
109
- private readonly converter;
110
- constructor(options?: OpenAPIGeneratorOptions);
111
- /**
112
- * Generates OpenAPI specifications from oRPC routers/contracts.
113
- *
114
- * @see {@link https://orpc.dev/docs/openapi/openapi-specification OpenAPI Specification Docs}
115
- */
116
- generate(router: AnyContractRouter | AnyRouter, { customErrorResponseBodySchema, commonSchemas, filter: baseFilter, exclude, ...baseDoc }?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
117
- }
118
-
119
- export { OpenAPIGenerator as b, CompositeSchemaConverter as e };
120
- export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConverterComponent as S, OpenAPIGeneratorGenerateOptions as a, SchemaConvertOptions as c, SchemaConverter as d };
@@ -1,120 +0,0 @@
1
- import { AnySchema, OpenAPI, AnyContractProcedure, AnyContractRouter } from '@orpc/contract';
2
- import { StandardOpenAPIJsonSerializerOptions } from '@orpc/openapi-client/standard';
3
- import { AnyProcedure, TraverseContractProcedureCallbackOptions, AnyRouter } from '@orpc/server';
4
- import { Promisable, Value } from '@orpc/shared';
5
- import { JSONSchema } from 'json-schema-typed/draft-2020-12';
6
-
7
- interface SchemaConverterComponent {
8
- allowedStrategies: readonly SchemaConvertOptions['strategy'][];
9
- schema: AnySchema;
10
- required: boolean;
11
- ref: string;
12
- }
13
- interface SchemaConvertOptions {
14
- strategy: 'input' | 'output';
15
- /**
16
- * Common components should use `$ref` to represent themselves if matched.
17
- */
18
- components?: readonly SchemaConverterComponent[];
19
- /**
20
- * Minimum schema structure depth required before using `$ref` for components.
21
- *
22
- * For example, if set to 2, `$ref` will only be used for schemas nested at depth 2 or greater.
23
- *
24
- * @default 0 - No depth limit;
25
- */
26
- minStructureDepthForRef?: number;
27
- }
28
- interface SchemaConverter {
29
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: JSONSchema]>;
30
- }
31
- interface ConditionalSchemaConverter extends SchemaConverter {
32
- condition(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<boolean>;
33
- }
34
- declare class CompositeSchemaConverter implements SchemaConverter {
35
- private readonly converters;
36
- constructor(converters: readonly ConditionalSchemaConverter[]);
37
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promise<[required: boolean, jsonSchema: JSONSchema]>;
38
- }
39
-
40
- interface OpenAPIGeneratorOptions extends StandardOpenAPIJsonSerializerOptions {
41
- schemaConverters?: ConditionalSchemaConverter[];
42
- }
43
- interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPI.Document, 'openapi'>> {
44
- /**
45
- * Exclude procedures from the OpenAPI specification.
46
- *
47
- * @deprecated Use `filter` option instead.
48
- * @default () => false
49
- */
50
- exclude?: (procedure: AnyProcedure | AnyContractProcedure, path: readonly string[]) => boolean;
51
- /**
52
- * Filter procedures. Return `false` to exclude a procedure from the OpenAPI specification.
53
- *
54
- * @default true
55
- */
56
- filter?: Value<boolean, [options: TraverseContractProcedureCallbackOptions]>;
57
- /**
58
- * Common schemas to be used for $ref resolution.
59
- */
60
- commonSchemas?: Record<string, {
61
- /**
62
- * Determines which schema definition to use when input and output schemas differ.
63
- * This is needed because some schemas transform data differently between input and output,
64
- * making it impossible to use a single $ref for both cases.
65
- *
66
- * @example
67
- * ```ts
68
- * // This schema transforms a string input into a number output
69
- * const Schema = z.string()
70
- * .transform(v => Number(v))
71
- * .pipe(z.number())
72
- *
73
- * // Input schema: { type: 'string' }
74
- * // Output schema: { type: 'number' }
75
- * ```
76
- *
77
- * When schemas differ between input and output, you must explicitly choose
78
- * which version to use for the OpenAPI specification.
79
- *
80
- * @default 'input' - Uses the input schema definition by default
81
- */
82
- strategy?: SchemaConvertOptions['strategy'];
83
- schema: AnySchema;
84
- } | {
85
- error: 'UndefinedError';
86
- schema?: never;
87
- }>;
88
- /**
89
- * Define a custom JSON schema for the error response body when using
90
- * type-safe errors. Helps align ORPC error formatting with existing API
91
- * response standards or conventions.
92
- *
93
- * @remarks
94
- * - Return `null | undefined` to use the default error response body shaper.
95
- */
96
- customErrorResponseBodySchema?: Value<JSONSchema | undefined | null, [
97
- definedErrors: [code: string, defaultMessage: string, dataRequired: boolean, dataSchema: JSONSchema][],
98
- status: number
99
- ]>;
100
- }
101
- /**
102
- * The generator that converts oRPC routers/contracts to OpenAPI specifications.
103
- *
104
- * @see {@link https://orpc.dev/docs/openapi/openapi-specification OpenAPI Specification Docs}
105
- */
106
- declare class OpenAPIGenerator {
107
- #private;
108
- private readonly serializer;
109
- private readonly converter;
110
- constructor(options?: OpenAPIGeneratorOptions);
111
- /**
112
- * Generates OpenAPI specifications from oRPC routers/contracts.
113
- *
114
- * @see {@link https://orpc.dev/docs/openapi/openapi-specification OpenAPI Specification Docs}
115
- */
116
- generate(router: AnyContractRouter | AnyRouter, { customErrorResponseBodySchema, commonSchemas, filter: baseFilter, exclude, ...baseDoc }?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
117
- }
118
-
119
- export { OpenAPIGenerator as b, CompositeSchemaConverter as e };
120
- export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConverterComponent as S, OpenAPIGeneratorGenerateOptions as a, SchemaConvertOptions as c, SchemaConverter as d };