@orpc/openapi 0.0.0-next.eaf61c7 → 0.0.0-next.eb3d98a

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/README.md CHANGED
@@ -30,7 +30,7 @@
30
30
  - **🔗 End-to-End Type Safety**: Ensure type-safe inputs, outputs, and errors from client to server.
31
31
  - **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
32
32
  - **📝 Contract-First Development**: Optionally define your API contract before implementation.
33
- - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte), Pinia Colada, and more.
33
+ - **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), Pinia Colada, and more.
34
34
  - **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
35
35
  - **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
36
36
  - **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
@@ -1,8 +1,10 @@
1
1
  import { Context, Router } from '@orpc/server';
2
2
  import { AwsLambdaHandler, AwsLambdaHandlerOptions } from '@orpc/server/aws-lambda';
3
- import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.mjs';
3
+ import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.CQmjvnb0.mjs';
4
4
  import '@orpc/openapi-client/standard';
5
5
  import '@orpc/server/standard';
6
+ import '@orpc/client';
7
+ import '@orpc/shared';
6
8
 
7
9
  /**
8
10
  * OpenAPI Handler for AWS Lambda.
@@ -10,8 +12,8 @@ import '@orpc/server/standard';
10
12
  * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
11
13
  * @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
12
14
  */
13
- declare class experimental_OpenAPIHandler<T extends Context> extends AwsLambdaHandler<T> {
15
+ declare class OpenAPIHandler<T extends Context> extends AwsLambdaHandler<T> {
14
16
  constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & AwsLambdaHandlerOptions>);
15
17
  }
16
18
 
17
- export { experimental_OpenAPIHandler };
19
+ export { OpenAPIHandler };
@@ -1,8 +1,10 @@
1
1
  import { Context, Router } from '@orpc/server';
2
2
  import { AwsLambdaHandler, AwsLambdaHandlerOptions } from '@orpc/server/aws-lambda';
3
- import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.js';
3
+ import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.CQmjvnb0.js';
4
4
  import '@orpc/openapi-client/standard';
5
5
  import '@orpc/server/standard';
6
+ import '@orpc/client';
7
+ import '@orpc/shared';
6
8
 
7
9
  /**
8
10
  * OpenAPI Handler for AWS Lambda.
@@ -10,8 +12,8 @@ import '@orpc/server/standard';
10
12
  * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
11
13
  * @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
12
14
  */
13
- declare class experimental_OpenAPIHandler<T extends Context> extends AwsLambdaHandler<T> {
15
+ declare class OpenAPIHandler<T extends Context> extends AwsLambdaHandler<T> {
14
16
  constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & AwsLambdaHandlerOptions>);
15
17
  }
16
18
 
17
- export { experimental_OpenAPIHandler };
19
+ export { OpenAPIHandler };
@@ -2,17 +2,17 @@ import { AwsLambdaHandler } from '@orpc/server/aws-lambda';
2
2
  import '@orpc/client';
3
3
  import '@orpc/contract';
4
4
  import '@orpc/shared';
5
- import { a as StandardOpenAPIHandler } from '../../shared/openapi.C_UtQ8Us.mjs';
5
+ import { a as StandardOpenAPIHandler } from '../../shared/openapi.BVXcB0u4.mjs';
6
6
  import '@orpc/client/standard';
7
7
  import '@orpc/server';
8
8
  import 'rou3';
9
9
  import '@orpc/openapi-client/standard';
10
10
  import '@orpc/server/standard';
11
11
 
