@orpc/openapi 0.0.0-next.0a9a32d → 0.0.0-next.0ab5adc
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 +5 -1
- package/dist/adapters/aws-lambda/index.d.mts +2 -1
- package/dist/adapters/aws-lambda/index.d.ts +2 -1
- package/dist/adapters/aws-lambda/index.mjs +1 -1
- package/dist/adapters/fastify/index.d.mts +23 -0
- package/dist/adapters/fastify/index.d.ts +23 -0
- package/dist/adapters/fastify/index.mjs +18 -0
- package/dist/adapters/fetch/index.d.mts +7 -3
- package/dist/adapters/fetch/index.d.ts +7 -3
- package/dist/adapters/fetch/index.mjs +1 -1
- package/dist/adapters/node/index.d.mts +7 -3
- package/dist/adapters/node/index.d.ts +7 -3
- package/dist/adapters/node/index.mjs +1 -1
- package/dist/adapters/standard/index.d.mts +7 -16
- package/dist/adapters/standard/index.d.ts +7 -16
- package/dist/adapters/standard/index.mjs +1 -1
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.mjs +2 -2
- package/dist/plugins/index.d.mts +18 -3
- package/dist/plugins/index.d.ts +18 -3
- package/dist/plugins/index.mjs +58 -18
- package/dist/shared/{openapi.CfjfVeBJ.d.mts → openapi.BfNjg7j9.d.mts} +13 -1
- package/dist/shared/{openapi.CfjfVeBJ.d.ts → openapi.BfNjg7j9.d.ts} +13 -1
- package/dist/shared/{openapi.1iT1iSZi.mjs → openapi.CzHcOMxv.mjs} +139 -36
- package/dist/shared/{openapi.BVXcB0u4.mjs → openapi.DIt-Z9W1.mjs} +6 -3
- package/dist/shared/openapi.DwaweYRb.d.mts +54 -0
- package/dist/shared/openapi.DwaweYRb.d.ts +54 -0
- package/package.json +16 -10
- package/dist/shared/openapi.CQmjvnb0.d.mts +0 -31
- package/dist/shared/openapi.CQmjvnb0.d.ts +0 -31
package/README.md
CHANGED
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
<a href="https://discord.gg/TXEbwRBvQn">
|
|
18
18
|
<img alt="Discord" src="https://img.shields.io/discord/1308966753044398161?color=7389D8&label&logo=discord&logoColor=ffffff" />
|
|
19
19
|
</a>
|
|
20
|
+
<a href="https://deepwiki.com/unnoq/orpc">
|
|
21
|
+
<img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki">
|
|
22
|
+
</a>
|
|
20
23
|
</div>
|
|
21
24
|
|
|
22
25
|
<h3 align="center">Typesafe APIs Made Simple 🪄</h3>
|
|
@@ -31,7 +34,7 @@
|
|
|
31
34
|
- **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
|
|
32
35
|
- **📝 Contract-First Development**: Optionally define your API contract before implementation.
|
|
33
36
|
- **🔍 First-Class OpenTelemetry**: Seamlessly integrate with OpenTelemetry for observability.
|
|
34
|
-
- **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), Pinia Colada, and more.
|
|
37
|
+
- **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), SWR, Pinia Colada, and more.
|
|
35
38
|
- **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
|
|
36
39
|
- **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
|
|
37
40
|
- **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
|
|
@@ -54,6 +57,7 @@ You can find the full documentation [here](https://orpc.unnoq.com).
|
|
|
54
57
|
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with [NestJS](https://nestjs.com/).
|
|
55
58
|
- [@orpc/react](https://www.npmjs.com/package/@orpc/react): Utilities for integrating oRPC with React and React Server Actions.
|
|
56
59
|
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): [TanStack Query](https://tanstack.com/query/latest) integration.
|
|
60
|
+
- [@orpc/experimental-react-swr](https://www.npmjs.com/package/@orpc/experimental-react-swr): [SWR](https://swr.vercel.app/) integration.
|
|
57
61
|
- [@orpc/vue-colada](https://www.npmjs.com/package/@orpc/vue-colada): Integration with [Pinia Colada](https://pinia-colada.esm.dev/).
|
|
58
62
|
- [@orpc/hey-api](https://www.npmjs.com/package/@orpc/hey-api): [Hey API](https://heyapi.dev/) integration.
|
|
59
63
|
- [@orpc/zod](https://www.npmjs.com/package/@orpc/zod): More schemas that [Zod](https://zod.dev/) doesn't support yet.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Context, Router } from '@orpc/server';
|
|
2
2
|
import { AwsLambdaHandler, AwsLambdaHandlerOptions } from '@orpc/server/aws-lambda';
|
|
3
|
-
import {
|
|
3
|
+
import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.mjs';
|
|
4
4
|
import '@orpc/openapi-client/standard';
|
|
5
5
|
import '@orpc/server/standard';
|
|
6
6
|
import '@orpc/client';
|
|
7
|
+
import '@orpc/standard-server';
|
|
7
8
|
import '@orpc/shared';
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Context, Router } from '@orpc/server';
|
|
2
2
|
import { AwsLambdaHandler, AwsLambdaHandlerOptions } from '@orpc/server/aws-lambda';
|
|
3
|
-
import {
|
|
3
|
+
import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.js';
|
|
4
4
|
import '@orpc/openapi-client/standard';
|
|
5
5
|
import '@orpc/server/standard';
|
|
6
6
|
import '@orpc/client';
|
|
7
|
+
import '@orpc/standard-server';
|
|
7
8
|
import '@orpc/shared';
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -2,7 +2,7 @@ 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.
|
|
5
|
+
import { a as StandardOpenAPIHandler } from '../../shared/openapi.DIt-Z9W1.mjs';
|
|
6
6
|
import '@orpc/client/standard';
|
|
7
7
|
import '@orpc/server';
|
|
8
8
|
import 'rou3';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Context, Router } from '@orpc/server';
|
|
2
|
+
import { FastifyHandlerOptions, FastifyHandler } from '@orpc/server/fastify';
|
|
3
|
+
import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.mjs';
|
|
4
|
+
import '@orpc/openapi-client/standard';
|
|
5
|
+
import '@orpc/server/standard';
|
|
6
|
+
import '@orpc/client';
|
|
7
|
+
import '@orpc/standard-server';
|
|
8
|
+
import '@orpc/shared';
|
|
9
|
+
|
|
10
|
+
interface OpenAPIHandlerOptions<T extends Context> extends FastifyHandlerOptions<T>, StandardOpenAPIHandlerOptions<T> {
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* OpenAPI Handler for Fastify Server
|
|
14
|
+
*
|
|
15
|
+
* @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
|
|
16
|
+
* @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
|
|
17
|
+
*/
|
|
18
|
+
declare class OpenAPIHandler<T extends Context> extends FastifyHandler<T> {
|
|
19
|
+
constructor(router: Router<any, T>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { OpenAPIHandler };
|
|
23
|
+
export type { OpenAPIHandlerOptions };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Context, Router } from '@orpc/server';
|
|
2
|
+
import { FastifyHandlerOptions, FastifyHandler } from '@orpc/server/fastify';
|
|
3
|
+
import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.js';
|
|
4
|
+
import '@orpc/openapi-client/standard';
|
|
5
|
+
import '@orpc/server/standard';
|
|
6
|
+
import '@orpc/client';
|
|
7
|
+
import '@orpc/standard-server';
|
|
8
|
+
import '@orpc/shared';
|
|
9
|
+
|
|
10
|
+
interface OpenAPIHandlerOptions<T extends Context> extends FastifyHandlerOptions<T>, StandardOpenAPIHandlerOptions<T> {
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* OpenAPI Handler for Fastify Server
|
|
14
|
+
*
|
|
15
|
+
* @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
|
|
16
|
+
* @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
|
|
17
|
+
*/
|
|
18
|
+
declare class OpenAPIHandler<T extends Context> extends FastifyHandler<T> {
|
|
19
|
+
constructor(router: Router<any, T>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { OpenAPIHandler };
|
|
23
|
+
export type { OpenAPIHandlerOptions };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FastifyHandler } from '@orpc/server/fastify';
|
|
2
|
+
import '@orpc/client';
|
|
3
|
+
import '@orpc/contract';
|
|
4
|
+
import '@orpc/shared';
|
|
5
|
+
import { a as StandardOpenAPIHandler } from '../../shared/openapi.DIt-Z9W1.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 OpenAPIHandler extends FastifyHandler {
|
|
13
|
+
constructor(router, options = {}) {
|
|
14
|
+
super(new StandardOpenAPIHandler(router, options), options);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { OpenAPIHandler };
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { Context, Router } from '@orpc/server';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { FetchHandlerOptions, FetchHandler } from '@orpc/server/fetch';
|
|
3
|
+
import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.mjs';
|
|
4
4
|
import '@orpc/openapi-client/standard';
|
|
5
5
|
import '@orpc/server/standard';
|
|
6
6
|
import '@orpc/client';
|
|
7
|
+
import '@orpc/standard-server';
|
|
7
8
|
import '@orpc/shared';
|
|
8
9
|
|
|
10
|
+
interface OpenAPIHandlerOptions<T extends Context> extends FetchHandlerOptions<T>, Omit<StandardOpenAPIHandlerOptions<T>, 'plugins'> {
|
|
11
|
+
}
|
|
9
12
|
/**
|
|
10
13
|
* OpenAPI Handler for Fetch Server
|
|
11
14
|
*
|
|
@@ -13,7 +16,8 @@ import '@orpc/shared';
|
|
|
13
16
|
* @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
|
|
14
17
|
*/
|
|
15
18
|
declare class OpenAPIHandler<T extends Context> extends FetchHandler<T> {
|
|
16
|
-
constructor(router: Router<any, T>, options?: NoInfer<
|
|
19
|
+
constructor(router: Router<any, T>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
export { OpenAPIHandler };
|
|
23
|
+
export type { OpenAPIHandlerOptions };
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { Context, Router } from '@orpc/server';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { FetchHandlerOptions, FetchHandler } from '@orpc/server/fetch';
|
|
3
|
+
import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.js';
|
|
4
4
|
import '@orpc/openapi-client/standard';
|
|
5
5
|
import '@orpc/server/standard';
|
|
6
6
|
import '@orpc/client';
|
|
7
|
+
import '@orpc/standard-server';
|
|
7
8
|
import '@orpc/shared';
|
|
8
9
|
|
|
10
|
+
interface OpenAPIHandlerOptions<T extends Context> extends FetchHandlerOptions<T>, Omit<StandardOpenAPIHandlerOptions<T>, 'plugins'> {
|
|
11
|
+
}
|
|
9
12
|
/**
|
|
10
13
|
* OpenAPI Handler for Fetch Server
|
|
11
14
|
*
|
|
@@ -13,7 +16,8 @@ import '@orpc/shared';
|
|
|
13
16
|
* @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
|
|
14
17
|
*/
|
|
15
18
|
declare class OpenAPIHandler<T extends Context> extends FetchHandler<T> {
|
|
16
|
-
constructor(router: Router<any, T>, options?: NoInfer<
|
|
19
|
+
constructor(router: Router<any, T>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
export { OpenAPIHandler };
|
|
23
|
+
export type { OpenAPIHandlerOptions };
|
|
@@ -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.
|
|
5
|
+
import { a as StandardOpenAPIHandler } from '../../shared/openapi.DIt-Z9W1.mjs';
|
|
6
6
|
import '@orpc/client/standard';
|
|
7
7
|
import '@orpc/server';
|
|
8
8
|
import 'rou3';
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { Context, Router } from '@orpc/server';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { NodeHttpHandlerOptions, NodeHttpHandler } from '@orpc/server/node';
|
|
3
|
+
import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.mjs';
|
|
4
4
|
import '@orpc/openapi-client/standard';
|
|
5
5
|
import '@orpc/server/standard';
|
|
6
6
|
import '@orpc/client';
|
|
7
|
+
import '@orpc/standard-server';
|
|
7
8
|
import '@orpc/shared';
|
|
8
9
|
|
|
10
|
+
interface OpenAPIHandlerOptions<T extends Context> extends NodeHttpHandlerOptions<T>, Omit<StandardOpenAPIHandlerOptions<T>, 'plugins'> {
|
|
11
|
+
}
|
|
9
12
|
/**
|
|
10
13
|
* OpenAPI Handler for Node Server
|
|
11
14
|
*
|
|
@@ -13,7 +16,8 @@ import '@orpc/shared';
|
|
|
13
16
|
* @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
|
|
14
17
|
*/
|
|
15
18
|
declare class OpenAPIHandler<T extends Context> extends NodeHttpHandler<T> {
|
|
16
|
-
constructor(router: Router<any, T>, options?: NoInfer<
|
|
19
|
+
constructor(router: Router<any, T>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
export { OpenAPIHandler };
|
|
23
|
+
export type { OpenAPIHandlerOptions };
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { Context, Router } from '@orpc/server';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { NodeHttpHandlerOptions, NodeHttpHandler } from '@orpc/server/node';
|
|
3
|
+
import { b as StandardOpenAPIHandlerOptions } from '../../shared/openapi.DwaweYRb.js';
|
|
4
4
|
import '@orpc/openapi-client/standard';
|
|
5
5
|
import '@orpc/server/standard';
|
|
6
6
|
import '@orpc/client';
|
|
7
|
+
import '@orpc/standard-server';
|
|
7
8
|
import '@orpc/shared';
|
|
8
9
|
|
|
10
|
+
interface OpenAPIHandlerOptions<T extends Context> extends NodeHttpHandlerOptions<T>, Omit<StandardOpenAPIHandlerOptions<T>, 'plugins'> {
|
|
11
|
+
}
|
|
9
12
|
/**
|
|
10
13
|
* OpenAPI Handler for Node Server
|
|
11
14
|
*
|
|
@@ -13,7 +16,8 @@ import '@orpc/shared';
|
|
|
13
16
|
* @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
|
|
14
17
|
*/
|
|
15
18
|
declare class OpenAPIHandler<T extends Context> extends NodeHttpHandler<T> {
|
|
16
|
-
constructor(router: Router<any, T>, options?: NoInfer<
|
|
19
|
+
constructor(router: Router<any, T>, options?: NoInfer<OpenAPIHandlerOptions<T>>);
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
export { OpenAPIHandler };
|
|
23
|
+
export type { OpenAPIHandlerOptions };
|
|
@@ -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.
|
|
5
|
+
import { a as StandardOpenAPIHandler } from '../../shared/openapi.DIt-Z9W1.mjs';
|
|
6
6
|
import '@orpc/client/standard';
|
|
7
7
|
import '@orpc/server';
|
|
8
8
|
import 'rou3';
|
|
@@ -1,20 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
1
|
+
export { a as StandardOpenAPICodec, S as StandardOpenAPICodecOptions, c as StandardOpenAPIHandler, b as StandardOpenAPIHandlerOptions, e as StandardOpenAPIMatcher, d as StandardOpenAPIMatcherOptions } from '../../shared/openapi.DwaweYRb.mjs';
|
|
2
|
+
import { HTTPPath } from '@orpc/client';
|
|
3
|
+
import '@orpc/openapi-client/standard';
|
|
4
|
+
import '@orpc/server';
|
|
5
|
+
import '@orpc/server/standard';
|
|
6
|
+
import '@orpc/standard-server';
|
|
7
7
|
import '@orpc/shared';
|
|
8
8
|
|
|
9
|
-
declare class StandardOpenAPICodec implements StandardCodec {
|
|
10
|
-
#private;
|
|
11
|
-
private readonly serializer;
|
|
12
|
-
constructor(serializer: StandardOpenAPISerializer);
|
|
13
|
-
decode(request: StandardLazyRequest, params: StandardParams | undefined, procedure: AnyProcedure): Promise<unknown>;
|
|
14
|
-
encode(output: unknown, procedure: AnyProcedure): StandardResponse;
|
|
15
|
-
encodeError(error: ORPCError<any, any>): StandardResponse;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
9
|
/**
|
|
19
10
|
* {@link https://github.com/unjs/rou3}
|
|
20
11
|
*
|
|
@@ -26,4 +17,4 @@ declare function toRou3Pattern(path: HTTPPath): string;
|
|
|
26
17
|
*/
|
|
27
18
|
declare function decodeParams(params: Record<string, string>): Record<string, string>;
|
|
28
19
|
|
|
29
|
-
export {
|
|
20
|
+
export { decodeParams, toRou3Pattern };
|
|
@@ -1,20 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
1
|
+
export { a as StandardOpenAPICodec, S as StandardOpenAPICodecOptions, c as StandardOpenAPIHandler, b as StandardOpenAPIHandlerOptions, e as StandardOpenAPIMatcher, d as StandardOpenAPIMatcherOptions } from '../../shared/openapi.DwaweYRb.js';
|
|
2
|
+
import { HTTPPath } from '@orpc/client';
|
|
3
|
+
import '@orpc/openapi-client/standard';
|
|
4
|
+
import '@orpc/server';
|
|
5
|
+
import '@orpc/server/standard';
|
|
6
|
+
import '@orpc/standard-server';
|
|
7
7
|
import '@orpc/shared';
|
|
8
8
|
|
|
9
|
-
declare class StandardOpenAPICodec implements StandardCodec {
|
|
10
|
-
#private;
|
|
11
|
-
private readonly serializer;
|
|
12
|
-
constructor(serializer: StandardOpenAPISerializer);
|
|
13
|
-
decode(request: StandardLazyRequest, params: StandardParams | undefined, procedure: AnyProcedure): Promise<unknown>;
|
|
14
|
-
encode(output: unknown, procedure: AnyProcedure): StandardResponse;
|
|
15
|
-
encodeError(error: ORPCError<any, any>): StandardResponse;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
9
|
/**
|
|
19
10
|
* {@link https://github.com/unjs/rou3}
|
|
20
11
|
*
|
|
@@ -26,4 +17,4 @@ declare function toRou3Pattern(path: HTTPPath): string;
|
|
|
26
17
|
*/
|
|
27
18
|
declare function decodeParams(params: Record<string, string>): Record<string, string>;
|
|
28
19
|
|
|
29
|
-
export {
|
|
20
|
+
export { 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.
|
|
1
|
+
export { S as StandardOpenAPICodec, a as StandardOpenAPIHandler, b as StandardOpenAPIMatcher, d as decodeParams, t as toRou3Pattern } from '../../shared/openapi.DIt-Z9W1.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 { 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.
|
|
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.BfNjg7j9.mjs';
|
|
4
4
|
import { HTTPPath, HTTPMethod } from '@orpc/client';
|
|
5
5
|
import { JSONSchema } from '@orpc/interop/json-schema-typed/draft-2020-12';
|
|
6
6
|
export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from '@orpc/interop/json-schema-typed/draft-2020-12';
|
|
@@ -66,6 +66,12 @@ declare function checkParamsSchema(schema: ObjectSchema, params: string[]): bool
|
|
|
66
66
|
*/
|
|
67
67
|
declare function toOpenAPISchema(schema: JSONSchema): OpenAPI.SchemaObject & object;
|
|
68
68
|
declare function resolveOpenAPIJsonSchemaRef(doc: OpenAPI.Document, schema: JSONSchema): JSONSchema;
|
|
69
|
+
/**
|
|
70
|
+
* Simplifies composed object JSON Schemas (using anyOf, oneOf, allOf) by flattening nested compositions
|
|
71
|
+
*
|
|
72
|
+
* @warning The result is looser than the original schema and may not fully validate the same data.
|
|
73
|
+
*/
|
|
74
|
+
declare function simplifyComposedObjectJsonSchemasAndRefs(schema: JSONSchema, doc?: OpenAPI.Document): JSONSchema;
|
|
69
75
|
|
|
70
76
|
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
77
|
|
|
@@ -106,5 +112,5 @@ declare const oo: {
|
|
|
106
112
|
spec: typeof customOpenAPIOperation;
|
|
107
113
|
};
|
|
108
114
|
|
|
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 };
|
|
115
|
+
export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, expandArrayableSchema, expandUnionSchema, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, isPrimitiveSchema, oo, resolveOpenAPIJsonSchemaRef, separateObjectSchema, simplifyComposedObjectJsonSchemasAndRefs, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
|
|
110
116
|
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 { 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.
|
|
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.BfNjg7j9.js';
|
|
4
4
|
import { HTTPPath, HTTPMethod } from '@orpc/client';
|
|
5
5
|
import { JSONSchema } from '@orpc/interop/json-schema-typed/draft-2020-12';
|
|
6
6
|
export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from '@orpc/interop/json-schema-typed/draft-2020-12';
|
|
@@ -66,6 +66,12 @@ declare function checkParamsSchema(schema: ObjectSchema, params: string[]): bool
|
|
|
66
66
|
*/
|
|
67
67
|
declare function toOpenAPISchema(schema: JSONSchema): OpenAPI.SchemaObject & object;
|
|
68
68
|
declare function resolveOpenAPIJsonSchemaRef(doc: OpenAPI.Document, schema: JSONSchema): JSONSchema;
|
|
69
|
+
/**
|
|
70
|
+
* Simplifies composed object JSON Schemas (using anyOf, oneOf, allOf) by flattening nested compositions
|
|
71
|
+
*
|
|
72
|
+
* @warning The result is looser than the original schema and may not fully validate the same data.
|
|
73
|
+
*/
|
|
74
|
+
declare function simplifyComposedObjectJsonSchemasAndRefs(schema: JSONSchema, doc?: OpenAPI.Document): JSONSchema;
|
|
69
75
|
|
|
70
76
|
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
77
|
|
|
@@ -106,5 +112,5 @@ declare const oo: {
|
|
|
106
112
|
spec: typeof customOpenAPIOperation;
|
|
107
113
|
};
|
|
108
114
|
|
|
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 };
|
|
115
|
+
export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, expandArrayableSchema, expandUnionSchema, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, isPrimitiveSchema, oo, resolveOpenAPIJsonSchemaRef, separateObjectSchema, simplifyComposedObjectJsonSchemasAndRefs, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
|
|
110
116
|
export type { FileSchema, ObjectSchema, OverrideOperationValue };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as customOpenAPIOperation } from './shared/openapi.
|
|
2
|
-
export { C as CompositeSchemaConverter, L as LOGIC_KEYWORDS, O as OpenAPIGenerator, a as applyCustomOpenAPIOperation,
|
|
1
|
+
import { c as customOpenAPIOperation } from './shared/openapi.CzHcOMxv.mjs';
|
|
2
|
+
export { C as CompositeSchemaConverter, L as LOGIC_KEYWORDS, O as OpenAPIGenerator, a as applyCustomOpenAPIOperation, o as applySchemaOptionality, h as checkParamsSchema, q as expandArrayableSchema, p as expandUnionSchema, n as filterSchemaBranches, g as getCustomOpenAPIOperation, l as isAnySchema, j as isFileSchema, k as isObjectSchema, u as isPrimitiveSchema, r as resolveOpenAPIJsonSchemaRef, m as separateObjectSchema, s as simplifyComposedObjectJsonSchemasAndRefs, d as toOpenAPIContent, e as toOpenAPIEventIteratorContent, b as toOpenAPIMethod, f as toOpenAPIParameters, t as toOpenAPIPath, i as toOpenAPISchema } from './shared/openapi.CzHcOMxv.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';
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -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.
|
|
5
|
+
import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.BfNjg7j9.mjs';
|
|
6
6
|
import '@orpc/openapi-client/standard';
|
|
7
7
|
import '@orpc/interop/json-schema-typed/draft-2020-12';
|
|
8
8
|
|
|
@@ -30,6 +30,12 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
|
|
|
30
30
|
* @default 'API Reference'
|
|
31
31
|
*/
|
|
32
32
|
docsTitle?: Value<Promisable<string>, [StandardHandlerInterceptorOptions<T>]>;
|
|
33
|
+
/**
|
|
34
|
+
* The UI library to use for rendering the API reference.
|
|
35
|
+
*
|
|
36
|
+
* @default 'scalar'
|
|
37
|
+
*/
|
|
38
|
+
docsProvider?: 'scalar' | 'swagger';
|
|
33
39
|
/**
|
|
34
40
|
* Arbitrary configuration object for the UI.
|
|
35
41
|
*/
|
|
@@ -43,13 +49,20 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
|
|
|
43
49
|
/**
|
|
44
50
|
* URL of the external script bundle for the reference UI.
|
|
45
51
|
*
|
|
46
|
-
*
|
|
52
|
+
* - For Scalar: defaults to 'https://cdn.jsdelivr.net/npm/@scalar/api-reference'
|
|
53
|
+
* - For Swagger UI: defaults to 'https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui-bundle.js'
|
|
47
54
|
*/
|
|
48
55
|
docsScriptUrl?: Value<Promisable<string>, [StandardHandlerInterceptorOptions<T>]>;
|
|
56
|
+
/**
|
|
57
|
+
* URL of the external CSS bundle for the reference UI (used by Swagger UI).
|
|
58
|
+
*
|
|
59
|
+
* @default 'https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui.css' (if swagger)
|
|
60
|
+
*/
|
|
61
|
+
docsCssUrl?: Value<Promisable<string>, [StandardHandlerInterceptorOptions<T>]>;
|
|
49
62
|
/**
|
|
50
63
|
* Override function to generate the full HTML for the docs page.
|
|
51
64
|
*/
|
|
52
|
-
renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPI.Document) => string;
|
|
65
|
+
renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPI.Document, docsProvider: 'scalar' | 'swagger', cssUrl: string | undefined) => string;
|
|
53
66
|
}
|
|
54
67
|
declare class OpenAPIReferencePlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
55
68
|
private readonly generator;
|
|
@@ -58,7 +71,9 @@ declare class OpenAPIReferencePlugin<T extends Context> implements StandardHandl
|
|
|
58
71
|
private readonly docsPath;
|
|
59
72
|
private readonly docsTitle;
|
|
60
73
|
private readonly docsHead;
|
|
74
|
+
private readonly docsProvider;
|
|
61
75
|
private readonly docsScriptUrl;
|
|
76
|
+
private readonly docsCssUrl;
|
|
62
77
|
private readonly docsConfig;
|
|
63
78
|
private readonly renderDocsHtml;
|
|
64
79
|
constructor(options?: OpenAPIReferencePluginOptions<T>);
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -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.
|
|
5
|
+
import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.BfNjg7j9.js';
|
|
6
6
|
import '@orpc/openapi-client/standard';
|
|
7
7
|
import '@orpc/interop/json-schema-typed/draft-2020-12';
|
|
8
8
|
|
|
@@ -30,6 +30,12 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
|
|
|
30
30
|
* @default 'API Reference'
|
|
31
31
|
*/
|
|
32
32
|
docsTitle?: Value<Promisable<string>, [StandardHandlerInterceptorOptions<T>]>;
|
|
33
|
+
/**
|
|
34
|
+
* The UI library to use for rendering the API reference.
|
|
35
|
+
*
|
|
36
|
+
* @default 'scalar'
|
|
37
|
+
*/
|
|
38
|
+
docsProvider?: 'scalar' | 'swagger';
|
|
33
39
|
/**
|
|
34
40
|
* Arbitrary configuration object for the UI.
|
|
35
41
|
*/
|
|
@@ -43,13 +49,20 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
|
|
|
43
49
|
/**
|
|
44
50
|
* URL of the external script bundle for the reference UI.
|
|
45
51
|
*
|
|
46
|
-
*
|
|
52
|
+
* - For Scalar: defaults to 'https://cdn.jsdelivr.net/npm/@scalar/api-reference'
|
|
53
|
+
* - For Swagger UI: defaults to 'https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui-bundle.js'
|
|
47
54
|
*/
|
|
48
55
|
docsScriptUrl?: Value<Promisable<string>, [StandardHandlerInterceptorOptions<T>]>;
|
|
56
|
+
/**
|
|
57
|
+
* URL of the external CSS bundle for the reference UI (used by Swagger UI).
|
|
58
|
+
*
|
|
59
|
+
* @default 'https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui.css' (if swagger)
|
|
60
|
+
*/
|
|
61
|
+
docsCssUrl?: Value<Promisable<string>, [StandardHandlerInterceptorOptions<T>]>;
|
|
49
62
|
/**
|
|
50
63
|
* Override function to generate the full HTML for the docs page.
|
|
51
64
|
*/
|
|
52
|
-
renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPI.Document) => string;
|
|
65
|
+
renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPI.Document, docsProvider: 'scalar' | 'swagger', cssUrl: string | undefined) => string;
|
|
53
66
|
}
|
|
54
67
|
declare class OpenAPIReferencePlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
55
68
|
private readonly generator;
|
|
@@ -58,7 +71,9 @@ declare class OpenAPIReferencePlugin<T extends Context> implements StandardHandl
|
|
|
58
71
|
private readonly docsPath;
|
|
59
72
|
private readonly docsTitle;
|
|
60
73
|
private readonly docsHead;
|
|
74
|
+
private readonly docsProvider;
|
|
61
75
|
private readonly docsScriptUrl;
|
|
76
|
+
private readonly docsCssUrl;
|
|
62
77
|
private readonly docsConfig;
|
|
63
78
|
private readonly renderDocsHtml;
|
|
64
79
|
constructor(options?: OpenAPIReferencePluginOptions<T>);
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { stringifyJSON, once, value } from '@orpc/shared';
|
|
2
|
-
import { O as OpenAPIGenerator } from '../shared/openapi.
|
|
2
|
+
import { O as OpenAPIGenerator } from '../shared/openapi.CzHcOMxv.mjs';
|
|
3
3
|
import '@orpc/client';
|
|
4
4
|
import '@orpc/client/standard';
|
|
5
5
|
import '@orpc/contract';
|
|
@@ -14,7 +14,9 @@ class OpenAPIReferencePlugin {
|
|
|
14
14
|
docsPath;
|
|
15
15
|
docsTitle;
|
|
16
16
|
docsHead;
|
|
17
|
+
docsProvider;
|
|
17
18
|
docsScriptUrl;
|
|
19
|
+
docsCssUrl;
|
|
18
20
|
docsConfig;
|
|
19
21
|
renderDocsHtml;
|
|
20
22
|
constructor(options = {}) {
|
|
@@ -22,16 +24,59 @@ class OpenAPIReferencePlugin {
|
|
|
22
24
|
this.docsPath = options.docsPath ?? "/";
|
|
23
25
|
this.docsTitle = options.docsTitle ?? "API Reference";
|
|
24
26
|
this.docsConfig = options.docsConfig ?? void 0;
|
|
25
|
-
this.
|
|
27
|
+
this.docsProvider = options.docsProvider ?? "scalar";
|
|
28
|
+
this.docsScriptUrl = options.docsScriptUrl ?? (this.docsProvider === "swagger" ? "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js" : "https://cdn.jsdelivr.net/npm/@scalar/api-reference");
|
|
29
|
+
this.docsCssUrl = options.docsCssUrl ?? (this.docsProvider === "swagger" ? "https://unpkg.com/swagger-ui-dist/swagger-ui.css" : void 0);
|
|
26
30
|
this.docsHead = options.docsHead ?? "";
|
|
27
31
|
this.specPath = options.specPath ?? "/spec.json";
|
|
28
32
|
this.generator = new OpenAPIGenerator(options);
|
|
29
33
|
const esc = (s) => s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
30
|
-
this.renderDocsHtml = options.renderDocsHtml ?? ((specUrl, title, head, scriptUrl, config, spec) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
this.renderDocsHtml = options.renderDocsHtml ?? ((specUrl, title, head, scriptUrl, config, spec, docsProvider, cssUrl) => {
|
|
35
|
+
let body;
|
|
36
|
+
if (docsProvider === "swagger") {
|
|
37
|
+
const swaggerConfig = {
|
|
38
|
+
dom_id: "#app",
|
|
39
|
+
spec,
|
|
40
|
+
deepLinking: true,
|
|
41
|
+
presets: [
|
|
42
|
+
"SwaggerUIBundle.presets.apis",
|
|
43
|
+
"SwaggerUIBundle.presets.standalone"
|
|
44
|
+
],
|
|
45
|
+
plugins: [
|
|
46
|
+
"SwaggerUIBundle.plugins.DownloadUrl"
|
|
47
|
+
],
|
|
48
|
+
...config
|
|
49
|
+
};
|
|
50
|
+
body = `
|
|
51
|
+
<body>
|
|
52
|
+
<div id="app"></div>
|
|
53
|
+
|
|
54
|
+
<script src="${esc(scriptUrl)}"><\/script>
|
|
55
|
+
|
|
56
|
+
<script>
|
|
57
|
+
window.onload = () => {
|
|
58
|
+
window.ui = SwaggerUIBundle(${stringifyJSON(swaggerConfig).replace(/"(SwaggerUIBundle\.[^"]+)"/g, "$1")})
|
|
59
|
+
}
|
|
60
|
+
<\/script>
|
|
61
|
+
</body>
|
|
62
|
+
`;
|
|
63
|
+
} else {
|
|
64
|
+
const scalarConfig = {
|
|
65
|
+
content: stringifyJSON(spec),
|
|
66
|
+
...config
|
|
67
|
+
};
|
|
68
|
+
body = `
|
|
69
|
+
<body>
|
|
70
|
+
<div id="app" data-config="${esc(stringifyJSON(scalarConfig))}"></div>
|
|
71
|
+
|
|
72
|
+
<script src="${esc(scriptUrl)}"><\/script>
|
|
73
|
+
|
|
74
|
+
<script>
|
|
75
|
+
Scalar.createApiReference('#app', JSON.parse(document.getElementById('app').dataset.config))
|
|
76
|
+
<\/script>
|
|
77
|
+
</body>
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
35
80
|
return `
|
|
36
81
|
<!doctype html>
|
|
37
82
|
<html>
|
|
@@ -39,19 +84,12 @@ class OpenAPIReferencePlugin {
|
|
|
39
84
|
<meta charset="utf-8" />
|
|
40
85
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
41
86
|
<title>${esc(title)}</title>
|
|
87
|
+
${cssUrl ? `<link rel="stylesheet" type="text/css" href="${esc(cssUrl)}" />` : ""}
|
|
42
88
|
${head}
|
|
43
89
|
</head>
|
|
44
|
-
|
|
45
|
-
<div id="app" data-config="${esc(stringifyJSON(finalConfig))}"></div>
|
|
46
|
-
|
|
47
|
-
<script src="${esc(scriptUrl)}"><\/script>
|
|
48
|
-
|
|
49
|
-
<script>
|
|
50
|
-
Scalar.createApiReference('#app', JSON.parse(document.getElementById('app').dataset.config))
|
|
51
|
-
<\/script>
|
|
52
|
-
</body>
|
|
90
|
+
${body}
|
|
53
91
|
</html>
|
|
54
|
-
|
|
92
|
+
`;
|
|
55
93
|
});
|
|
56
94
|
}
|
|
57
95
|
init(options, router) {
|
|
@@ -89,7 +127,9 @@ class OpenAPIReferencePlugin {
|
|
|
89
127
|
await value(this.docsHead, options2),
|
|
90
128
|
await value(this.docsScriptUrl, options2),
|
|
91
129
|
await value(this.docsConfig, options2),
|
|
92
|
-
await generateSpec()
|
|
130
|
+
await generateSpec(),
|
|
131
|
+
this.docsProvider,
|
|
132
|
+
await value(this.docsCssUrl, options2)
|
|
93
133
|
);
|
|
94
134
|
return {
|
|
95
135
|
matched: true,
|
|
@@ -85,6 +85,18 @@ interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPI.Document,
|
|
|
85
85
|
error: 'UndefinedError';
|
|
86
86
|
schema?: never;
|
|
87
87
|
}>;
|
|
88
|
+
/**
|
|
89
|
+
* Define a custom JSON schema for the error response body when using
|
|
90
|
+
* type-safe errors. Helps align ORPC error formatting with existing API
|
|
91
|
+
* response standards or conventions.
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* - Return `null | undefined` to use the default error response body shaper.
|
|
95
|
+
*/
|
|
96
|
+
customErrorResponseBodySchema?: Value<JSONSchema | undefined | null, [
|
|
97
|
+
definedErrors: [code: string, defaultMessage: string, dataRequired: boolean, dataSchema: JSONSchema][],
|
|
98
|
+
status: number
|
|
99
|
+
]>;
|
|
88
100
|
}
|
|
89
101
|
/**
|
|
90
102
|
* The generator that converts oRPC routers/contracts to OpenAPI specifications.
|
|
@@ -101,7 +113,7 @@ declare class OpenAPIGenerator {
|
|
|
101
113
|
*
|
|
102
114
|
* @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
|
|
103
115
|
*/
|
|
104
|
-
generate(router: AnyContractRouter | AnyRouter,
|
|
116
|
+
generate(router: AnyContractRouter | AnyRouter, { customErrorResponseBodySchema, commonSchemas, filter: baseFilter, exclude, ...baseDoc }?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
export { OpenAPIGenerator as b, CompositeSchemaConverter as e };
|
|
@@ -85,6 +85,18 @@ interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPI.Document,
|
|
|
85
85
|
error: 'UndefinedError';
|
|
86
86
|
schema?: never;
|
|
87
87
|
}>;
|
|
88
|
+
/**
|
|
89
|
+
* Define a custom JSON schema for the error response body when using
|
|
90
|
+
* type-safe errors. Helps align ORPC error formatting with existing API
|
|
91
|
+
* response standards or conventions.
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* - Return `null | undefined` to use the default error response body shaper.
|
|
95
|
+
*/
|
|
96
|
+
customErrorResponseBodySchema?: Value<JSONSchema | undefined | null, [
|
|
97
|
+
definedErrors: [code: string, defaultMessage: string, dataRequired: boolean, dataSchema: JSONSchema][],
|
|
98
|
+
status: number
|
|
99
|
+
]>;
|
|
88
100
|
}
|
|
89
101
|
/**
|
|
90
102
|
* The generator that converts oRPC routers/contracts to OpenAPI specifications.
|
|
@@ -101,7 +113,7 @@ declare class OpenAPIGenerator {
|
|
|
101
113
|
*
|
|
102
114
|
* @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
|
|
103
115
|
*/
|
|
104
|
-
generate(router: AnyContractRouter | AnyRouter,
|
|
116
|
+
generate(router: AnyContractRouter | AnyRouter, { customErrorResponseBodySchema, commonSchemas, filter: baseFilter, exclude, ...baseDoc }?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
export { OpenAPIGenerator as b, CompositeSchemaConverter as e };
|
|
@@ -359,6 +359,107 @@ function resolveOpenAPIJsonSchemaRef(doc, schema) {
|
|
|
359
359
|
const resolved = doc.components?.schemas?.[name];
|
|
360
360
|
return resolved ?? schema;
|
|
361
361
|
}
|
|
362
|
+
function simplifyComposedObjectJsonSchemasAndRefs(schema, doc) {
|
|
363
|
+
if (doc) {
|
|
364
|
+
schema = resolveOpenAPIJsonSchemaRef(doc, schema);
|
|
365
|
+
}
|
|
366
|
+
if (typeof schema !== "object" || !schema.anyOf && !schema.oneOf && !schema.allOf) {
|
|
367
|
+
return schema;
|
|
368
|
+
}
|
|
369
|
+
const unionSchemas = [
|
|
370
|
+
...toArray(schema.anyOf?.map((s) => simplifyComposedObjectJsonSchemasAndRefs(s, doc))),
|
|
371
|
+
...toArray(schema.oneOf?.map((s) => simplifyComposedObjectJsonSchemasAndRefs(s, doc)))
|
|
372
|
+
];
|
|
373
|
+
const objectUnionSchemas = [];
|
|
374
|
+
for (const u of unionSchemas) {
|
|
375
|
+
if (!isObjectSchema(u)) {
|
|
376
|
+
return schema;
|
|
377
|
+
}
|
|
378
|
+
objectUnionSchemas.push(u);
|
|
379
|
+
}
|
|
380
|
+
const mergedUnionPropertyMap = /* @__PURE__ */ new Map();
|
|
381
|
+
for (const u of objectUnionSchemas) {
|
|
382
|
+
if (u.properties) {
|
|
383
|
+
for (const [key, value] of Object.entries(u.properties)) {
|
|
384
|
+
let entry = mergedUnionPropertyMap.get(key);
|
|
385
|
+
if (!entry) {
|
|
386
|
+
const required = objectUnionSchemas.every((s) => s.required?.includes(key));
|
|
387
|
+
entry = { required, schemas: [] };
|
|
388
|
+
mergedUnionPropertyMap.set(key, entry);
|
|
389
|
+
}
|
|
390
|
+
entry.schemas.push(value);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const intersectionSchemas = toArray(schema.allOf?.map((s) => simplifyComposedObjectJsonSchemasAndRefs(s, doc)));
|
|
395
|
+
const objectIntersectionSchemas = [];
|
|
396
|
+
for (const u of intersectionSchemas) {
|
|
397
|
+
if (!isObjectSchema(u)) {
|
|
398
|
+
return schema;
|
|
399
|
+
}
|
|
400
|
+
objectIntersectionSchemas.push(u);
|
|
401
|
+
}
|
|
402
|
+
if (isObjectSchema(schema)) {
|
|
403
|
+
objectIntersectionSchemas.push(schema);
|
|
404
|
+
}
|
|
405
|
+
const mergedInteractionPropertyMap = /* @__PURE__ */ new Map();
|
|
406
|
+
for (const u of objectIntersectionSchemas) {
|
|
407
|
+
if (u.properties) {
|
|
408
|
+
for (const [key, value] of Object.entries(u.properties)) {
|
|
409
|
+
let entry = mergedInteractionPropertyMap.get(key);
|
|
410
|
+
if (!entry) {
|
|
411
|
+
const required = objectIntersectionSchemas.some((s) => s.required?.includes(key));
|
|
412
|
+
entry = { required, schemas: [] };
|
|
413
|
+
mergedInteractionPropertyMap.set(key, entry);
|
|
414
|
+
}
|
|
415
|
+
entry.schemas.push(value);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
const resultObjectSchema = { type: "object", properties: {}, required: [] };
|
|
420
|
+
const keys = /* @__PURE__ */ new Set([
|
|
421
|
+
...mergedUnionPropertyMap.keys(),
|
|
422
|
+
...mergedInteractionPropertyMap.keys()
|
|
423
|
+
]);
|
|
424
|
+
if (keys.size === 0) {
|
|
425
|
+
return schema;
|
|
426
|
+
}
|
|
427
|
+
const deduplicateSchemas = (schemas) => {
|
|
428
|
+
const seen = /* @__PURE__ */ new Set();
|
|
429
|
+
const result = [];
|
|
430
|
+
for (const schema2 of schemas) {
|
|
431
|
+
const key = stringifyJSON(schema2);
|
|
432
|
+
if (!seen.has(key)) {
|
|
433
|
+
seen.add(key);
|
|
434
|
+
result.push(schema2);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return result;
|
|
438
|
+
};
|
|
439
|
+
for (const key of keys) {
|
|
440
|
+
const unionEntry = mergedUnionPropertyMap.get(key);
|
|
441
|
+
const intersectionEntry = mergedInteractionPropertyMap.get(key);
|
|
442
|
+
resultObjectSchema.properties[key] = (() => {
|
|
443
|
+
const dedupedUnionSchemas = unionEntry ? deduplicateSchemas(unionEntry.schemas) : [];
|
|
444
|
+
const dedupedIntersectionSchemas = intersectionEntry ? deduplicateSchemas(intersectionEntry.schemas) : [];
|
|
445
|
+
if (!dedupedUnionSchemas.length) {
|
|
446
|
+
return dedupedIntersectionSchemas.length === 1 ? dedupedIntersectionSchemas[0] : { allOf: dedupedIntersectionSchemas };
|
|
447
|
+
}
|
|
448
|
+
if (!dedupedIntersectionSchemas.length) {
|
|
449
|
+
return dedupedUnionSchemas.length === 1 ? dedupedUnionSchemas[0] : { anyOf: dedupedUnionSchemas };
|
|
450
|
+
}
|
|
451
|
+
const allOf = deduplicateSchemas([
|
|
452
|
+
...dedupedIntersectionSchemas,
|
|
453
|
+
dedupedUnionSchemas.length === 1 ? dedupedUnionSchemas[0] : { anyOf: dedupedUnionSchemas }
|
|
454
|
+
]);
|
|
455
|
+
return allOf.length === 1 ? allOf[0] : { allOf };
|
|
456
|
+
})();
|
|
457
|
+
if (unionEntry?.required || intersectionEntry?.required) {
|
|
458
|
+
resultObjectSchema.required.push(key);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return resultObjectSchema;
|
|
462
|
+
}
|
|
362
463
|
|
|
363
464
|
class CompositeSchemaConverter {
|
|
364
465
|
converters;
|
|
@@ -389,19 +490,16 @@ class OpenAPIGenerator {
|
|
|
389
490
|
*
|
|
390
491
|
* @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
|
|
391
492
|
*/
|
|
392
|
-
async generate(router,
|
|
393
|
-
const filter =
|
|
394
|
-
return !(
|
|
493
|
+
async generate(router, { customErrorResponseBodySchema, commonSchemas, filter: baseFilter, exclude, ...baseDoc } = {}) {
|
|
494
|
+
const filter = baseFilter ?? (({ contract, path }) => {
|
|
495
|
+
return !(exclude?.(contract, path) ?? false);
|
|
395
496
|
});
|
|
396
497
|
const doc = {
|
|
397
|
-
...clone(
|
|
398
|
-
info:
|
|
399
|
-
openapi: "3.1.1"
|
|
400
|
-
exclude: void 0,
|
|
401
|
-
filter: void 0,
|
|
402
|
-
commonSchemas: void 0
|
|
498
|
+
...clone(baseDoc),
|
|
499
|
+
info: baseDoc.info ?? { title: "API Reference", version: "0.0.0" },
|
|
500
|
+
openapi: "3.1.1"
|
|
403
501
|
};
|
|
404
|
-
const { baseSchemaConvertOptions, undefinedErrorJsonSchema } = await this.#resolveCommonSchemas(doc,
|
|
502
|
+
const { baseSchemaConvertOptions, undefinedErrorJsonSchema } = await this.#resolveCommonSchemas(doc, commonSchemas);
|
|
405
503
|
const contracts = [];
|
|
406
504
|
await resolveContractProcedures({ path: [], router }, (traverseOptions) => {
|
|
407
505
|
if (!value(filter, traverseOptions)) {
|
|
@@ -429,7 +527,7 @@ class OpenAPIGenerator {
|
|
|
429
527
|
};
|
|
430
528
|
await this.#request(doc, operationObjectRef, def, baseSchemaConvertOptions);
|
|
431
529
|
await this.#successResponse(doc, operationObjectRef, def, baseSchemaConvertOptions);
|
|
432
|
-
await this.#errorResponse(operationObjectRef, def, baseSchemaConvertOptions, undefinedErrorJsonSchema);
|
|
530
|
+
await this.#errorResponse(operationObjectRef, def, baseSchemaConvertOptions, undefinedErrorJsonSchema, customErrorResponseBodySchema);
|
|
433
531
|
}
|
|
434
532
|
if (typeof def.route.spec === "function") {
|
|
435
533
|
operationObjectRef = def.route.spec(operationObjectRef);
|
|
@@ -542,13 +640,15 @@ ${errors.join("\n\n")}`
|
|
|
542
640
|
def.inputSchema,
|
|
543
641
|
{
|
|
544
642
|
...baseSchemaConvertOptions,
|
|
545
|
-
strategy: "input"
|
|
546
|
-
minStructureDepthForRef: dynamicParams?.length || inputStructure === "detailed" ? 1 : 0
|
|
643
|
+
strategy: "input"
|
|
547
644
|
}
|
|
548
645
|
);
|
|
549
646
|
if (isAnySchema(schema) && !dynamicParams?.length) {
|
|
550
647
|
return;
|
|
551
648
|
}
|
|
649
|
+
if (inputStructure === "detailed" || inputStructure === "compact" && (dynamicParams?.length || method === "GET")) {
|
|
650
|
+
schema = simplifyComposedObjectJsonSchemasAndRefs(schema, doc);
|
|
651
|
+
}
|
|
552
652
|
if (inputStructure === "compact") {
|
|
553
653
|
if (dynamicParams?.length) {
|
|
554
654
|
const error2 = new OpenAPIGeneratorError(
|
|
@@ -588,7 +688,7 @@ ${errors.join("\n\n")}`
|
|
|
588
688
|
if (!isObjectSchema(schema)) {
|
|
589
689
|
throw error;
|
|
590
690
|
}
|
|
591
|
-
const resolvedParamSchema = schema.properties?.params !== void 0 ?
|
|
691
|
+
const resolvedParamSchema = schema.properties?.params !== void 0 ? simplifyComposedObjectJsonSchemasAndRefs(schema.properties.params, doc) : void 0;
|
|
592
692
|
if (dynamicParams?.length && (resolvedParamSchema === void 0 || !isObjectSchema(resolvedParamSchema) || !checkParamsSchema(resolvedParamSchema, dynamicParams))) {
|
|
593
693
|
throw new OpenAPIGeneratorError(
|
|
594
694
|
'When input structure is "detailed" and path has dynamic params, the "params" schema must be an object with all dynamic params as required.'
|
|
@@ -597,7 +697,7 @@ ${errors.join("\n\n")}`
|
|
|
597
697
|
for (const from of ["params", "query", "headers"]) {
|
|
598
698
|
const fromSchema = schema.properties?.[from];
|
|
599
699
|
if (fromSchema !== void 0) {
|
|
600
|
-
const resolvedSchema =
|
|
700
|
+
const resolvedSchema = simplifyComposedObjectJsonSchemasAndRefs(fromSchema, doc);
|
|
601
701
|
if (!isObjectSchema(resolvedSchema)) {
|
|
602
702
|
throw error;
|
|
603
703
|
}
|
|
@@ -658,13 +758,14 @@ ${errors.join("\n\n")}`
|
|
|
658
758
|
|
|
659
759
|
But got: ${stringifyJSON(item)}
|
|
660
760
|
`);
|
|
661
|
-
|
|
761
|
+
const simplifiedItem = simplifyComposedObjectJsonSchemasAndRefs(item, doc);
|
|
762
|
+
if (!isObjectSchema(simplifiedItem)) {
|
|
662
763
|
throw error;
|
|
663
764
|
}
|
|
664
765
|
let schemaStatus;
|
|
665
766
|
let schemaDescription;
|
|
666
|
-
if (
|
|
667
|
-
const statusSchema = resolveOpenAPIJsonSchemaRef(doc,
|
|
767
|
+
if (simplifiedItem.properties?.status !== void 0) {
|
|
768
|
+
const statusSchema = resolveOpenAPIJsonSchemaRef(doc, simplifiedItem.properties.status);
|
|
668
769
|
if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) {
|
|
669
770
|
throw error;
|
|
670
771
|
}
|
|
@@ -684,8 +785,8 @@ ${errors.join("\n\n")}`
|
|
|
684
785
|
ref.responses[itemStatus] = {
|
|
685
786
|
description: itemDescription
|
|
686
787
|
};
|
|
687
|
-
if (
|
|
688
|
-
const headersSchema =
|
|
788
|
+
if (simplifiedItem.properties?.headers !== void 0) {
|
|
789
|
+
const headersSchema = simplifyComposedObjectJsonSchemasAndRefs(simplifiedItem.properties.headers, doc);
|
|
689
790
|
if (!isObjectSchema(headersSchema)) {
|
|
690
791
|
throw error;
|
|
691
792
|
}
|
|
@@ -695,50 +796,52 @@ ${errors.join("\n\n")}`
|
|
|
695
796
|
ref.responses[itemStatus].headers ??= {};
|
|
696
797
|
ref.responses[itemStatus].headers[key] = {
|
|
697
798
|
schema: toOpenAPISchema(headerSchema),
|
|
698
|
-
required:
|
|
799
|
+
required: simplifiedItem.required?.includes("headers") && headersSchema.required?.includes(key)
|
|
699
800
|
};
|
|
700
801
|
}
|
|
701
802
|
}
|
|
702
803
|
}
|
|
703
|
-
if (
|
|
804
|
+
if (simplifiedItem.properties?.body !== void 0) {
|
|
704
805
|
ref.responses[itemStatus].content = toOpenAPIContent(
|
|
705
|
-
applySchemaOptionality(
|
|
806
|
+
applySchemaOptionality(simplifiedItem.required?.includes("body") ?? false, simplifiedItem.properties.body)
|
|
706
807
|
);
|
|
707
808
|
}
|
|
708
809
|
}
|
|
709
810
|
}
|
|
710
|
-
async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema) {
|
|
811
|
+
async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema, customErrorResponseBodySchema) {
|
|
711
812
|
const errorMap = def.errorMap;
|
|
712
|
-
const
|
|
813
|
+
const errorResponsesByStatus = {};
|
|
713
814
|
for (const code in errorMap) {
|
|
714
815
|
const config = errorMap[code];
|
|
715
816
|
if (!config) {
|
|
716
817
|
continue;
|
|
717
818
|
}
|
|
718
819
|
const status = fallbackORPCErrorStatus(code, config.status);
|
|
719
|
-
const
|
|
820
|
+
const defaultMessage = fallbackORPCErrorMessage(code, config.message);
|
|
821
|
+
errorResponsesByStatus[status] ??= { status, definedErrorDefinitions: [], errorSchemaVariants: [] };
|
|
720
822
|
const [dataRequired, dataSchema] = await this.converter.convert(config.data, { ...baseSchemaConvertOptions, strategy: "output" });
|
|
721
|
-
|
|
722
|
-
|
|
823
|
+
errorResponsesByStatus[status].definedErrorDefinitions.push([code, defaultMessage, dataRequired, dataSchema]);
|
|
824
|
+
errorResponsesByStatus[status].errorSchemaVariants.push({
|
|
723
825
|
type: "object",
|
|
724
826
|
properties: {
|
|
725
827
|
defined: { const: true },
|
|
726
828
|
code: { const: code },
|
|
727
829
|
status: { const: status },
|
|
728
|
-
message: { type: "string", default:
|
|
830
|
+
message: { type: "string", default: defaultMessage },
|
|
729
831
|
data: dataSchema
|
|
730
832
|
},
|
|
731
833
|
required: dataRequired ? ["defined", "code", "status", "message", "data"] : ["defined", "code", "status", "message"]
|
|
732
834
|
});
|
|
733
835
|
}
|
|
734
836
|
ref.responses ??= {};
|
|
735
|
-
for (const
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
837
|
+
for (const statusString in errorResponsesByStatus) {
|
|
838
|
+
const errorResponse = errorResponsesByStatus[statusString];
|
|
839
|
+
const customBodySchema = value(customErrorResponseBodySchema, errorResponse.definedErrorDefinitions, errorResponse.status);
|
|
840
|
+
ref.responses[statusString] = {
|
|
841
|
+
description: statusString,
|
|
842
|
+
content: toOpenAPIContent(customBodySchema ?? {
|
|
740
843
|
oneOf: [
|
|
741
|
-
...
|
|
844
|
+
...errorResponse.errorSchemaVariants,
|
|
742
845
|
undefinedErrorSchema
|
|
743
846
|
]
|
|
744
847
|
})
|
|
@@ -747,4 +850,4 @@ ${errors.join("\n\n")}`
|
|
|
747
850
|
}
|
|
748
851
|
}
|
|
749
852
|
|
|
750
|
-
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,
|
|
853
|
+
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, separateObjectSchema as m, filterSchemaBranches as n, applySchemaOptionality as o, expandUnionSchema as p, expandArrayableSchema as q, resolveOpenAPIJsonSchemaRef as r, simplifyComposedObjectJsonSchemasAndRefs as s, toOpenAPIPath as t, isPrimitiveSchema as u };
|
|
@@ -8,9 +8,11 @@ import { traverseContractProcedures, isProcedure, getLazyMeta, unlazy, getRouter
|
|
|
8
8
|
import { createRouter, addRoute, findRoute } from 'rou3';
|
|
9
9
|
|
|
10
10
|
class StandardOpenAPICodec {
|
|
11
|
-
constructor(serializer) {
|
|
11
|
+
constructor(serializer, options = {}) {
|
|
12
12
|
this.serializer = serializer;
|
|
13
|
+
this.customErrorResponseBodyEncoder = options.customErrorResponseBodyEncoder;
|
|
13
14
|
}
|
|
15
|
+
customErrorResponseBodyEncoder;
|
|
14
16
|
async decode(request, params, procedure) {
|
|
15
17
|
const inputStructure = fallbackContractConfig("defaultInputStructure", procedure["~orpc"].route.inputStructure);
|
|
16
18
|
if (inputStructure === "compact") {
|
|
@@ -73,10 +75,11 @@ class StandardOpenAPICodec {
|
|
|
73
75
|
};
|
|
74
76
|
}
|
|
75
77
|
encodeError(error) {
|
|
78
|
+
const body = this.customErrorResponseBodyEncoder?.(error) ?? error.toJSON();
|
|
76
79
|
return {
|
|
77
80
|
status: error.status,
|
|
78
81
|
headers: {},
|
|
79
|
-
body: this.serializer.serialize(
|
|
82
|
+
body: this.serializer.serialize(body, { outputFormat: "plain" })
|
|
80
83
|
};
|
|
81
84
|
}
|
|
82
85
|
#isDetailedOutput(output) {
|
|
@@ -179,7 +182,7 @@ class StandardOpenAPIHandler extends StandardHandler {
|
|
|
179
182
|
const bracketNotationSerializer = new StandardBracketNotationSerializer(options);
|
|
180
183
|
const serializer = new StandardOpenAPISerializer(jsonSerializer, bracketNotationSerializer);
|
|
181
184
|
const matcher = new StandardOpenAPIMatcher(options);
|
|
182
|
-
const codec = new StandardOpenAPICodec(serializer);
|
|
185
|
+
const codec = new StandardOpenAPICodec(serializer, options);
|
|
183
186
|
super(router, matcher, codec, options);
|
|
184
187
|
}
|
|
185
188
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { StandardOpenAPISerializer, StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions } from '@orpc/openapi-client/standard';
|
|
2
|
+
import { AnyProcedure, TraverseContractProcedureCallbackOptions, AnyRouter, Context, Router } from '@orpc/server';
|
|
3
|
+
import { StandardCodec, StandardParams, StandardMatcher, StandardMatchResult, StandardHandlerOptions, StandardHandler } from '@orpc/server/standard';
|
|
4
|
+
import { ORPCError, HTTPPath } from '@orpc/client';
|
|
5
|
+
import { StandardLazyRequest, StandardResponse } from '@orpc/standard-server';
|
|
6
|
+
import { Value } from '@orpc/shared';
|
|
7
|
+
|
|
8
|
+
interface StandardOpenAPICodecOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Customize how an ORPC error is encoded into a response body.
|
|
11
|
+
* Use this if your API needs a different error output structure.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* - Return `null | undefined` to fallback to default behavior
|
|
15
|
+
*
|
|
16
|
+
* @default ((e) => e.toJSON())
|
|
17
|
+
*/
|
|
18
|
+
customErrorResponseBodyEncoder?: (error: ORPCError<any, any>) => unknown;
|
|
19
|
+
}
|
|
20
|
+
declare class StandardOpenAPICodec implements StandardCodec {
|
|
21
|
+
#private;
|
|
22
|
+
private readonly serializer;
|
|
23
|
+
private readonly customErrorResponseBodyEncoder;
|
|
24
|
+
constructor(serializer: StandardOpenAPISerializer, options?: StandardOpenAPICodecOptions);
|
|
25
|
+
decode(request: StandardLazyRequest, params: StandardParams | undefined, procedure: AnyProcedure): Promise<unknown>;
|
|
26
|
+
encode(output: unknown, procedure: AnyProcedure): StandardResponse;
|
|
27
|
+
encodeError(error: ORPCError<any, any>): StandardResponse;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface StandardOpenAPIMatcherOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Filter procedures. Return `false` to exclude a procedure from matching.
|
|
33
|
+
*
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
filter?: Value<boolean, [options: TraverseContractProcedureCallbackOptions]>;
|
|
37
|
+
}
|
|
38
|
+
declare class StandardOpenAPIMatcher implements StandardMatcher {
|
|
39
|
+
private readonly filter;
|
|
40
|
+
private readonly tree;
|
|
41
|
+
private pendingRouters;
|
|
42
|
+
constructor(options?: StandardOpenAPIMatcherOptions);
|
|
43
|
+
init(router: AnyRouter, path?: readonly string[]): void;
|
|
44
|
+
match(method: string, pathname: HTTPPath): Promise<StandardMatchResult>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface StandardOpenAPIHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions, StandardOpenAPIMatcherOptions, StandardOpenAPICodecOptions {
|
|
48
|
+
}
|
|
49
|
+
declare class StandardOpenAPIHandler<T extends Context> extends StandardHandler<T> {
|
|
50
|
+
constructor(router: Router<any, T>, options: NoInfer<StandardOpenAPIHandlerOptions<T>>);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { StandardOpenAPICodec as a, StandardOpenAPIHandler as c, StandardOpenAPIMatcher as e };
|
|
54
|
+
export type { StandardOpenAPICodecOptions as S, StandardOpenAPIHandlerOptions as b, StandardOpenAPIMatcherOptions as d };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { StandardOpenAPISerializer, StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions } from '@orpc/openapi-client/standard';
|
|
2
|
+
import { AnyProcedure, TraverseContractProcedureCallbackOptions, AnyRouter, Context, Router } from '@orpc/server';
|
|
3
|
+
import { StandardCodec, StandardParams, StandardMatcher, StandardMatchResult, StandardHandlerOptions, StandardHandler } from '@orpc/server/standard';
|
|
4
|
+
import { ORPCError, HTTPPath } from '@orpc/client';
|
|
5
|
+
import { StandardLazyRequest, StandardResponse } from '@orpc/standard-server';
|
|
6
|
+
import { Value } from '@orpc/shared';
|
|
7
|
+
|
|
8
|
+
interface StandardOpenAPICodecOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Customize how an ORPC error is encoded into a response body.
|
|
11
|
+
* Use this if your API needs a different error output structure.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* - Return `null | undefined` to fallback to default behavior
|
|
15
|
+
*
|
|
16
|
+
* @default ((e) => e.toJSON())
|
|
17
|
+
*/
|
|
18
|
+
customErrorResponseBodyEncoder?: (error: ORPCError<any, any>) => unknown;
|
|
19
|
+
}
|
|
20
|
+
declare class StandardOpenAPICodec implements StandardCodec {
|
|
21
|
+
#private;
|
|
22
|
+
private readonly serializer;
|
|
23
|
+
private readonly customErrorResponseBodyEncoder;
|
|
24
|
+
constructor(serializer: StandardOpenAPISerializer, options?: StandardOpenAPICodecOptions);
|
|
25
|
+
decode(request: StandardLazyRequest, params: StandardParams | undefined, procedure: AnyProcedure): Promise<unknown>;
|
|
26
|
+
encode(output: unknown, procedure: AnyProcedure): StandardResponse;
|
|
27
|
+
encodeError(error: ORPCError<any, any>): StandardResponse;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface StandardOpenAPIMatcherOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Filter procedures. Return `false` to exclude a procedure from matching.
|
|
33
|
+
*
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
filter?: Value<boolean, [options: TraverseContractProcedureCallbackOptions]>;
|
|
37
|
+
}
|
|
38
|
+
declare class StandardOpenAPIMatcher implements StandardMatcher {
|
|
39
|
+
private readonly filter;
|
|
40
|
+
private readonly tree;
|
|
41
|
+
private pendingRouters;
|
|
42
|
+
constructor(options?: StandardOpenAPIMatcherOptions);
|
|
43
|
+
init(router: AnyRouter, path?: readonly string[]): void;
|
|
44
|
+
match(method: string, pathname: HTTPPath): Promise<StandardMatchResult>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface StandardOpenAPIHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, StandardOpenAPIJsonSerializerOptions, StandardBracketNotationSerializerOptions, StandardOpenAPIMatcherOptions, StandardOpenAPICodecOptions {
|
|
48
|
+
}
|
|
49
|
+
declare class StandardOpenAPIHandler<T extends Context> extends StandardHandler<T> {
|
|
50
|
+
constructor(router: Router<any, T>, options: NoInfer<StandardOpenAPIHandlerOptions<T>>);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { StandardOpenAPICodec as a, StandardOpenAPIHandler as c, StandardOpenAPIMatcher as e };
|
|
54
|
+
export type { StandardOpenAPICodecOptions as S, StandardOpenAPIHandlerOptions as b, StandardOpenAPIMatcherOptions 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.
|
|
4
|
+
"version": "0.0.0-next.0ab5adc",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://orpc.unnoq.com",
|
|
7
7
|
"repository": {
|
|
@@ -39,6 +39,11 @@
|
|
|
39
39
|
"import": "./dist/adapters/node/index.mjs",
|
|
40
40
|
"default": "./dist/adapters/node/index.mjs"
|
|
41
41
|
},
|
|
42
|
+
"./fastify": {
|
|
43
|
+
"types": "./dist/adapters/fastify/index.d.mts",
|
|
44
|
+
"import": "./dist/adapters/fastify/index.mjs",
|
|
45
|
+
"default": "./dist/adapters/fastify/index.mjs"
|
|
46
|
+
},
|
|
42
47
|
"./aws-lambda": {
|
|
43
48
|
"types": "./dist/adapters/aws-lambda/index.d.mts",
|
|
44
49
|
"import": "./dist/adapters/aws-lambda/index.mjs",
|
|
@@ -49,17 +54,18 @@
|
|
|
49
54
|
"dist"
|
|
50
55
|
],
|
|
51
56
|
"dependencies": {
|
|
52
|
-
"rou3": "^0.7.
|
|
53
|
-
"@orpc/client": "0.0.0-next.
|
|
54
|
-
"@orpc/contract": "0.0.0-next.
|
|
55
|
-
"@orpc/
|
|
56
|
-
"@orpc/server": "0.0.0-next.
|
|
57
|
-
"@orpc/
|
|
58
|
-
"@orpc/standard-server": "0.0.0-next.
|
|
59
|
-
"@orpc/
|
|
57
|
+
"rou3": "^0.7.10",
|
|
58
|
+
"@orpc/client": "0.0.0-next.0ab5adc",
|
|
59
|
+
"@orpc/contract": "0.0.0-next.0ab5adc",
|
|
60
|
+
"@orpc/openapi-client": "0.0.0-next.0ab5adc",
|
|
61
|
+
"@orpc/server": "0.0.0-next.0ab5adc",
|
|
62
|
+
"@orpc/interop": "0.0.0-next.0ab5adc",
|
|
63
|
+
"@orpc/standard-server": "0.0.0-next.0ab5adc",
|
|
64
|
+
"@orpc/shared": "0.0.0-next.0ab5adc"
|
|
60
65
|
},
|
|
61
66
|
"devDependencies": {
|
|
62
|
-
"
|
|
67
|
+
"fastify": "^5.6.1",
|
|
68
|
+
"zod": "^4.1.12"
|
|
63
69
|
},
|
|
64
70
|
"scripts": {
|
|
65
71
|
"build": "unbuild",
|
|
@@ -1,31 +0,0 @@
|
|
|
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 };
|
|
@@ -1,31 +0,0 @@
|
|
|
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 };
|