@orpc/openapi 0.0.0-next.3d9f498 → 0.0.0-next.3e05997

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
@@ -49,14 +49,12 @@ You can find the full documentation [here](https://orpc.unnoq.com).
49
49
  - [@orpc/contract](https://www.npmjs.com/package/@orpc/contract): Build your API contract.
50
50
  - [@orpc/server](https://www.npmjs.com/package/@orpc/server): Build your API or implement API contract.
51
51
  - [@orpc/client](https://www.npmjs.com/package/@orpc/client): Consume your API on the client with type-safety.
52
- - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with NestJS.
52
+ - [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Generate OpenAPI specs and handle OpenAPI requests.
53
+ - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with [NestJS](https://nestjs.com/).
53
54
  - [@orpc/react](https://www.npmjs.com/package/@orpc/react): Utilities for integrating oRPC with React and React Server Actions.
54
- - [@orpc/react-query](https://www.npmjs.com/package/@orpc/react-query): Integration with [React Query](https://tanstack.com/query/latest/docs/framework/react/overview).
55
- - [@orpc/vue-query](https://www.npmjs.com/package/@orpc/vue-query): Integration with [Vue Query](https://tanstack.com/query/latest/docs/framework/vue/overview).
56
- - [@orpc/solid-query](https://www.npmjs.com/package/@orpc/solid-query): Integration with [Solid Query](https://tanstack.com/query/latest/docs/framework/solid/overview).
57
- - [@orpc/svelte-query](https://www.npmjs.com/package/@orpc/svelte-query): Integration with [Svelte Query](https://tanstack.com/query/latest/docs/framework/svelte/overview).
55
+ - [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): [TanStack Query](https://tanstack.com/query/latest) integration.
58
56
  - [@orpc/vue-colada](https://www.npmjs.com/package/@orpc/vue-colada): Integration with [Pinia Colada](https://pinia-colada.esm.dev/).
59
- - [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Generate OpenAPI specs and handle OpenAPI requests.
57
+ - [@orpc/hey-api](https://www.npmjs.com/package/@orpc/hey-api): [Hey API](https://heyapi.dev/) integration.
60
58
  - [@orpc/zod](https://www.npmjs.com/package/@orpc/zod): More schemas that [Zod](https://zod.dev/) doesn't support yet.
61
59
  - [@orpc/valibot](https://www.npmjs.com/package/@orpc/valibot): OpenAPI spec generation from [Valibot](https://valibot.dev/).
62
60
  - [@orpc/arktype](https://www.npmjs.com/package/@orpc/arktype): OpenAPI spec generation from [ArkType](https://arktype.io/).
@@ -0,0 +1,17 @@
1
+ import { Context, Router } from '@orpc/server';
2
+ import { AwsLambdaHandler, AwsLambdaHandlerOptions } from '@orpc/server/aws-lambda';
3
+ import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.mjs';
4
+ import '@orpc/openapi-client/standard';
5
+ import '@orpc/server/standard';
6
+
7
+ /**
8
+ * OpenAPI Handler for AWS Lambda.
9
+ *
10
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
11
+ * @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
12
+ */
13
+ declare class experimental_OpenAPIHandler<T extends Context> extends AwsLambdaHandler<T> {
14
+ constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & AwsLambdaHandlerOptions>);
15
+ }
16
+
17
+ export { experimental_OpenAPIHandler };
@@ -0,0 +1,17 @@
1
+ import { Context, Router } from '@orpc/server';
2
+ import { AwsLambdaHandler, AwsLambdaHandlerOptions } from '@orpc/server/aws-lambda';
3
+ import { S as StandardOpenAPIHandlerOptions } from '../../shared/openapi.D3j94c9n.js';
4
+ import '@orpc/openapi-client/standard';
5
+ import '@orpc/server/standard';
6
+
7
+ /**
8
+ * OpenAPI Handler for AWS Lambda.
9
+ *
10
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
11
+ * @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
12
+ */
13
+ declare class experimental_OpenAPIHandler<T extends Context> extends AwsLambdaHandler<T> {
14
+ constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & AwsLambdaHandlerOptions>);
15
+ }
16
+
17
+ export { experimental_OpenAPIHandler };
@@ -0,0 +1,18 @@
1
+ import { AwsLambdaHandler } from '@orpc/server/aws-lambda';
2
+ import '@orpc/client';
3
+ import '@orpc/contract';
4
+ import '@orpc/shared';
5
+ import { a as StandardOpenAPIHandler } from '../../shared/openapi.C_UtQ8Us.mjs';
6
+ import '@orpc/client/standard';
7
+ import '@orpc/server';
8
+ import 'rou3';
9
+ import '@orpc/openapi-client/standard';
10
+ import '@orpc/server/standard';
11
+
12
+ class experimental_OpenAPIHandler extends AwsLambdaHandler {
13
+ constructor(router, options = {}) {
14
+ super(new StandardOpenAPIHandler(router, options), options);
15
+ }
16
+ }
17
+
18
+ export { experimental_OpenAPIHandler };
package/dist/index.d.mts CHANGED
@@ -1,16 +1,15 @@
1
- import { AnyContractProcedure } from '@orpc/contract';
2
- import { OpenAPIV3_1 } from 'openapi-types';
3
- export { OpenAPIV3_1 as OpenAPI } from 'openapi-types';
4
- 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.CwdCLgSU.mjs';
1
+ import { OpenAPI, AnyContractProcedure } from '@orpc/contract';
2
+ export { OpenAPI } from '@orpc/contract';
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.DYi1fARS.mjs';
5
4
  import { HTTPPath, HTTPMethod } from '@orpc/client';
6
5
  import { JSONSchema } from 'json-schema-typed/draft-2020-12';
7
- export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
6
+ export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from 'json-schema-typed/draft-2020-12';
8
7
  import { JsonifiedClient } from '@orpc/openapi-client';
9
8
  import { AnyRouter, ClientContext, Lazyable, CreateProcedureClientOptions, InferRouterInitialContext, Schema, ErrorMap, Meta, RouterClient } from '@orpc/server';
10
9
  import { MaybeOptionalOptions } from '@orpc/shared';
11
10
  import '@orpc/openapi-client/standard';
12
11
 
13
- type OverrideOperationValue = Partial<OpenAPIV3_1.OperationObject> | ((current: OpenAPIV3_1.OperationObject, procedure: AnyContractProcedure) => OpenAPIV3_1.OperationObject);
12
+ type OverrideOperationValue = Partial<OpenAPI.OperationObject> | ((current: OpenAPI.OperationObject, procedure: AnyContractProcedure) => OpenAPI.OperationObject);
14
13
  /**
15
14
  * Customize The Operation Object by proxy an error map item or a middleware.
16
15
  *
@@ -18,7 +17,7 @@ type OverrideOperationValue = Partial<OpenAPIV3_1.OperationObject> | ((current:
18
17
  */
19
18
  declare function customOpenAPIOperation<T extends object>(o: T, extend: OverrideOperationValue): T;
20
19
  declare function getCustomOpenAPIOperation(o: object): OverrideOperationValue | undefined;
21
- declare function applyCustomOpenAPIOperation(operation: OpenAPIV3_1.OperationObject, contract: AnyContractProcedure): OpenAPIV3_1.OperationObject;
20
+ declare function applyCustomOpenAPIOperation(operation: OpenAPI.OperationObject, contract: AnyContractProcedure): OpenAPI.OperationObject;
22
21
 
23
22
  /**
24
23
  * @internal
@@ -49,15 +48,15 @@ declare function toOpenAPIMethod(method: HTTPMethod): Lowercase<HTTPMethod>;
49
48
  /**
50
49
  * @internal
51
50
  */
52
- declare function toOpenAPIContent(schema: JSONSchema): Record<string, OpenAPIV3_1.MediaTypeObject>;
51
+ declare function toOpenAPIContent(schema: JSONSchema): Record<string, OpenAPI.MediaTypeObject>;
53
52
  /**
54
53
  * @internal
55
54
  */
56
- declare function toOpenAPIEventIteratorContent([yieldsRequired, yieldsSchema]: [boolean, JSONSchema], [returnsRequired, returnsSchema]: [boolean, JSONSchema]): Record<string, OpenAPIV3_1.MediaTypeObject>;
55
+ declare function toOpenAPIEventIteratorContent([yieldsRequired, yieldsSchema]: [boolean, JSONSchema], [returnsRequired, returnsSchema]: [boolean, JSONSchema]): Record<string, OpenAPI.MediaTypeObject>;
57
56
  /**
58
57
  * @internal
59
58
  */
60
- declare function toOpenAPIParameters(schema: ObjectSchema, parameterIn: 'path' | 'query' | 'header' | 'cookie'): OpenAPIV3_1.ParameterObject[];
59
+ declare function toOpenAPIParameters(schema: ObjectSchema, parameterIn: 'path' | 'query' | 'header' | 'cookie'): OpenAPI.ParameterObject[];
61
60
  /**
62
61
  * @internal
63
62
  */
@@ -65,7 +64,8 @@ declare function checkParamsSchema(schema: ObjectSchema, params: string[]): bool
65
64
  /**
66
65
  * @internal
67
66
  */
68
- declare function toOpenAPISchema(schema: JSONSchema): OpenAPIV3_1.SchemaObject & object;
67
+ declare function toOpenAPISchema(schema: JSONSchema): OpenAPI.SchemaObject & object;
68
+ declare function resolveOpenAPIJsonSchemaRef(doc: OpenAPI.Document, schema: JSONSchema): JSONSchema;
69
69
 
70
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>>;
71
71
 
@@ -96,10 +96,15 @@ declare function applySchemaOptionality(required: boolean, schema: JSONSchema):
96
96
  * If the schema is not a simple union or is a base type, it's returned as a single-element array.
97
97
  */
98
98
  declare function expandUnionSchema(schema: JSONSchema): JSONSchema[];
99
+ declare function expandArrayableSchema(schema: JSONSchema): undefined | [items: JSONSchema, array: JSONSchema & {
100
+ type: 'array';
101
+ items?: JSONSchema;
102
+ }];
103
+ declare function isPrimitiveSchema(schema: JSONSchema): boolean;
99
104
 
100
105
  declare const oo: {
101
106
  spec: typeof customOpenAPIOperation;
102
107
  };
103
108
 
104
- export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, expandUnionSchema, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, 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 };
105
110
  export type { FileSchema, ObjectSchema, OverrideOperationValue };
package/dist/index.d.ts CHANGED
@@ -1,16 +1,15 @@
1
- import { AnyContractProcedure } from '@orpc/contract';
2
- import { OpenAPIV3_1 } from 'openapi-types';
3
- export { OpenAPIV3_1 as OpenAPI } from 'openapi-types';
4
- 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.CwdCLgSU.js';
1
+ import { OpenAPI, AnyContractProcedure } from '@orpc/contract';
2
+ export { OpenAPI } from '@orpc/contract';
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.DYi1fARS.js';
5
4
  import { HTTPPath, HTTPMethod } from '@orpc/client';
6
5
  import { JSONSchema } from 'json-schema-typed/draft-2020-12';
7
- export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
6
+ export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from 'json-schema-typed/draft-2020-12';
8
7
  import { JsonifiedClient } from '@orpc/openapi-client';
9
8
  import { AnyRouter, ClientContext, Lazyable, CreateProcedureClientOptions, InferRouterInitialContext, Schema, ErrorMap, Meta, RouterClient } from '@orpc/server';
10
9
  import { MaybeOptionalOptions } from '@orpc/shared';
11
10
  import '@orpc/openapi-client/standard';
12
11
 
13
- type OverrideOperationValue = Partial<OpenAPIV3_1.OperationObject> | ((current: OpenAPIV3_1.OperationObject, procedure: AnyContractProcedure) => OpenAPIV3_1.OperationObject);
12
+ type OverrideOperationValue = Partial<OpenAPI.OperationObject> | ((current: OpenAPI.OperationObject, procedure: AnyContractProcedure) => OpenAPI.OperationObject);
14
13
  /**
15
14
  * Customize The Operation Object by proxy an error map item or a middleware.
16
15
  *
@@ -18,7 +17,7 @@ type OverrideOperationValue = Partial<OpenAPIV3_1.OperationObject> | ((current:
18
17
  */
19
18
  declare function customOpenAPIOperation<T extends object>(o: T, extend: OverrideOperationValue): T;
20
19
  declare function getCustomOpenAPIOperation(o: object): OverrideOperationValue | undefined;
21
- declare function applyCustomOpenAPIOperation(operation: OpenAPIV3_1.OperationObject, contract: AnyContractProcedure): OpenAPIV3_1.OperationObject;
20
+ declare function applyCustomOpenAPIOperation(operation: OpenAPI.OperationObject, contract: AnyContractProcedure): OpenAPI.OperationObject;
22
21
 
23
22
  /**
24
23
  * @internal
@@ -49,15 +48,15 @@ declare function toOpenAPIMethod(method: HTTPMethod): Lowercase<HTTPMethod>;
49
48
  /**
50
49
  * @internal
51
50
  */
52
- declare function toOpenAPIContent(schema: JSONSchema): Record<string, OpenAPIV3_1.MediaTypeObject>;
51
+ declare function toOpenAPIContent(schema: JSONSchema): Record<string, OpenAPI.MediaTypeObject>;
53
52
  /**
54
53
  * @internal
55
54
  */
56
- declare function toOpenAPIEventIteratorContent([yieldsRequired, yieldsSchema]: [boolean, JSONSchema], [returnsRequired, returnsSchema]: [boolean, JSONSchema]): Record<string, OpenAPIV3_1.MediaTypeObject>;
55
+ declare function toOpenAPIEventIteratorContent([yieldsRequired, yieldsSchema]: [boolean, JSONSchema], [returnsRequired, returnsSchema]: [boolean, JSONSchema]): Record<string, OpenAPI.MediaTypeObject>;
57
56
  /**
58
57
  * @internal
59
58
  */
60
- declare function toOpenAPIParameters(schema: ObjectSchema, parameterIn: 'path' | 'query' | 'header' | 'cookie'): OpenAPIV3_1.ParameterObject[];
59
+ declare function toOpenAPIParameters(schema: ObjectSchema, parameterIn: 'path' | 'query' | 'header' | 'cookie'): OpenAPI.ParameterObject[];
61
60
  /**
62
61
  * @internal
63
62
  */
@@ -65,7 +64,8 @@ declare function checkParamsSchema(schema: ObjectSchema, params: string[]): bool
65
64
  /**
66
65
  * @internal
67
66
  */
68
- declare function toOpenAPISchema(schema: JSONSchema): OpenAPIV3_1.SchemaObject & object;
67
+ declare function toOpenAPISchema(schema: JSONSchema): OpenAPI.SchemaObject & object;
68
+ declare function resolveOpenAPIJsonSchemaRef(doc: OpenAPI.Document, schema: JSONSchema): JSONSchema;
69
69
 
70
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>>;
71
71
 
@@ -96,10 +96,15 @@ declare function applySchemaOptionality(required: boolean, schema: JSONSchema):
96
96
  * If the schema is not a simple union or is a base type, it's returned as a single-element array.
97
97
  */
98
98
  declare function expandUnionSchema(schema: JSONSchema): JSONSchema[];
99
+ declare function expandArrayableSchema(schema: JSONSchema): undefined | [items: JSONSchema, array: JSONSchema & {
100
+ type: 'array';
101
+ items?: JSONSchema;
102
+ }];
103
+ declare function isPrimitiveSchema(schema: JSONSchema): boolean;
99
104
 
100
105
  declare const oo: {
101
106
  spec: typeof customOpenAPIOperation;
102
107
  };
103
108
 
104
- export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, expandUnionSchema, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, 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 };
105
110
  export type { FileSchema, ObjectSchema, OverrideOperationValue };
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { c as customOpenAPIOperation } from './shared/openapi.PDTdnRIU.mjs';
2
- export { C as CompositeSchemaConverter, L as LOGIC_KEYWORDS, O as OpenAPIGenerator, a as applyCustomOpenAPIOperation, n as applySchemaOptionality, h as checkParamsSchema, o as expandUnionSchema, m as filterSchemaBranches, g as getCustomOpenAPIOperation, l as isAnySchema, j as isFileSchema, k as isObjectSchema, s as separateObjectSchema, d as toOpenAPIContent, e as toOpenAPIEventIteratorContent, b as toOpenAPIMethod, f as toOpenAPIParameters, t as toOpenAPIPath, i as toOpenAPISchema } from './shared/openapi.PDTdnRIU.mjs';
1
+ import { c as customOpenAPIOperation } from './shared/openapi.C_3bk7bB.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.C_3bk7bB.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';
6
6
  import { resolveMaybeOptionalOptions } from '@orpc/shared';
7
- export { ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
7
+ export { ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from 'json-schema-typed/draft-2020-12';
8
8
  import '@orpc/client/standard';
9
9
  import '@orpc/contract';
10
10
 
@@ -1,9 +1,8 @@
1
+ import { OpenAPI } from '@orpc/contract';
1
2
  import { Context, HTTPPath, Router } from '@orpc/server';
2
3
  import { StandardHandlerInterceptorOptions, StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
3
4
  import { Value, Promisable } from '@orpc/shared';
4
- import { OpenAPIV3_1 } from 'openapi-types';
5
- import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.CwdCLgSU.mjs';
6
- import '@orpc/contract';
5
+ import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.DYi1fARS.mjs';
7
6
  import '@orpc/openapi-client/standard';
8
7
  import 'json-schema-typed/draft-2020-12';
9
8
 
@@ -50,7 +49,7 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
50
49
  /**
51
50
  * Override function to generate the full HTML for the docs page.
52
51
  */
53
- renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPIV3_1.Document) => string;
52
+ renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPI.Document) => string;
54
53
  }
55
54
  declare class OpenAPIReferencePlugin<T extends Context> implements StandardHandlerPlugin<T> {
56
55
  private readonly generator;
@@ -1,9 +1,8 @@
1
+ import { OpenAPI } from '@orpc/contract';
1
2
  import { Context, HTTPPath, Router } from '@orpc/server';
2
3
  import { StandardHandlerInterceptorOptions, StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
3
4
  import { Value, Promisable } from '@orpc/shared';
4
- import { OpenAPIV3_1 } from 'openapi-types';
5
- import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.CwdCLgSU.js';
6
- import '@orpc/contract';
5
+ import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.DYi1fARS.js';
7
6
  import '@orpc/openapi-client/standard';
8
7
  import 'json-schema-typed/draft-2020-12';
9
8
 
@@ -50,7 +49,7 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
50
49
  /**
51
50
  * Override function to generate the full HTML for the docs page.
52
51
  */
53
- renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPIV3_1.Document) => string;
52
+ renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPI.Document) => string;
54
53
  }
55
54
  declare class OpenAPIReferencePlugin<T extends Context> implements StandardHandlerPlugin<T> {
56
55
  private readonly generator;
@@ -1,5 +1,5 @@
1
1
  import { stringifyJSON, once, value } from '@orpc/shared';
2
- import { O as OpenAPIGenerator } from '../shared/openapi.PDTdnRIU.mjs';
2
+ import { O as OpenAPIGenerator } from '../shared/openapi.C_3bk7bB.mjs';
3
3
  import '@orpc/client';
4
4
  import '@orpc/client/standard';
5
5
  import '@orpc/contract';
@@ -3,8 +3,8 @@ 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, findDeepMatches, toArray, clone, stringifyJSON } from '@orpc/shared';
7
- import 'json-schema-typed/draft-2020-12';
6
+ import { isObject, stringifyJSON, findDeepMatches, toArray, clone } from '@orpc/shared';
7
+ import { TypeName } from 'json-schema-typed/draft-2020-12';
8
8
 
9
9
  const OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
10
10
  function customOpenAPIOperation(o, extend) {
@@ -196,6 +196,45 @@ function expandUnionSchema(schema) {
196
196
  }
197
197
  return [schema];
198
198
  }
199
+ function expandArrayableSchema(schema) {
200
+ const schemas = expandUnionSchema(schema);
201
+ if (schemas.length !== 2) {
202
+ return void 0;
203
+ }
204
+ const arraySchema = schemas.find(
205
+ (s) => typeof s === "object" && s.type === "array" && Object.keys(s).filter((k) => LOGIC_KEYWORDS.includes(k)).every((k) => k === "type" || k === "items")
206
+ );
207
+ if (arraySchema === void 0) {
208
+ return void 0;
209
+ }
210
+ const items1 = arraySchema.items;
211
+ const items2 = schemas.find((s) => s !== arraySchema);
212
+ if (stringifyJSON(items1) !== stringifyJSON(items2)) {
213
+ return void 0;
214
+ }
215
+ return [items2, arraySchema];
216
+ }
217
+ const PRIMITIVE_SCHEMA_TYPES = /* @__PURE__ */ new Set([
218
+ TypeName.String,
219
+ TypeName.Number,
220
+ TypeName.Integer,
221
+ TypeName.Boolean,
222
+ TypeName.Null
223
+ ]);
224
+ function isPrimitiveSchema(schema) {
225
+ return expandUnionSchema(schema).every((s) => {
226
+ if (typeof s === "boolean") {
227
+ return false;
228
+ }
229
+ if (typeof s.type === "string" && PRIMITIVE_SCHEMA_TYPES.has(s.type)) {
230
+ return true;
231
+ }
232
+ if (s.const !== void 0) {
233
+ return true;
234
+ }
235
+ return false;
236
+ });
237
+ }
199
238
 
200
239
  function toOpenAPIPath(path) {
201
240
  return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/{$1}");
@@ -268,13 +307,26 @@ function toOpenAPIParameters(schema, parameterIn) {
268
307
  const parameters = [];
269
308
  for (const key in schema.properties) {
270
309
  const keySchema = schema.properties[key];
310
+ let isDeepObjectStyle = true;
311
+ if (parameterIn !== "query") {
312
+ isDeepObjectStyle = false;
313
+ } else if (isPrimitiveSchema(keySchema)) {
314
+ isDeepObjectStyle = false;
315
+ } else {
316
+ const [item] = expandArrayableSchema(keySchema) ?? [];
317
+ if (item !== void 0 && isPrimitiveSchema(item)) {
318
+ isDeepObjectStyle = false;
319
+ }
320
+ }
271
321
  parameters.push({
272
322
  name: key,
273
323
  in: parameterIn,
274
324
  required: schema.required?.includes(key),
275
- style: parameterIn === "query" ? "deepObject" : void 0,
276
- explode: parameterIn === "query" ? true : void 0,
277
- schema: toOpenAPISchema(keySchema)
325
+ schema: toOpenAPISchema(keySchema),
326
+ style: isDeepObjectStyle ? "deepObject" : void 0,
327
+ explode: isDeepObjectStyle ? true : void 0,
328
+ allowEmptyValue: parameterIn === "query" ? true : void 0,
329
+ allowReserved: parameterIn === "query" ? true : void 0
278
330
  });
279
331
  }
280
332
  return parameters;
@@ -293,6 +345,15 @@ function checkParamsSchema(schema, params) {
293
345
  function toOpenAPISchema(schema) {
294
346
  return schema === true ? {} : schema === false ? { not: {} } : schema;
295
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
+ }
296
357
 
297
358
  class CompositeSchemaConverter {
298
359
  converters;
@@ -329,8 +390,10 @@ class OpenAPIGenerator {
329
390
  ...clone(options),
330
391
  info: options.info ?? { title: "API Reference", version: "0.0.0" },
331
392
  openapi: "3.1.1",
332
- exclude: void 0
393
+ exclude: void 0,
394
+ commonSchemas: void 0
333
395
  };
396
+ const baseSchemaConvertOptions = await this.#resolveCommonSchemas(doc, options.commonSchemas);
334
397
  const contracts = [];
335
398
  await resolveContractProcedures({ path: [], router }, ({ contract, path }) => {
336
399
  if (!exclude(contract, path)) {
@@ -344,16 +407,21 @@ class OpenAPIGenerator {
344
407
  const def = contract["~orpc"];
345
408
  const method = toOpenAPIMethod(fallbackContractConfig("defaultMethod", def.route.method));
346
409
  const httpPath = toOpenAPIPath(def.route.path ?? toHttpPath(path));
347
- const operationObjectRef = {
348
- operationId,
349
- summary: def.route.summary,
350
- description: def.route.description,
351
- deprecated: def.route.deprecated,
352
- tags: def.route.tags?.map((tag) => tag)
353
- };
354
- await this.#request(operationObjectRef, def);
355
- await this.#successResponse(operationObjectRef, def);
356
- await this.#errorResponse(operationObjectRef, def);
410
+ let operationObjectRef;
411
+ if (def.route.spec !== void 0) {
412
+ operationObjectRef = def.route.spec;
413
+ } else {
414
+ operationObjectRef = {
415
+ operationId,
416
+ summary: def.route.summary,
417
+ description: def.route.description,
418
+ deprecated: def.route.deprecated,
419
+ tags: def.route.tags?.map((tag) => tag)
420
+ };
421
+ await this.#request(doc, operationObjectRef, def, baseSchemaConvertOptions);
422
+ await this.#successResponse(doc, operationObjectRef, def, baseSchemaConvertOptions);
423
+ await this.#errorResponse(operationObjectRef, def, baseSchemaConvertOptions);
424
+ }
357
425
  doc.paths ??= {};
358
426
  doc.paths[httpPath] ??= {};
359
427
  doc.paths[httpPath][method] = applyCustomOpenAPIOperation(operationObjectRef, contract);
@@ -376,22 +444,73 @@ ${errors.join("\n\n")}`
376
444
  }
377
445
  return this.serializer.serialize(doc)[0];
378
446
  }
379
- async #request(ref, def) {
447
+ async #resolveCommonSchemas(doc, commonSchemas) {
448
+ const baseOptions = {};
449
+ if (commonSchemas) {
450
+ baseOptions.components = [];
451
+ for (const key in commonSchemas) {
452
+ const { schema, strategy = "input" } = commonSchemas[key];
453
+ const [required, json] = await this.converter.convert(schema, { strategy });
454
+ const allowedStrategies = [strategy];
455
+ if (strategy === "input") {
456
+ const [outputRequired, outputJson] = await this.converter.convert(schema, { strategy: "output" });
457
+ if (outputRequired === required && stringifyJSON(outputJson) === stringifyJSON(json)) {
458
+ allowedStrategies.push("output");
459
+ }
460
+ } else if (strategy === "output") {
461
+ const [inputRequired, inputJson] = await this.converter.convert(schema, { strategy: "input" });
462
+ if (inputRequired === required && stringifyJSON(inputJson) === stringifyJSON(json)) {
463
+ allowedStrategies.push("input");
464
+ }
465
+ }
466
+ baseOptions.components.push({
467
+ schema,
468
+ required,
469
+ ref: `#/components/schemas/${key}`,
470
+ allowedStrategies
471
+ });
472
+ }
473
+ doc.components ??= {};
474
+ doc.components.schemas ??= {};
475
+ for (const key in commonSchemas) {
476
+ const { schema, strategy = "input" } = commonSchemas[key];
477
+ const [, json] = await this.converter.convert(
478
+ schema,
479
+ {
480
+ ...baseOptions,
481
+ strategy,
482
+ minStructureDepthForRef: 1
483
+ // not allow use $ref for root schemas
484
+ }
485
+ );
486
+ doc.components.schemas[key] = toOpenAPISchema(json);
487
+ }
488
+ }
489
+ return baseOptions;
490
+ }
491
+ async #request(doc, ref, def, baseSchemaConvertOptions) {
380
492
  const method = fallbackContractConfig("defaultMethod", def.route.method);
381
493
  const details = getEventIteratorSchemaDetails(def.inputSchema);
382
494
  if (details) {
383
495
  ref.requestBody = {
384
496
  required: true,
385
497
  content: toOpenAPIEventIteratorContent(
386
- await this.converter.convert(details.yields, { strategy: "input" }),
387
- await this.converter.convert(details.returns, { strategy: "input" })
498
+ await this.converter.convert(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
499
+ await this.converter.convert(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
388
500
  )
389
501
  };
390
502
  return;
391
503
  }
392
504
  const dynamicParams = getDynamicParams(def.route.path)?.map((v) => v.name);
393
505
  const inputStructure = fallbackContractConfig("defaultInputStructure", def.route.inputStructure);
394
- let [required, schema] = await this.converter.convert(def.inputSchema, { strategy: "input" });
506
+ let [required, schema] = await this.converter.convert(
507
+ def.inputSchema,
508
+ {
509
+ ...baseSchemaConvertOptions,
510
+ strategy: "input",
511
+ minStructureDepthForRef: dynamicParams?.length || inputStructure === "detailed" ? 1 : 0
512
+ }
513
+ );
395
514
  if (isAnySchema(schema) && !dynamicParams?.length) {
396
515
  return;
397
516
  }
@@ -434,7 +553,8 @@ ${errors.join("\n\n")}`
434
553
  if (!isObjectSchema(schema)) {
435
554
  throw error;
436
555
  }
437
- if (dynamicParams?.length && (schema.properties?.params === void 0 || !isObjectSchema(schema.properties.params) || !checkParamsSchema(schema.properties.params, dynamicParams))) {
556
+ const resolvedParamSchema = schema.properties?.params !== void 0 ? resolveOpenAPIJsonSchemaRef(doc, schema.properties.params) : void 0;
557
+ if (dynamicParams?.length && (resolvedParamSchema === void 0 || !isObjectSchema(resolvedParamSchema) || !checkParamsSchema(resolvedParamSchema, dynamicParams))) {
438
558
  throw new OpenAPIGeneratorError(
439
559
  'When input structure is "detailed" and path has dynamic params, the "params" schema must be an object with all dynamic params as required.'
440
560
  );
@@ -442,12 +562,13 @@ ${errors.join("\n\n")}`
442
562
  for (const from of ["params", "query", "headers"]) {
443
563
  const fromSchema = schema.properties?.[from];
444
564
  if (fromSchema !== void 0) {
445
- if (!isObjectSchema(fromSchema)) {
565
+ const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, fromSchema);
566
+ if (!isObjectSchema(resolvedSchema)) {
446
567
  throw error;
447
568
  }
448
569
  const parameterIn = from === "params" ? "path" : from === "headers" ? "header" : "query";
449
570
  ref.parameters ??= [];
450
- ref.parameters.push(...toOpenAPIParameters(fromSchema, parameterIn));
571
+ ref.parameters.push(...toOpenAPIParameters(resolvedSchema, parameterIn));
451
572
  }
452
573
  }
453
574
  if (schema.properties?.body !== void 0) {
@@ -457,7 +578,7 @@ ${errors.join("\n\n")}`
457
578
  };
458
579
  }
459
580
  }
460
- async #successResponse(ref, def) {
581
+ async #successResponse(doc, ref, def, baseSchemaConvertOptions) {
461
582
  const outputSchema = def.outputSchema;
462
583
  const status = fallbackContractConfig("defaultSuccessStatus", def.route.successStatus);
463
584
  const description = fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription);
@@ -468,13 +589,20 @@ ${errors.join("\n\n")}`
468
589
  ref.responses[status] = {
469
590
  description,
470
591
  content: toOpenAPIEventIteratorContent(
471
- await this.converter.convert(eventIteratorSchemaDetails.yields, { strategy: "output" }),
472
- await this.converter.convert(eventIteratorSchemaDetails.returns, { strategy: "output" })
592
+ await this.converter.convert(eventIteratorSchemaDetails.yields, { ...baseSchemaConvertOptions, strategy: "output" }),
593
+ await this.converter.convert(eventIteratorSchemaDetails.returns, { ...baseSchemaConvertOptions, strategy: "output" })
473
594
  )
474
595
  };
475
596
  return;
476
597
  }
477
- const [required, json] = await this.converter.convert(outputSchema, { strategy: "output" });
598
+ const [required, json] = await this.converter.convert(
599
+ outputSchema,
600
+ {
601
+ ...baseSchemaConvertOptions,
602
+ strategy: "output",
603
+ minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
604
+ }
605
+ );
478
606
  if (outputStructure === "compact") {
479
607
  ref.responses ??= {};
480
608
  ref.responses[status] = {
@@ -501,11 +629,12 @@ ${errors.join("\n\n")}`
501
629
  let schemaStatus;
502
630
  let schemaDescription;
503
631
  if (item.properties?.status !== void 0) {
504
- 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)) {
632
+ const statusSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.status);
633
+ if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) {
505
634
  throw error;
506
635
  }
507
- schemaStatus = item.properties.status.const;
508
- schemaDescription = item.properties.status.description;
636
+ schemaStatus = statusSchema.const;
637
+ schemaDescription = statusSchema.description;
509
638
  }
510
639
  const itemStatus = schemaStatus ?? status;
511
640
  const itemDescription = schemaDescription ?? description;
@@ -521,16 +650,17 @@ ${errors.join("\n\n")}`
521
650
  description: itemDescription
522
651
  };
523
652
  if (item.properties?.headers !== void 0) {
524
- if (!isObjectSchema(item.properties.headers)) {
653
+ const headersSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.headers);
654
+ if (!isObjectSchema(headersSchema)) {
525
655
  throw error;
526
656
  }
527
- for (const key in item.properties.headers.properties) {
528
- const headerSchema = item.properties.headers.properties[key];
657
+ for (const key in headersSchema.properties) {
658
+ const headerSchema = headersSchema.properties[key];
529
659
  if (headerSchema !== void 0) {
530
660
  ref.responses[itemStatus].headers ??= {};
531
661
  ref.responses[itemStatus].headers[key] = {
532
662
  schema: toOpenAPISchema(headerSchema),
533
- required: item.properties.headers.required?.includes(key)
663
+ required: item.required?.includes("headers") && headersSchema.required?.includes(key)
534
664
  };
535
665
  }
536
666
  }
@@ -542,7 +672,7 @@ ${errors.join("\n\n")}`
542
672
  }
543
673
  }
544
674
  }
545
- async #errorResponse(ref, def) {
675
+ async #errorResponse(ref, def, baseSchemaConvertOptions) {
546
676
  const errorMap = def.errorMap;
547
677
  const errors = {};
548
678
  for (const code in errorMap) {
@@ -552,7 +682,7 @@ ${errors.join("\n\n")}`
552
682
  }
553
683
  const status = fallbackORPCErrorStatus(code, config.status);
554
684
  const message = fallbackORPCErrorMessage(code, config.message);
555
- const [dataRequired, dataSchema] = await this.converter.convert(config.data, { strategy: "output" });
685
+ const [dataRequired, dataSchema] = await this.converter.convert(config.data, { ...baseSchemaConvertOptions, strategy: "output" });
556
686
  errors[status] ??= [];
557
687
  errors[status].push({
558
688
  type: "object",
@@ -592,4 +722,4 @@ ${errors.join("\n\n")}`
592
722
  }
593
723
  }
594
724
 
595
- 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, separateObjectSchema as s, toOpenAPIPath as t };
725
+ 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,98 @@
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 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: 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
+ * @default () => false
48
+ */
49
+ exclude?: (procedure: AnyProcedure | AnyContractProcedure, path: readonly string[]) => boolean;
50
+ /**
51
+ * Common schemas to be used for $ref resolution.
52
+ */
53
+ commonSchemas?: Record<string, {
54
+ /**
55
+ * Determines which schema definition to use when input and output schemas differ.
56
+ * This is needed because some schemas transform data differently between input and output,
57
+ * making it impossible to use a single $ref for both cases.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * // This schema transforms a string input into a number output
62
+ * const Schema = z.string()
63
+ * .transform(v => Number(v))
64
+ * .pipe(z.number())
65
+ *
66
+ * // Input schema: { type: 'string' }
67
+ * // Output schema: { type: 'number' }
68
+ * ```
69
+ *
70
+ * When schemas differ between input and output, you must explicitly choose
71
+ * which version to use for the OpenAPI specification.
72
+ *
73
+ * @default 'input' - Uses the input schema definition by default
74
+ */
75
+ strategy?: SchemaConvertOptions['strategy'];
76
+ schema: AnySchema;
77
+ }>;
78
+ }
79
+ /**
80
+ * The generator that converts oRPC routers/contracts to OpenAPI specifications.
81
+ *
82
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
83
+ */
84
+ declare class OpenAPIGenerator {
85
+ #private;
86
+ private readonly serializer;
87
+ private readonly converter;
88
+ constructor(options?: OpenAPIGeneratorOptions);
89
+ /**
90
+ * Generates OpenAPI specifications from oRPC routers/contracts.
91
+ *
92
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
93
+ */
94
+ generate(router: AnyContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
95
+ }
96
+
97
+ export { OpenAPIGenerator as b, CompositeSchemaConverter as e };
98
+ export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConverterComponent as S, OpenAPIGeneratorGenerateOptions as a, SchemaConvertOptions as c, SchemaConverter as d };
@@ -0,0 +1,98 @@
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 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: 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
+ * @default () => false
48
+ */
49
+ exclude?: (procedure: AnyProcedure | AnyContractProcedure, path: readonly string[]) => boolean;
50
+ /**
51
+ * Common schemas to be used for $ref resolution.
52
+ */
53
+ commonSchemas?: Record<string, {
54
+ /**
55
+ * Determines which schema definition to use when input and output schemas differ.
56
+ * This is needed because some schemas transform data differently between input and output,
57
+ * making it impossible to use a single $ref for both cases.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * // This schema transforms a string input into a number output
62
+ * const Schema = z.string()
63
+ * .transform(v => Number(v))
64
+ * .pipe(z.number())
65
+ *
66
+ * // Input schema: { type: 'string' }
67
+ * // Output schema: { type: 'number' }
68
+ * ```
69
+ *
70
+ * When schemas differ between input and output, you must explicitly choose
71
+ * which version to use for the OpenAPI specification.
72
+ *
73
+ * @default 'input' - Uses the input schema definition by default
74
+ */
75
+ strategy?: SchemaConvertOptions['strategy'];
76
+ schema: AnySchema;
77
+ }>;
78
+ }
79
+ /**
80
+ * The generator that converts oRPC routers/contracts to OpenAPI specifications.
81
+ *
82
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
83
+ */
84
+ declare class OpenAPIGenerator {
85
+ #private;
86
+ private readonly serializer;
87
+ private readonly converter;
88
+ constructor(options?: OpenAPIGeneratorOptions);
89
+ /**
90
+ * Generates OpenAPI specifications from oRPC routers/contracts.
91
+ *
92
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
93
+ */
94
+ generate(router: AnyContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
95
+ }
96
+
97
+ export { OpenAPIGenerator as b, CompositeSchemaConverter as e };
98
+ 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.3d9f498",
4
+ "version": "0.0.0-next.3e05997",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -38,6 +38,11 @@
38
38
  "types": "./dist/adapters/node/index.d.mts",
39
39
  "import": "./dist/adapters/node/index.mjs",
40
40
  "default": "./dist/adapters/node/index.mjs"
41
+ },
42
+ "./aws-lambda": {
43
+ "types": "./dist/adapters/aws-lambda/index.d.mts",
44
+ "import": "./dist/adapters/aws-lambda/index.mjs",
45
+ "default": "./dist/adapters/aws-lambda/index.mjs"
41
46
  }
42
47
  },
43
48
  "files": [
@@ -45,17 +50,16 @@
45
50
  ],
46
51
  "dependencies": {
47
52
  "json-schema-typed": "^8.0.1",
48
- "openapi-types": "^12.1.3",
49
53
  "rou3": "^0.6.0",
50
- "@orpc/client": "0.0.0-next.3d9f498",
51
- "@orpc/contract": "0.0.0-next.3d9f498",
52
- "@orpc/openapi-client": "0.0.0-next.3d9f498",
53
- "@orpc/shared": "0.0.0-next.3d9f498",
54
- "@orpc/standard-server": "0.0.0-next.3d9f498",
55
- "@orpc/server": "0.0.0-next.3d9f498"
54
+ "@orpc/contract": "0.0.0-next.3e05997",
55
+ "@orpc/client": "0.0.0-next.3e05997",
56
+ "@orpc/server": "0.0.0-next.3e05997",
57
+ "@orpc/shared": "0.0.0-next.3e05997",
58
+ "@orpc/openapi-client": "0.0.0-next.3e05997",
59
+ "@orpc/standard-server": "0.0.0-next.3e05997"
56
60
  },
57
61
  "devDependencies": {
58
- "zod": "^3.25.11"
62
+ "zod": "^3.25.64"
59
63
  },
60
64
  "scripts": {
61
65
  "build": "unbuild",
@@ -1,53 +0,0 @@
1
- import { AnySchema, AnyContractProcedure, AnyContractRouter } from '@orpc/contract';
2
- import { StandardOpenAPIJsonSerializerOptions } from '@orpc/openapi-client/standard';
3
- import { AnyProcedure, AnyRouter } from '@orpc/server';
4
- import { OpenAPIV3_1 } from 'openapi-types';
5
- import { Promisable } from '@orpc/shared';
6
- import { JSONSchema } from 'json-schema-typed/draft-2020-12';
7
-
8
- interface SchemaConvertOptions {
9
- strategy: 'input' | 'output';
10
- }
11
- interface SchemaConverter {
12
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: JSONSchema]>;
13
- }
14
- interface ConditionalSchemaConverter extends SchemaConverter {
15
- condition(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<boolean>;
16
- }
17
- declare class CompositeSchemaConverter implements SchemaConverter {
18
- private readonly converters;
19
- constructor(converters: ConditionalSchemaConverter[]);
20
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promise<[required: boolean, jsonSchema: JSONSchema]>;
21
- }
22
-
23
- interface OpenAPIGeneratorOptions extends StandardOpenAPIJsonSerializerOptions {
24
- schemaConverters?: ConditionalSchemaConverter[];
25
- }
26
- interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPIV3_1.Document, 'openapi'>> {
27
- /**
28
- * Exclude procedures from the OpenAPI specification.
29
- *
30
- * @default () => false
31
- */
32
- exclude?: (procedure: AnyProcedure | AnyContractProcedure, path: readonly string[]) => boolean;
33
- }
34
- /**
35
- * The generator that converts oRPC routers/contracts to OpenAPI specifications.
36
- *
37
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
38
- */
39
- declare class OpenAPIGenerator {
40
- #private;
41
- private readonly serializer;
42
- private readonly converter;
43
- constructor(options?: OpenAPIGeneratorOptions);
44
- /**
45
- * Generates OpenAPI specifications from oRPC routers/contracts.
46
- *
47
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
48
- */
49
- generate(router: AnyContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPIV3_1.Document>;
50
- }
51
-
52
- export { OpenAPIGenerator as b, CompositeSchemaConverter as d };
53
- export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConvertOptions as S, OpenAPIGeneratorGenerateOptions as a, SchemaConverter as c };
@@ -1,53 +0,0 @@
1
- import { AnySchema, AnyContractProcedure, AnyContractRouter } from '@orpc/contract';
2
- import { StandardOpenAPIJsonSerializerOptions } from '@orpc/openapi-client/standard';
3
- import { AnyProcedure, AnyRouter } from '@orpc/server';
4
- import { OpenAPIV3_1 } from 'openapi-types';
5
- import { Promisable } from '@orpc/shared';
6
- import { JSONSchema } from 'json-schema-typed/draft-2020-12';
7
-
8
- interface SchemaConvertOptions {
9
- strategy: 'input' | 'output';
10
- }
11
- interface SchemaConverter {
12
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: JSONSchema]>;
13
- }
14
- interface ConditionalSchemaConverter extends SchemaConverter {
15
- condition(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<boolean>;
16
- }
17
- declare class CompositeSchemaConverter implements SchemaConverter {
18
- private readonly converters;
19
- constructor(converters: ConditionalSchemaConverter[]);
20
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promise<[required: boolean, jsonSchema: JSONSchema]>;
21
- }
22
-
23
- interface OpenAPIGeneratorOptions extends StandardOpenAPIJsonSerializerOptions {
24
- schemaConverters?: ConditionalSchemaConverter[];
25
- }
26
- interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPIV3_1.Document, 'openapi'>> {
27
- /**
28
- * Exclude procedures from the OpenAPI specification.
29
- *
30
- * @default () => false
31
- */
32
- exclude?: (procedure: AnyProcedure | AnyContractProcedure, path: readonly string[]) => boolean;
33
- }
34
- /**
35
- * The generator that converts oRPC routers/contracts to OpenAPI specifications.
36
- *
37
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
38
- */
39
- declare class OpenAPIGenerator {
40
- #private;
41
- private readonly serializer;
42
- private readonly converter;
43
- constructor(options?: OpenAPIGeneratorOptions);
44
- /**
45
- * Generates OpenAPI specifications from oRPC routers/contracts.
46
- *
47
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
48
- */
49
- generate(router: AnyContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPIV3_1.Document>;
50
- }
51
-
52
- export { OpenAPIGenerator as b, CompositeSchemaConverter as d };
53
- export type { ConditionalSchemaConverter as C, OpenAPIGeneratorOptions as O, SchemaConvertOptions as S, OpenAPIGeneratorGenerateOptions as a, SchemaConverter as c };