12
- class experimental_OpenAPIHandler extends AwsLambdaHandler {
12
+ class OpenAPIHandler extends AwsLambdaHandler {
13
13
  constructor(router, options = {}) {
14
14
  super(new StandardOpenAPIHandler(router, options), options);
15
15
  }
16
16
  }
17
17
 
18
- export { experimental_OpenAPIHandler };
18
+ export { OpenAPIHandler };
@@ -1,8 +1,10 @@
1
1
  import { Context, Router } from '@orpc/server';
2
2
  import { FetchHandler, FetchHandlerOptions } from '@orpc/server/fetch';
3
- import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.mjs';
3
+ import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.CQmjvnb0.mjs';
4
4
  import '@orpc/openapi-client/standard';
5
5
  import '@orpc/server/standard';
6
+ import '@orpc/client';
7
+ import '@orpc/shared';
6
8
 
7
9
  /**
8
10
  * OpenAPI Handler for Fetch Server
@@ -1,8 +1,10 @@
1
1
  import { Context, Router } from '@orpc/server';
2
2
  import { FetchHandler, FetchHandlerOptions } from '@orpc/server/fetch';
3
- import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.js';
3
+ import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.CQmjvnb0.js';
4
4
  import '@orpc/openapi-client/standard';
5
5
  import '@orpc/server/standard';
6
+ import '@orpc/client';
7
+ import '@orpc/shared';
6
8
 
7
9
  /**
8
10
  * OpenAPI Handler for Fetch Server
@@ -2,7 +2,7 @@ import { FetchHandler } from '@orpc/server/fetch';
2
2
  import '@orpc/client';
3
3
  import '@orpc/contract';
4
4
  import '@orpc/shared';
5
- import { a as StandardOpenAPIHandler } from '../../shared/openapi.C_UtQ8Us.mjs';
5
+ import { a as StandardOpenAPIHandler } from '../../shared/openapi.BVXcB0u4.mjs';
6
6
  import '@orpc/client/standard';
7
7
  import '@orpc/server';
8
8
  import 'rou3';
@@ -1,8 +1,10 @@
1
1
  import { Context, Router } from '@orpc/server';
2
2
  import { NodeHttpHandler, NodeHttpHandlerOptions } from '@orpc/server/node';
3
- import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.mjs';
3
+ import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.CQmjvnb0.mjs';
4
4
  import '@orpc/openapi-client/standard';
5
5
  import '@orpc/server/standard';
6
+ import '@orpc/client';
7
+ import '@orpc/shared';
6
8
 
7
9
  /**
8
10
  * OpenAPI Handler for Node Server
@@ -1,8 +1,10 @@
1
1
  import { Context, Router } from '@orpc/server';
2
2
  import { NodeHttpHandler, NodeHttpHandlerOptions } from '@orpc/server/node';
3
- import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.js';
3
+ import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.CQmjvnb0.js';
4
4
  import '@orpc/openapi-client/standard';
5
5
  import '@orpc/server/standard';
6
+ import '@orpc/client';
7
+ import '@orpc/shared';
6
8
 
7
9
  /**
8
10
  * OpenAPI Handler for Node Server
@@ -2,7 +2,7 @@ import { NodeHttpHandler } from '@orpc/server/node';
2
2
  import '@orpc/client';
3
3
  import '@orpc/contract';
4
4
  import '@orpc/shared';
5
- import { a as StandardOpenAPIHandler } from '../../shared/openapi.C_UtQ8Us.mjs';
5
+ import { a as StandardOpenAPIHandler } from '../../shared/openapi.BVXcB0u4.mjs';
6
6
  import '@orpc/client/standard';
7
7
  import '@orpc/server';
8
8
  import 'rou3';
@@ -1,9 +1,10 @@
1
1
  import { ORPCError, HTTPPath } from '@orpc/client';
2
2
  import { StandardOpenAPISerializer } from '@orpc/openapi-client/standard';
3
- import { AnyProcedure, AnyRouter } from '@orpc/server';
4
- import { StandardCodec, StandardParams, StandardMatcher, StandardMatchResult } from '@orpc/server/standard';
3
+ import { AnyProcedure } from '@orpc/server';
4
+ import { StandardCodec, StandardParams } from '@orpc/server/standard';
5
5
  import { StandardLazyRequest, StandardResponse } from '@orpc/standard-server';
6
- export { a as StandardOpenAPIHandler, S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.mjs';
6
+ export { a as StandardOpenAPIHandler, S as StandardOpenAPIHandlerOptions, c as StandardOpenAPIMatcher, b as StandardOpenAPIMatcherOptions } from '../../shared/openapi.CQmjvnb0.mjs';
7
+ import '@orpc/shared';
7
8
 
8
9
  declare class StandardOpenAPICodec implements StandardCodec {
9
10
  #private;
@@ -14,13 +15,6 @@ declare class StandardOpenAPICodec implements StandardCodec {
14
15
  encodeError(error: ORPCError<any, any>): StandardResponse;
15
16
  }
16
17
 
17
- declare class StandardOpenAPIMatcher implements StandardMatcher {
18
- private readonly tree;
19
- private pendingRouters;
20
- init(router: AnyRouter, path?: readonly string[]): void;
21
- match(method: string, pathname: HTTPPath): Promise<StandardMatchResult>;
22
- }
23
-
24
18
  /**
25
19
  * {@link https://github.com/unjs/rou3}
26
20
  *
@@ -32,4 +26,4 @@ declare function toRou3Pattern(path: HTTPPath): string;
32
26
  */
33
27
  declare function decodeParams(params: Record<string, string>): Record<string, string>;
34
28
 
35
- export { StandardOpenAPICodec, StandardOpenAPIMatcher, decodeParams, toRou3Pattern };
29
+ export { StandardOpenAPICodec, decodeParams, toRou3Pattern };
@@ -1,9 +1,10 @@
1
1
  import { ORPCError, HTTPPath } from '@orpc/client';
2
2
  import { StandardOpenAPISerializer } from '@orpc/openapi-client/standard';
3
- import { AnyProcedure, AnyRouter } from '@orpc/server';
4
- import { StandardCodec, StandardParams, StandardMatcher, StandardMatchResult } from '@orpc/server/standard';
3
+ import { AnyProcedure } from '@orpc/server';
4
+ import { StandardCodec, StandardParams } from '@orpc/server/standard';
5
5
  import { StandardLazyRequest, StandardResponse } from '@orpc/standard-server';
6
- export { a as StandardOpenAPIHandler, S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.js';
6
+ export { a as StandardOpenAPIHandler, S as StandardOpenAPIHandlerOptions, c as StandardOpenAPIMatcher, b as StandardOpenAPIMatcherOptions } from '../../shared/openapi.CQmjvnb0.js';
7
+ import '@orpc/shared';
7
8
 
8
9
  declare class StandardOpenAPICodec implements StandardCodec {
9
10
  #private;
@@ -14,13 +15,6 @@ declare class StandardOpenAPICodec implements StandardCodec {
14
15
  encodeError(error: ORPCError<any, any>): StandardResponse;
15
16
  }
16
17
 
17
- declare class StandardOpenAPIMatcher implements StandardMatcher {
18
- private readonly tree;
19
- private pendingRouters;
20
- init(router: AnyRouter, path?: readonly string[]): void;
21
- match(method: string, pathname: HTTPPath): Promise<StandardMatchResult>;
22
- }
23
-
24
18
  /**
25
19
  * {@link https://github.com/unjs/rou3}
26
20
  *
@@ -32,4 +26,4 @@ declare function toRou3Pattern(path: HTTPPath): string;
32
26
  */
33
27
  declare function decodeParams(params: Record<string, string>): Record<string, string>;
34
28
 
35
- export { StandardOpenAPICodec, StandardOpenAPIMatcher, decodeParams, toRou3Pattern };
29
+ export { StandardOpenAPICodec, decodeParams, toRou3Pattern };
@@ -1,4 +1,4 @@
1
- export { S as StandardOpenAPICodec, a as StandardOpenAPIHandler, b as StandardOpenAPIMatcher, d as decodeParams, t as toRou3Pattern } from '../../shared/openapi.C_UtQ8Us.mjs';
1
+ export { S as StandardOpenAPICodec, a as StandardOpenAPIHandler, b as StandardOpenAPIMatcher, d as decodeParams, t as toRou3Pattern } from '../../shared/openapi.BVXcB0u4.mjs';
2
2
  import '@orpc/openapi-client/standard';
3
3
  import '@orpc/server/standard';
4
4
  import '@orpc/client';
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { OpenAPI, AnyContractProcedure } from '@orpc/contract';
2
2
  export { OpenAPI } from '@orpc/contract';
3
- export { d as CompositeSchemaConverter, C as ConditionalSchemaConverter, b as OpenAPIGenerator, a as OpenAPIGeneratorGenerateOptions, O as OpenAPIGeneratorOptions, S as SchemaConvertOptions, c as SchemaConverter } from './shared/openapi.qZLdpE0a.mjs';
3
+ export { e as CompositeSchemaConverter, C as ConditionalSchemaConverter, b as OpenAPIGenerator, a as OpenAPIGeneratorGenerateOptions, O as OpenAPIGeneratorOptions, c as SchemaConvertOptions, d as SchemaConverter, S as SchemaConverterComponent } from './shared/openapi.DPAN3GVs.mjs';
4
4
  import { HTTPPath, HTTPMethod } from '@orpc/client';
5
5
  import { JSONSchema } from 'json-schema-typed/draft-2020-12';
6
6
  export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from 'json-schema-typed/draft-2020-12';
@@ -65,6 +65,7 @@ declare function checkParamsSchema(schema: ObjectSchema, params: string[]): bool
65
65
  * @internal
66
66
  */
67
67
  declare function toOpenAPISchema(schema: JSONSchema): OpenAPI.SchemaObject & object;
68
+ declare function resolveOpenAPIJsonSchemaRef(doc: OpenAPI.Document, schema: JSONSchema): JSONSchema;
68
69
 
69
70
  declare function createJsonifiedRouterClient<T extends AnyRouter, TClientContext extends ClientContext>(router: Lazyable<T | undefined>, ...rest: MaybeOptionalOptions<CreateProcedureClientOptions<InferRouterInitialContext<T>, Schema<unknown, unknown>, ErrorMap, Meta, TClientContext>>): JsonifiedClient<RouterClient<T, TClientContext>>;
70
71
 
@@ -105,5 +106,5 @@ declare const oo: {
105
106
  spec: typeof customOpenAPIOperation;
106
107
  };
107
108
 
108
- export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, expandArrayableSchema, expandUnionSchema, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, isPrimitiveSchema, oo, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
109
+ export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, expandArrayableSchema, expandUnionSchema, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, isPrimitiveSchema, oo, resolveOpenAPIJsonSchemaRef, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
109
110
  export type { FileSchema, ObjectSchema, OverrideOperationValue };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { OpenAPI, AnyContractProcedure } from '@orpc/contract';
2
2
  export { OpenAPI } from '@orpc/contract';
3
- export { d as CompositeSchemaConverter, C as ConditionalSchemaConverter, b as OpenAPIGenerator, a as OpenAPIGeneratorGenerateOptions, O as OpenAPIGeneratorOptions, S as SchemaConvertOptions, c as SchemaConverter } from './shared/openapi.qZLdpE0a.js';
3
+ export { e as CompositeSchemaConverter, C as ConditionalSchemaConverter, b as OpenAPIGenerator, a as OpenAPIGeneratorGenerateOptions, O as OpenAPIGeneratorOptions, c as SchemaConvertOptions, d as SchemaConverter, S as SchemaConverterComponent } from './shared/openapi.DPAN3GVs.js';
4
4
  import { HTTPPath, HTTPMethod } from '@orpc/client';
5
5
  import { JSONSchema } from 'json-schema-typed/draft-2020-12';
6
6
  export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from 'json-schema-typed/draft-2020-12';
@@ -65,6 +65,7 @@ declare function checkParamsSchema(schema: ObjectSchema, params: string[]): bool
65
65
  * @internal
66
66
  */
67
67
  declare function toOpenAPISchema(schema: JSONSchema): OpenAPI.SchemaObject & object;
68
+ declare function resolveOpenAPIJsonSchemaRef(doc: OpenAPI.Document, schema: JSONSchema): JSONSchema;
68
69
 
69
70
  declare function createJsonifiedRouterClient<T extends AnyRouter, TClientContext extends ClientContext>(router: Lazyable<T | undefined>, ...rest: MaybeOptionalOptions<CreateProcedureClientOptions<InferRouterInitialContext<T>, Schema<unknown, unknown>, ErrorMap, Meta, TClientContext>>): JsonifiedClient<RouterClient<T, TClientContext>>;
70
71
 
@@ -105,5 +106,5 @@ declare const oo: {
105
106
  spec: typeof customOpenAPIOperation;
106
107
  };
107
108
 
108
- export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, expandArrayableSchema, expandUnionSchema, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, isPrimitiveSchema, oo, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
109
+ export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, expandArrayableSchema, expandUnionSchema, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, isPrimitiveSchema, oo, resolveOpenAPIJsonSchemaRef, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
109
110
  export type { FileSchema, ObjectSchema, OverrideOperationValue };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { c as customOpenAPIOperation } from './shared/openapi.DaYgbD_w.mjs';
2
- export { C as CompositeSchemaConverter, L as LOGIC_KEYWORDS, O as OpenAPIGenerator, a as applyCustomOpenAPIOperation, n as applySchemaOptionality, h as checkParamsSchema, p as expandArrayableSchema, o as expandUnionSchema, m as filterSchemaBranches, g as getCustomOpenAPIOperation, l as isAnySchema, j as isFileSchema, k as isObjectSchema, q as isPrimitiveSchema, s as separateObjectSchema, d as toOpenAPIContent, e as toOpenAPIEventIteratorContent, b as toOpenAPIMethod, f as toOpenAPIParameters, t as toOpenAPIPath, i as toOpenAPISchema } from './shared/openapi.DaYgbD_w.mjs';
1
+ import { c as customOpenAPIOperation } from './shared/openapi.BtoY8ZFF.mjs';
2
+ export { C as CompositeSchemaConverter, L as LOGIC_KEYWORDS, O as OpenAPIGenerator, a as applyCustomOpenAPIOperation, n as applySchemaOptionality, h as checkParamsSchema, p as expandArrayableSchema, o as expandUnionSchema, m as filterSchemaBranches, g as getCustomOpenAPIOperation, l as isAnySchema, j as isFileSchema, k as isObjectSchema, q as isPrimitiveSchema, r as resolveOpenAPIJsonSchemaRef, s as separateObjectSchema, d as toOpenAPIContent, e as toOpenAPIEventIteratorContent, b as toOpenAPIMethod, f as toOpenAPIParameters, t as toOpenAPIPath, i as toOpenAPISchema } from './shared/openapi.BtoY8ZFF.mjs';
3
3
  import { createORPCErrorFromJson } from '@orpc/client';
4
4
  import { StandardOpenAPISerializer, StandardOpenAPIJsonSerializer, StandardBracketNotationSerializer } from '@orpc/openapi-client/standard';
5
5
  import { ORPCError, createRouterClient } from '@orpc/server';
@@ -2,7 +2,7 @@ import { OpenAPI } from '@orpc/contract';
2
2
  import { Context, HTTPPath, Router } from '@orpc/server';
3
3
  import { StandardHandlerInterceptorOptions, StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
4
4
  import { Value, Promisable } from '@orpc/shared';
5
- import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.qZLdpE0a.mjs';
5
+ import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.DPAN3GVs.mjs';
6
6
  import '@orpc/openapi-client/standard';
7
7
  import 'json-schema-typed/draft-2020-12';
8
8
 
@@ -2,7 +2,7 @@ import { OpenAPI } from '@orpc/contract';
2
2
  import { Context, HTTPPath, Router } from '@orpc/server';
3
3
  import { StandardHandlerInterceptorOptions, StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
4
4
  import { Value, Promisable } from '@orpc/shared';
5
- import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.qZLdpE0a.js';
5
+ import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.DPAN3GVs.js';
6
6
  import '@orpc/openapi-client/standard';
7
7
  import 'json-schema-typed/draft-2020-12';
8
8
 
@@ -1,5 +1,5 @@
1
1
  import { stringifyJSON, once, value } from '@orpc/shared';
2
- import { O as OpenAPIGenerator } from '../shared/openapi.DaYgbD_w.mjs';
2
+ import { O as OpenAPIGenerator } from '../shared/openapi.BtoY8ZFF.mjs';
3
3
  import '@orpc/client';
4
4
  import '@orpc/client/standard';
5
5
  import '@orpc/contract';
@@ -2,7 +2,7 @@ import { standardizeHTTPPath, StandardOpenAPIJsonSerializer, StandardBracketNota
2
2
  import { StandardHandler } from '@orpc/server/standard';
3
3
  import { isORPCErrorStatus } from '@orpc/client';
4
4
  import { fallbackContractConfig } from '@orpc/contract';
5
- import { isObject, stringifyJSON } from '@orpc/shared';
5
+ import { isObject, stringifyJSON, tryDecodeURIComponent, value } from '@orpc/shared';
6
6
  import { toHttpPath } from '@orpc/client/standard';
7
7
  import { traverseContractProcedures, isProcedure, getLazyMeta, unlazy, getRouter, createContractedProcedure } from '@orpc/server';
8
8
  import { createRouter, addRoute, findRoute } from 'rou3';
@@ -97,14 +97,22 @@ function toRou3Pattern(path) {
97
97
  return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/**:$1").replace(/\/\{([^}]+)\}/g, "/:$1");
98
98
  }
99
99
  function decodeParams(params) {
100
- return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, decodeURIComponent(value)]));
100
+ return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, tryDecodeURIComponent(value)]));
101
101
  }
102
102
 
103
103
  class StandardOpenAPIMatcher {
104
+ filter;
104
105
  tree = createRouter();
105
106
  pendingRouters = [];
107
+ constructor(options = {}) {
108
+ this.filter = options.filter ?? true;
109
+ }
106
110
  init(router, path = []) {
107
- const laziedOptions = traverseContractProcedures({ router, path }, ({ path: path2, contract }) => {
111
+ const laziedOptions = traverseContractProcedures({ router, path }, (traverseOptions) => {
112
+ if (!value(this.filter, traverseOptions)) {
113
+ return;
114
+ }
115
+ const { path: path2, contract } = traverseOptions;
108
116
  const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route.method);
109
117
  const httpPath = toRou3Pattern(contract["~orpc"].route.path ?? toHttpPath(path2));
110
118
  if (isProcedure(contract)) {
@@ -168,9 +176,9 @@ class StandardOpenAPIMatcher {
168
176
  class StandardOpenAPIHandler extends StandardHandler {
169
177
  constructor(router, options) {
170
178
  const jsonSerializer = new StandardOpenAPIJsonSerializer(options);
171
- const bracketNotationSerializer = new StandardBracketNotationSerializer();
179
+ const bracketNotationSerializer = new StandardBracketNotationSerializer(options);
172
180
  const serializer = new StandardOpenAPISerializer(jsonSerializer, bracketNotationSerializer);
173
- const matcher = new StandardOpenAPIMatcher();
181
+ const matcher = new StandardOpenAPIMatcher(options);
174
182
  const codec = new StandardOpenAPICodec(serializer);
175
183
  super(router, matcher, codec, options);
176
184
  }
@@ -3,7 +3,7 @@ import { toHttpPath } from '@orpc/client/standard';
3
3
  import { fallbackContractConfig, getEventIteratorSchemaDetails } from '@orpc/contract';
4
4
  import { standardizeHTTPPath, StandardOpenAPIJsonSerializer, getDynamicParams } from '@orpc/openapi-client/standard';
5
5
  import { isProcedure, resolveContractProcedures } from '@orpc/server';
6
- import { isObject, stringifyJSON, findDeepMatches, toArray, clone } from '@orpc/shared';
6
+ import { isObject, stringifyJSON, findDeepMatches, toArray, clone, value } from '@orpc/shared';
7
7
  import { TypeName } from 'json-schema-typed/draft-2020-12';
8
8
 
9
9
  const OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
@@ -345,6 +345,15 @@ function checkParamsSchema(schema, params) {
345
345
  function toOpenAPISchema(schema) {
346
346
  return schema === true ? {} : schema === false ? { not: {} } : schema;
347
347
  }
348
+ const OPENAPI_JSON_SCHEMA_REF_PREFIX = "#/components/schemas/";
349
+ function resolveOpenAPIJsonSchemaRef(doc, schema) {
350
+ if (typeof schema !== "object" || !schema.$ref?.startsWith(OPENAPI_JSON_SCHEMA_REF_PREFIX)) {
351
+ return schema;
352
+ }
353
+ const name = schema.$ref.slice(OPENAPI_JSON_SCHEMA_REF_PREFIX.length);
354
+ const resolved = doc.components?.schemas?.[name];
355
+ return resolved ?? schema;
356
+ }
348
357
 
349
358
  class CompositeSchemaConverter {
350
359
  converters;
@@ -376,18 +385,24 @@ class OpenAPIGenerator {
376
385
  * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
377
386
  */
378
387
  async generate(router, options = {}) {
379
- const exclude = options.exclude ?? (() => false);
388
+ const filter = options.filter ?? (({ contract, path }) => {
389
+ return !(options.exclude?.(contract, path) ?? false);
390
+ });
380
391
  const doc = {
381
392
  ...clone(options),
382
393
  info: options.info ?? { title: "API Reference", version: "0.0.0" },
383
394
  openapi: "3.1.1",
384
- exclude: void 0
395
+ exclude: void 0,
396
+ filter: void 0,
397
+ commonSchemas: void 0
385
398
  };
399
+ const { baseSchemaConvertOptions, undefinedErrorJsonSchema } = await this.#resolveCommonSchemas(doc, options.commonSchemas);
386
400
  const contracts = [];
387
- await resolveContractProcedures({ path: [], router }, ({ contract, path }) => {
388
- if (!exclude(contract, path)) {
389
- contracts.push({ contract, path });
401
+ await resolveContractProcedures({ path: [], router }, (traverseOptions) => {
402
+ if (!value(filter, traverseOptions)) {
403
+ return;
390
404
  }
405
+ contracts.push(traverseOptions);
391
406
  });
392
407
  const errors = [];
393
408
  for (const { contract, path } of contracts) {
@@ -407,9 +422,9 @@ class OpenAPIGenerator {
407
422
  deprecated: def.route.deprecated,
408
423
  tags: def.route.tags?.map((tag) => tag)
409
424
  };
410
- await this.#request(operationObjectRef, def);
411
- await this.#successResponse(operationObjectRef, def);
412
- await this.#errorResponse(operationObjectRef, def);
425
+ await this.#request(doc, operationObjectRef, def, baseSchemaConvertOptions);
426
+ await this.#successResponse(doc, operationObjectRef, def, baseSchemaConvertOptions);
427
+ await this.#errorResponse(operationObjectRef, def, baseSchemaConvertOptions, undefinedErrorJsonSchema);
413
428
  }
414
429
  doc.paths ??= {};
415
430
  doc.paths[httpPath] ??= {};
@@ -433,22 +448,96 @@ ${errors.join("\n\n")}`
433
448
  }
434
449
  return this.serializer.serialize(doc)[0];
435
450
  }
436
- async #request(ref, def) {
451
+ async #resolveCommonSchemas(doc, commonSchemas) {
452
+ let undefinedErrorJsonSchema = {
453
+ type: "object",
454
+ properties: {
455
+ defined: { const: false },
456
+ code: { type: "string" },
457
+ status: { type: "number" },
458
+ message: { type: "string" },
459
+ data: {}
460
+ },
461
+ required: ["defined", "code", "status", "message"]
462
+ };
463
+ const baseSchemaConvertOptions = {};
464
+ if (commonSchemas) {
465
+ baseSchemaConvertOptions.components = [];
466
+ for (const key in commonSchemas) {
467
+ const options = commonSchemas[key];
468
+ if (options.schema === void 0) {
469
+ continue;
470
+ }
471
+ const { schema, strategy = "input" } = options;
472
+ const [required, json] = await this.converter.convert(schema, { strategy });
473
+ const allowedStrategies = [strategy];
474
+ if (strategy === "input") {
475
+ const [outputRequired, outputJson] = await this.converter.convert(schema, { strategy: "output" });
476
+ if (outputRequired === required && stringifyJSON(outputJson) === stringifyJSON(json)) {
477
+ allowedStrategies.push("output");
478
+ }
479
+ } else if (strategy === "output") {
480
+ const [inputRequired, inputJson] = await this.converter.convert(schema, { strategy: "input" });
481
+ if (inputRequired === required && stringifyJSON(inputJson) === stringifyJSON(json)) {
482
+ allowedStrategies.push("input");
483
+ }
484
+ }
485
+ baseSchemaConvertOptions.components.push({
486
+ schema,
487
+ required,
488
+ ref: `#/components/schemas/${key}`,
489
+ allowedStrategies
490
+ });
491
+ }
492
+ doc.components ??= {};
493
+ doc.components.schemas ??= {};
494
+ for (const key in commonSchemas) {
495
+ const options = commonSchemas[key];
496
+ if (options.schema === void 0) {
497
+ if (options.error === "UndefinedError") {
498
+ doc.components.schemas[key] = toOpenAPISchema(undefinedErrorJsonSchema);
499
+ undefinedErrorJsonSchema = { $ref: `#/components/schemas/${key}` };
500
+ }
501
+ continue;
502
+ }
503
+ const { schema, strategy = "input" } = options;
504
+ const [, json] = await this.converter.convert(
505
+ schema,
506
+ {
507
+ ...baseSchemaConvertOptions,
508
+ strategy,
509
+ minStructureDepthForRef: 1
510
+ // not allow use $ref for root schemas
511
+ }
512
+ );
513
+ doc.components.schemas[key] = toOpenAPISchema(json);
514
+ }
515
+ }
516
+ return { baseSchemaConvertOptions, undefinedErrorJsonSchema };
517
+ }
518
+ async #request(doc, ref, def, baseSchemaConvertOptions) {
437
519
  const method = fallbackContractConfig("defaultMethod", def.route.method);
438
520
  const details = getEventIteratorSchemaDetails(def.inputSchema);
439
521
  if (details) {
440
522
  ref.requestBody = {
441
523
  required: true,
442
524
  content: toOpenAPIEventIteratorContent(
443
- await this.converter.convert(details.yields, { strategy: "input" }),
444
- await this.converter.convert(details.returns, { strategy: "input" })
525
+ await this.converter.convert(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
526
+ await this.converter.convert(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
445
527
  )
446
528
  };
447
529
  return;
448
530
  }
449
531
  const dynamicParams = getDynamicParams(def.route.path)?.map((v) => v.name);
450
532
  const inputStructure = fallbackContractConfig("defaultInputStructure", def.route.inputStructure);
451
- let [required, schema] = await this.converter.convert(def.inputSchema, { strategy: "input" });
533
+ let [required, schema] = await this.converter.convert(
534
+ def.inputSchema,
535
+ {
536
+ ...baseSchemaConvertOptions,
537
+ strategy: "input",
538
+ minStructureDepthForRef: dynamicParams?.length || inputStructure === "detailed" ? 1 : 0
539
+ }
540
+ );
452
541
  if (isAnySchema(schema) && !dynamicParams?.length) {
453
542
  return;
454
543
  }
@@ -491,7 +580,8 @@ ${errors.join("\n\n")}`
491
580
  if (!isObjectSchema(schema)) {
492
581
  throw error;
493
582
  }
494
- if (dynamicParams?.length && (schema.properties?.params === void 0 || !isObjectSchema(schema.properties.params) || !checkParamsSchema(schema.properties.params, dynamicParams))) {
583
+ const resolvedParamSchema = schema.properties?.params !== void 0 ? resolveOpenAPIJsonSchemaRef(doc, schema.properties.params) : void 0;
584
+ if (dynamicParams?.length && (resolvedParamSchema === void 0 || !isObjectSchema(resolvedParamSchema) || !checkParamsSchema(resolvedParamSchema, dynamicParams))) {
495
585
  throw new OpenAPIGeneratorError(
496
586
  'When input structure is "detailed" and path has dynamic params, the "params" schema must be an object with all dynamic params as required.'
497
587
  );
@@ -499,12 +589,13 @@ ${errors.join("\n\n")}`
499
589
  for (const from of ["params", "query", "headers"]) {
500
590
  const fromSchema = schema.properties?.[from];
501
591
  if (fromSchema !== void 0) {
502
- if (!isObjectSchema(fromSchema)) {
592
+ const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, fromSchema);
593
+ if (!isObjectSchema(resolvedSchema)) {
503
594
  throw error;
504
595
  }
505
596
  const parameterIn = from === "params" ? "path" : from === "headers" ? "header" : "query";
506
597
  ref.parameters ??= [];
507
- ref.parameters.push(...toOpenAPIParameters(fromSchema, parameterIn));
598
+ ref.parameters.push(...toOpenAPIParameters(resolvedSchema, parameterIn));
508
599
  }
509
600
  }
510
601
  if (schema.properties?.body !== void 0) {
@@ -514,7 +605,7 @@ ${errors.join("\n\n")}`
514
605
  };
515
606
  }
516
607
  }
517
- async #successResponse(ref, def) {
608
+ async #successResponse(doc, ref, def, baseSchemaConvertOptions) {
518
609
  const outputSchema = def.outputSchema;
519
610
  const status = fallbackContractConfig("defaultSuccessStatus", def.route.successStatus);
520
611
  const description = fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription);
@@ -525,13 +616,20 @@ ${errors.join("\n\n")}`
525
616
  ref.responses[status] = {
526
617
  description,
527
618
  content: toOpenAPIEventIteratorContent(
528
- await this.converter.convert(eventIteratorSchemaDetails.yields, { strategy: "output" }),
529
- await this.converter.convert(eventIteratorSchemaDetails.returns, { strategy: "output" })
619
+ await this.converter.convert(eventIteratorSchemaDetails.yields, { ...baseSchemaConvertOptions, strategy: "output" }),
620
+ await this.converter.convert(eventIteratorSchemaDetails.returns, { ...baseSchemaConvertOptions, strategy: "output" })
530
621
  )
531
622
  };
532
623
  return;
533
624
  }
534
- const [required, json] = await this.converter.convert(outputSchema, { strategy: "output" });
625
+ const [required, json] = await this.converter.convert(
626
+ outputSchema,
627
+ {
628
+ ...baseSchemaConvertOptions,
629
+ strategy: "output",
630
+ minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
631
+ }
632
+ );
535
633
  if (outputStructure === "compact") {
536
634
  ref.responses ??= {};
537
635
  ref.responses[status] = {
@@ -558,11 +656,12 @@ ${errors.join("\n\n")}`
558
656
  let schemaStatus;
559
657
  let schemaDescription;
560
658
  if (item.properties?.status !== void 0) {
561
- if (typeof item.properties.status !== "object" || item.properties.status.const === void 0 || typeof item.properties.status.const !== "number" || !Number.isInteger(item.properties.status.const) || isORPCErrorStatus(item.properties.status.const)) {
659
+ const statusSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.status);
660
+ if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) {
562
661
  throw error;
563
662
  }
564
- schemaStatus = item.properties.status.const;
565
- schemaDescription = item.properties.status.description;
663
+ schemaStatus = statusSchema.const;
664
+ schemaDescription = statusSchema.description;
566
665
  }
567
666
  const itemStatus = schemaStatus ?? status;
568
667
  const itemDescription = schemaDescription ?? description;
@@ -578,16 +677,17 @@ ${errors.join("\n\n")}`
578
677
  description: itemDescription
579
678
  };
580
679
  if (item.properties?.headers !== void 0) {
581
- if (!isObjectSchema(item.properties.headers)) {
680
+ const headersSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.headers);
681
+ if (!isObjectSchema(headersSchema)) {
582
682
  throw error;
583
683
  }
584
- for (const key in item.properties.headers.properties) {
585
- const headerSchema = item.properties.headers.properties[key];
684
+ for (const key in headersSchema.properties) {
685
+ const headerSchema = headersSchema.properties[key];
586
686
  if (headerSchema !== void 0) {
587
687
  ref.responses[itemStatus].headers ??= {};
588
688
  ref.responses[itemStatus].headers[key] = {
589
689
  schema: toOpenAPISchema(headerSchema),
590
- required: item.properties.headers.required?.includes(key)
690
+ required: item.required?.includes("headers") && headersSchema.required?.includes(key)
591
691
  };
592
692
  }
593
693
  }
@@ -599,7 +699,7 @@ ${errors.join("\n\n")}`
599
699
  }
600
700
  }
601
701
  }
602
- async #errorResponse(ref, def) {
702
+ async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema) {
603
703
  const errorMap = def.errorMap;
604
704
  const errors = {};
605
705
  for (const code in errorMap) {
@@ -609,7 +709,7 @@ ${errors.join("\n\n")}`
609
709
  }
610
710
  const status = fallbackORPCErrorStatus(code, config.status);
611
711
  const message = fallbackORPCErrorMessage(code, config.message);
612
- const [dataRequired, dataSchema] = await this.converter.convert(config.data, { strategy: "output" });
712
+ const [dataRequired, dataSchema] = await this.converter.convert(config.data, { ...baseSchemaConvertOptions, strategy: "output" });
613
713
  errors[status] ??= [];
614
714
  errors[status].push({
615
715
  type: "object",
@@ -631,17 +731,7 @@ ${errors.join("\n\n")}`
631
731
  content: toOpenAPIContent({
632
732
  oneOf: [
633
733
  ...schemas,
634
- {
635
- type: "object",
636
- properties: {
637
- defined: { const: false },
638
- code: { type: "string" },
639
- status: { type: "number" },
640
- message: { type: "string" },
641
- data: {}
642
- },
643
- required: ["defined", "code", "status", "message"]
644
- }
734
+ undefinedErrorSchema
645
735
  ]
646
736
  })
647
737
  };
@@ -649,4 +739,4 @@ ${errors.join("\n\n")}`
649
739
  }
650
740
  }
651
741
 
652
- export { CompositeSchemaConverter as C, LOGIC_KEYWORDS as L, OpenAPIGenerator as O, applyCustomOpenAPIOperation as a, toOpenAPIMethod as b, customOpenAPIOperation as c, toOpenAPIContent as d, toOpenAPIEventIteratorContent as e, toOpenAPIParameters as f, getCustomOpenAPIOperation as g, checkParamsSchema as h, toOpenAPISchema as i, isFileSchema as j, isObjectSchema as k, isAnySchema as l, filterSchemaBranches as m, applySchemaOptionality as n, expandUnionSchema as o, expandArrayableSchema as p, isPrimitiveSchema as q, separateObjectSchema as s, toOpenAPIPath as t };
742
+ export { CompositeSchemaConverter as C, LOGIC_KEYWORDS as L, OpenAPIGenerator as O, applyCustomOpenAPIOperation as a, toOpenAPIMethod as b, customOpenAPIOperation as c, toOpenAPIContent as d, toOpenAPIEventIteratorContent as e, toOpenAPIParameters as f, getCustomOpenAPIOperation as g, checkParamsSchema as h, toOpenAPISchema as i, isFileSchema as j, isObjectSchema as k, isAnySchema as l, filterSchemaBranches as m, applySchemaOptionality as n, expandUnionSchema as o, expandArrayableSchema as p, isPrimitiveSchema as q, resolveOpenAPIJsonSchemaRef as r, separateObjectSchema as s, toOpenAPIPath as t };
@@ -0,0 +1,31 @@
1
+ import { StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions } from '@orpc/openapi-client/standard';
2
+ import { TraverseContractProcedureCallbackOptions, AnyRouter, Context, Router } from '@orpc/server';
3
+ import { StandardMatcher, StandardMatchResult, StandardHandlerOptions, StandardHandler } from '@orpc/server/standard';
4
+ import { HTTPPath } from '@orpc/client';
5
+ import { Value } from '@orpc/shared';
6
+
7
+ interface StandardOpenAPIMatcherOptions {
8
+ /**
9
+ * Filter procedures. Return `false` to exclude a procedure from matching.
10
+ *
11
+ * @default true
12
+ */
13
+ filter?: Value<boolean, [options: TraverseContractProcedureCallbackOptions]>;
14
+ }
15
+ declare class StandardOpenAPIMatcher implements StandardMatcher {
16
+ private readonly filter;
17
+ private readonly tree;
18
+ private pendingRouters;
19
+ constructor(options?: StandardOpenAPIMatcherOptions);
20
+ init(router: AnyRouter, path?: readonly string[]): void;
21
+ match(method: string, pathname: HTTPPath): Promise<StandardMatchResult>;
22
+ }
23
+
24
+ interface StandardOpenAPIHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions, StandardOpenAPIMatcherOptions {
25
+ }
26
+ declare class StandardOpenAPIHandler<T extends Context> extends StandardHandler<T> {
27
+ constructor(router: Router<any, T>, options: NoInfer<StandardOpenAPIHandlerOptions<T>>);
28
+ }
29
+
30
+ export { StandardOpenAPIHandler as a, StandardOpenAPIMatcher as c };
31
+ export type { StandardOpenAPIHandlerOptions as S, StandardOpenAPIMatcherOptions as b };
@@ -0,0 +1,31 @@
1
+ import { StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions } from '@orpc/openapi-client/standard';
2
+ import { TraverseContractProcedureCallbackOptions, AnyRouter, Context, Router } from '@orpc/server';
3
+ import { StandardMatcher, StandardMatchResult, StandardHandlerOptions, StandardHandler } from '@orpc/server/standard';
4
+ import { HTTPPath } from '@orpc/client';
5
+ import { Value } from '@orpc/shared';
6
+
7
+ interface StandardOpenAPIMatcherOptions {
8
+ /**
9
+ * Filter procedures. Return `false` to exclude a procedure from matching.
10
+ *
11
+ * @default true
12
+ */
13
+ filter?: Value<boolean, [options: TraverseContractProcedureCallbackOptions]>;
14
+ }
15
+ declare class StandardOpenAPIMatcher implements StandardMatcher {
16
+ private readonly filter;
17
+ private readonly tree;
18
+ private pendingRouters;
19
+ constructor(options?: StandardOpenAPIMatcherOptions);
20
+ init(router: AnyRouter, path?: readonly string[]): void;
21
+ match(method: string, pathname: HTTPPath): Promise<StandardMatchResult>;
22
+ }
23
+
24
+ interface StandardOpenAPIHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions, StandardOpenAPIMatcherOptions {
25
+ }
26
+ declare class StandardOpenAPIHandler<T extends Context> extends StandardHandler<T> {
27
+ constructor(router: Router<any, T>, options: NoInfer<StandardOpenAPIHandlerOptions<T>>);
28
+ }
29
+
30
+ export { StandardOpenAPIHandler as a, StandardOpenAPIMatcher as c };
31
+ export type { StandardOpenAPIHandlerOptions as S, StandardOpenAPIMatcherOptions as b };
@@ -0,0 +1,108 @@
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
+ /**
90
+ * The generator that converts oRPC routers/contracts to OpenAPI specifications.
91
+ *
92
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
93
+ */
94
+ declare class OpenAPIGenerator {
95
+ #private;
96
+ private readonly serializer;
97
+ private readonly converter;
98
+ constructor(options?: OpenAPIGeneratorOptions);
99
+ /**
100
+ * Generates OpenAPI specifications from oRPC routers/contracts.
101
+ *
102
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
103
+ */
104
+ generate(router: AnyContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
105
+ }
106
+
107
+ export { OpenAPIGenerator as b, CompositeSchemaConverter as e };
108
+ export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConverterComponent as S, OpenAPIGeneratorGenerateOptions as a, SchemaConvertOptions as c, SchemaConverter as d };
@@ -0,0 +1,108 @@
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
+ /**
90
+ * The generator that converts oRPC routers/contracts to OpenAPI specifications.
91
+ *
92
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
93
+ */
94
+ declare class OpenAPIGenerator {
95
+ #private;
96
+ private readonly serializer;
97
+ private readonly converter;
98
+ constructor(options?: OpenAPIGeneratorOptions);
99
+ /**
100
+ * Generates OpenAPI specifications from oRPC routers/contracts.
101
+ *
102
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
103
+ */
104
+ generate(router: AnyContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
105
+ }
106
+
107
+ export { OpenAPIGenerator as b, CompositeSchemaConverter as e };
108
+ export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConverterComponent as S, OpenAPIGeneratorGenerateOptions as a, SchemaConvertOptions as c, SchemaConverter as d };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/openapi",
3
3
  "type": "module",
4
- "version": "0.0.0-next.eaf61c7",
4
+ "version": "0.0.0-next.eb3d98a",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -50,16 +50,16 @@
50
50
  ],
51
51
  "dependencies": {
52
52
  "json-schema-typed": "^8.0.1",
53
- "rou3": "^0.6.0",
54
- "@orpc/client": "0.0.0-next.eaf61c7",
55
- "@orpc/openapi-client": "0.0.0-next.eaf61c7",
56
- "@orpc/server": "0.0.0-next.eaf61c7",
57
- "@orpc/contract": "0.0.0-next.eaf61c7",
58
- "@orpc/standard-server": "0.0.0-next.eaf61c7",
59
- "@orpc/shared": "0.0.0-next.eaf61c7"
53
+ "rou3": "^0.7.3",
54
+ "@orpc/client": "0.0.0-next.eb3d98a",
55
+ "@orpc/contract": "0.0.0-next.eb3d98a",
56
+ "@orpc/openapi-client": "0.0.0-next.eb3d98a",
57
+ "@orpc/server": "0.0.0-next.eb3d98a",
58
+ "@orpc/shared": "0.0.0-next.eb3d98a",
59
+ "@orpc/standard-server": "0.0.0-next.eb3d98a"
60
60
  },
61
61
  "devDependencies": {
62
- "zod": "^3.25.57"
62
+ "zod": "^4.0.5"
63
63
  },
64
64
  "scripts": {
65
65
  "build": "unbuild",
@@ -1,12 +0,0 @@
1
- import { StandardOpenAPIJsonSerializerOptions } from '@orpc/openapi-client/standard';
2
- import { Context, Router } from '@orpc/server';
3
- import { StandardHandlerOptions, StandardHandler } from '@orpc/server/standard';
4
-
5
- interface StandardOpenAPIHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, StandardOpenAPIJsonSerializerOptions {
6
- }
7
- declare class StandardOpenAPIHandler<T extends Context> extends StandardHandler<T> {
8
- constructor(router: Router<any, T>, options: NoInfer<StandardOpenAPIHandlerOptions<T>>);
9
- }
10
-
11
- export { StandardOpenAPIHandler as a };
12
- export type { StandardOpenAPIHandlerOptions as S };
@@ -1,12 +0,0 @@
1
- import { StandardOpenAPIJsonSerializerOptions } from '@orpc/openapi-client/standard';
2
- import { Context, Router } from '@orpc/server';
3
- import { StandardHandlerOptions, StandardHandler } from '@orpc/server/standard';
4
-
5
- interface StandardOpenAPIHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, StandardOpenAPIJsonSerializerOptions {
6
- }
7
- declare class StandardOpenAPIHandler<T extends Context> extends StandardHandler<T> {
8
- constructor(router: Router<any, T>, options: NoInfer<StandardOpenAPIHandlerOptions<T>>);
9
- }
10
-
11
- export { StandardOpenAPIHandler as a };
12
- export type { StandardOpenAPIHandlerOptions as S };
@@ -1,52 +0,0 @@
1
- import { AnySchema, OpenAPI, AnyContractProcedure, AnyContractRouter } from '@orpc/contract';
2
- import { StandardOpenAPIJsonSerializerOptions } from '@orpc/openapi-client/standard';
3
- import { AnyProcedure, AnyRouter } from '@orpc/server';
4
- import { Promisable } from '@orpc/shared';
5
- import { JSONSchema } from 'json-schema-typed/draft-2020-12';
6
-
7
- interface SchemaConvertOptions {
8
- strategy: 'input' | 'output';
9
- }
10
- interface SchemaConverter {
11
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: JSONSchema]>;
12
- }
13
- interface ConditionalSchemaConverter extends SchemaConverter {
14
- condition(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<boolean>;
15
- }
16
- declare class CompositeSchemaConverter implements SchemaConverter {
17
- private readonly converters;
18
- constructor(converters: ConditionalSchemaConverter[]);
19
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promise<[required: boolean, jsonSchema: JSONSchema]>;
20
- }
21
-
22
- interface OpenAPIGeneratorOptions extends StandardOpenAPIJsonSerializerOptions {
23
- schemaConverters?: ConditionalSchemaConverter[];
24
- }
25
- interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPI.Document, 'openapi'>> {
26
- /**
27
- * Exclude procedures from the OpenAPI specification.
28
- *
29
- * @default () => false
30
- */
31
- exclude?: (procedure: AnyProcedure | AnyContractProcedure, path: readonly string[]) => boolean;
32
- }
33
- /**
34
- * The generator that converts oRPC routers/contracts to OpenAPI specifications.
35
- *
36
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
37
- */
38
- declare class OpenAPIGenerator {
39
- #private;
40
- private readonly serializer;
41
- private readonly converter;
42
- constructor(options?: OpenAPIGeneratorOptions);
43
- /**
44
- * Generates OpenAPI specifications from oRPC routers/contracts.
45
- *
46
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
47
- */
48
- generate(router: AnyContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
49
- }
50
-
51
- export { OpenAPIGenerator as b, CompositeSchemaConverter as d };
52
- export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConvertOptions as S, OpenAPIGeneratorGenerateOptions as a, SchemaConverter as c };
@@ -1,52 +0,0 @@
1
- import { AnySchema, OpenAPI, AnyContractProcedure, AnyContractRouter } from '@orpc/contract';
2
- import { StandardOpenAPIJsonSerializerOptions } from '@orpc/openapi-client/standard';
3
- import { AnyProcedure, AnyRouter } from '@orpc/server';
4
- import { Promisable } from '@orpc/shared';
5
- import { JSONSchema } from 'json-schema-typed/draft-2020-12';
6
-
7
- interface SchemaConvertOptions {
8
- strategy: 'input' | 'output';
9
- }
10
- interface SchemaConverter {
11
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: JSONSchema]>;
12
- }
13
- interface ConditionalSchemaConverter extends SchemaConverter {
14
- condition(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<boolean>;
15
- }
16
- declare class CompositeSchemaConverter implements SchemaConverter {
17
- private readonly converters;
18
- constructor(converters: ConditionalSchemaConverter[]);
19
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promise<[required: boolean, jsonSchema: JSONSchema]>;
20
- }
21
-
22
- interface OpenAPIGeneratorOptions extends StandardOpenAPIJsonSerializerOptions {
23
- schemaConverters?: ConditionalSchemaConverter[];
24
- }
25
- interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPI.Document, 'openapi'>> {
26
- /**
27
- * Exclude procedures from the OpenAPI specification.
28
- *
29
- * @default () => false
30
- */
31
- exclude?: (procedure: AnyProcedure | AnyContractProcedure, path: readonly string[]) => boolean;
32
- }
33
- /**
34
- * The generator that converts oRPC routers/contracts to OpenAPI specifications.
35
- *
36
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
37
- */
38
- declare class OpenAPIGenerator {
39
- #private;
40
- private readonly serializer;
41
- private readonly converter;
42
- constructor(options?: OpenAPIGeneratorOptions);
43
- /**
44
- * Generates OpenAPI specifications from oRPC routers/contracts.
45
- *
46
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
47
- */
48
- generate(router: AnyContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
49
- }
50
-
51
- export { OpenAPIGenerator as b, CompositeSchemaConverter as d };
52
- export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConvertOptions as S, OpenAPIGeneratorGenerateOptions as a, SchemaConverter as c };