@orpc/server 0.0.0-next.4a7a06a → 0.0.0-next.4b3a4c5
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 +9 -9
- package/dist/adapters/aws-lambda/index.d.mts +46 -0
- package/dist/adapters/aws-lambda/index.d.ts +46 -0
- package/dist/adapters/aws-lambda/index.mjs +42 -0
- package/dist/adapters/bun-ws/index.d.mts +12 -11
- package/dist/adapters/bun-ws/index.d.ts +12 -11
- package/dist/adapters/bun-ws/index.mjs +16 -20
- package/dist/adapters/crossws/index.d.mts +8 -5
- package/dist/adapters/crossws/index.d.ts +8 -5
- package/dist/adapters/crossws/index.mjs +11 -17
- package/dist/adapters/fetch/index.d.mts +56 -10
- package/dist/adapters/fetch/index.d.ts +56 -10
- package/dist/adapters/fetch/index.mjs +74 -4
- package/dist/adapters/message-port/index.d.mts +31 -0
- package/dist/adapters/message-port/index.d.ts +31 -0
- package/dist/adapters/message-port/index.mjs +39 -0
- package/dist/adapters/node/index.d.mts +32 -10
- package/dist/adapters/node/index.d.ts +32 -10
- package/dist/adapters/node/index.mjs +70 -13
- package/dist/adapters/standard/index.d.mts +8 -13
- package/dist/adapters/standard/index.d.ts +8 -13
- package/dist/adapters/standard/index.mjs +3 -2
- package/dist/adapters/standard-peer/index.d.mts +18 -0
- package/dist/adapters/standard-peer/index.d.ts +18 -0
- package/dist/adapters/standard-peer/index.mjs +7 -0
- package/dist/adapters/websocket/index.d.mts +36 -9
- package/dist/adapters/websocket/index.d.ts +36 -9
- package/dist/adapters/websocket/index.mjs +49 -20
- package/dist/adapters/ws/index.d.mts +11 -8
- package/dist/adapters/ws/index.d.ts +11 -8
- package/dist/adapters/ws/index.mjs +13 -14
- package/dist/helpers/index.d.mts +134 -0
- package/dist/helpers/index.d.ts +134 -0
- package/dist/helpers/index.mjs +188 -0
- package/dist/hibernation/index.d.mts +44 -0
- package/dist/hibernation/index.d.ts +44 -0
- package/dist/hibernation/index.mjs +65 -0
- package/dist/index.d.mts +21 -47
- package/dist/index.d.ts +21 -47
- package/dist/index.mjs +24 -9
- package/dist/plugins/index.d.mts +28 -15
- package/dist/plugins/index.d.ts +28 -15
- package/dist/plugins/index.mjs +94 -60
- package/dist/shared/{server.4FnxLwwr.mjs → server.2SSWGLDL.mjs} +75 -42
- package/dist/shared/server.B7b2w3_i.d.ts +12 -0
- package/dist/shared/server.BEFBl-Cb.d.mts +12 -0
- package/dist/shared/server.BU4WI18A.d.mts +32 -0
- package/dist/shared/{server.YZzrREz9.d.ts → server.Bmh5xd4n.d.ts} +8 -8
- package/dist/shared/{server.DPWk5pjW.d.mts → server.CYNGeoCm.d.mts} +10 -8
- package/dist/shared/{server.DPWk5pjW.d.ts → server.CYNGeoCm.d.ts} +10 -8
- package/dist/shared/server.D0H-iaY3.d.ts +32 -0
- package/dist/shared/{server.BVwwTHyO.mjs → server.DZ5BIITo.mjs} +1 -1
- package/dist/shared/server.DhJj-1X9.d.mts +42 -0
- package/dist/shared/{server.DG7Tamti.mjs → server.Dp6pyBjF.mjs} +114 -57
- package/dist/shared/server.UVMTOWrk.mjs +26 -0
- package/dist/shared/{server.eWLxY3lq.d.mts → server.gqRxT-yN.d.mts} +8 -8
- package/dist/shared/server.jMTkVNIb.d.ts +42 -0
- package/package.json +40 -12
- package/dist/shared/server.BRoxSiSC.d.mts +0 -12
- package/dist/shared/server.BjiJH9Vo.d.ts +0 -10
- package/dist/shared/server.Cy1vfSiG.d.ts +0 -12
- package/dist/shared/server.QUe9N8P4.d.mts +0 -10
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { mergeErrorMap, mergeMeta, mergeRoute, mergePrefix, mergeTags, isContractProcedure, getContractRouter } from '@orpc/contract';
|
|
1
|
+
import { mergeErrorMap, mergeMeta, mergeRoute, mergePrefix, mergeTags, isContractProcedure, getContractRouter, fallbackContractConfig } from '@orpc/contract';
|
|
2
2
|
export { ValidationError, eventIterator, type } from '@orpc/contract';
|
|
3
|
-
import { P as Procedure, b as addMiddleware, c as createProcedureClient, e as enhanceRouter, l as lazy, s as setHiddenRouterContract, i as isProcedure, d as isLazy, f as createAssertedLazyProcedure
|
|
4
|
-
export { L as LAZY_SYMBOL, p as call, r as createAccessibleLazyRouter, a as createContractedProcedure, h as createORPCErrorConstructorMap, q as getHiddenRouterContract, j as getLazyMeta, n as isStartWithMiddlewares, m as mergeCurrentContext, o as mergeMiddlewares, k as middlewareOutputFn, w as resolveContractProcedures, t as traverseContractProcedures,
|
|
3
|
+
import { P as Procedure, b as addMiddleware, c as createProcedureClient, e as enhanceRouter, l as lazy, s as setHiddenRouterContract, u as unlazy, g as getRouter, i as isProcedure, d as isLazy, f as createAssertedLazyProcedure } from './shared/server.Dp6pyBjF.mjs';
|
|
4
|
+
export { L as LAZY_SYMBOL, p as call, r as createAccessibleLazyRouter, a as createContractedProcedure, h as createORPCErrorConstructorMap, q as getHiddenRouterContract, j as getLazyMeta, n as isStartWithMiddlewares, m as mergeCurrentContext, o as mergeMiddlewares, k as middlewareOutputFn, w as resolveContractProcedures, t as traverseContractProcedures, x as unlazyRouter, v as validateORPCError } from './shared/server.Dp6pyBjF.mjs';
|
|
5
5
|
import { toORPCError } from '@orpc/client';
|
|
6
6
|
export { ORPCError, isDefinedError, safe } from '@orpc/client';
|
|
7
|
-
|
|
7
|
+
import { resolveMaybeOptionalOptions } from '@orpc/shared';
|
|
8
|
+
export { AsyncIteratorClass, EventPublisher, asyncIteratorToStream as eventIteratorToStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@orpc/shared';
|
|
8
9
|
export { getEventMeta, withEventMeta } from '@orpc/standard-server';
|
|
9
10
|
|
|
10
11
|
const DEFAULT_CONFIG = {
|
|
@@ -20,7 +21,7 @@ function fallbackConfig(key, value) {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
function decorateMiddleware(middleware) {
|
|
23
|
-
const decorated = (...args) => middleware(...args);
|
|
24
|
+
const decorated = ((...args) => middleware(...args));
|
|
24
25
|
decorated.mapInput = (mapInput) => {
|
|
25
26
|
const mapped = decorateMiddleware(
|
|
26
27
|
(options, input, ...rest) => middleware(options, mapInput(input), ...rest)
|
|
@@ -150,7 +151,7 @@ class Builder {
|
|
|
150
151
|
/**
|
|
151
152
|
* Sets or overrides the config.
|
|
152
153
|
*
|
|
153
|
-
* @see {@link https://orpc.unnoq.com/docs/
|
|
154
|
+
* @see {@link https://orpc.unnoq.com/docs/client/server-side#middlewares-order Middlewares Order Docs}
|
|
154
155
|
* @see {@link https://orpc.unnoq.com/docs/best-practices/dedupe-middleware#configuration Dedupe Middleware Docs}
|
|
155
156
|
*/
|
|
156
157
|
$config(config) {
|
|
@@ -447,12 +448,26 @@ function implement(contract, config = {}) {
|
|
|
447
448
|
return impl;
|
|
448
449
|
}
|
|
449
450
|
|
|
451
|
+
function inferRPCMethodFromRouter(router) {
|
|
452
|
+
return async (_, path) => {
|
|
453
|
+
const { default: procedure } = await unlazy(getRouter(router, path));
|
|
454
|
+
if (!isProcedure(procedure)) {
|
|
455
|
+
throw new Error(
|
|
456
|
+
`[inferRPCMethodFromRouter] No valid procedure found at path "${path.join(".")}". This may happen when the router is not properly configured.`
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
const method = fallbackContractConfig("defaultMethod", procedure["~orpc"].route.method);
|
|
460
|
+
return method === "HEAD" ? "GET" : method;
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
450
464
|
function createRouterClient(router, ...rest) {
|
|
465
|
+
const options = resolveMaybeOptionalOptions(rest);
|
|
451
466
|
if (isProcedure(router)) {
|
|
452
|
-
const caller = createProcedureClient(router,
|
|
467
|
+
const caller = createProcedureClient(router, options);
|
|
453
468
|
return caller;
|
|
454
469
|
}
|
|
455
|
-
const procedureCaller = isLazy(router) ? createProcedureClient(createAssertedLazyProcedure(router),
|
|
470
|
+
const procedureCaller = isLazy(router) ? createProcedureClient(createAssertedLazyProcedure(router), options) : {};
|
|
456
471
|
const recursive = new Proxy(procedureCaller, {
|
|
457
472
|
get(target, key) {
|
|
458
473
|
if (typeof key !== "string") {
|
|
@@ -471,4 +486,4 @@ function createRouterClient(router, ...rest) {
|
|
|
471
486
|
return recursive;
|
|
472
487
|
}
|
|
473
488
|
|
|
474
|
-
export { Builder, DecoratedProcedure, Procedure, addMiddleware, createActionableClient, createAssertedLazyProcedure, createProcedureClient, createRouterClient, decorateMiddleware, enhanceRouter, fallbackConfig, getRouter, implement, implementerInternal, isLazy, isProcedure, lazy, os, setHiddenRouterContract };
|
|
489
|
+
export { Builder, DecoratedProcedure, Procedure, addMiddleware, createActionableClient, createAssertedLazyProcedure, createProcedureClient, createRouterClient, decorateMiddleware, enhanceRouter, fallbackConfig, getRouter, implement, implementerInternal, inferRPCMethodFromRouter, isLazy, isProcedure, lazy, os, setHiddenRouterContract, unlazy };
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Value } from '@orpc/shared';
|
|
1
|
+
import { Value, Promisable } from '@orpc/shared';
|
|
2
2
|
import { StandardRequest, StandardHeaders } from '@orpc/standard-server';
|
|
3
3
|
import { BatchResponseBodyItem } from '@orpc/standard-server/batch';
|
|
4
|
-
import {
|
|
5
|
-
import { C as Context,
|
|
4
|
+
import { d as StandardHandlerInterceptorOptions, g as StandardHandlerPlugin, e as StandardHandlerOptions } from '../shared/server.gqRxT-yN.mjs';
|
|
5
|
+
import { C as Context, d as ProcedureClientInterceptorOptions } from '../shared/server.CYNGeoCm.mjs';
|
|
6
6
|
import { Meta, ORPCError as ORPCError$1 } from '@orpc/contract';
|
|
7
7
|
import { ORPCError } from '@orpc/client';
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ interface BatchHandlerOptions<T extends Context> {
|
|
|
12
12
|
*
|
|
13
13
|
* @default 10
|
|
14
14
|
*/
|
|
15
|
-
maxSize?: Value<number
|
|
15
|
+
maxSize?: Value<Promisable<number>, [StandardHandlerInterceptorOptions<T>]>;
|
|
16
16
|
/**
|
|
17
17
|
* Map the request before processing it.
|
|
18
18
|
*
|
|
@@ -24,19 +24,19 @@ interface BatchHandlerOptions<T extends Context> {
|
|
|
24
24
|
*
|
|
25
25
|
* @default 207
|
|
26
26
|
*/
|
|
27
|
-
successStatus?: Value<number
|
|
27
|
+
successStatus?: Value<Promisable<number>, [responses: Promise<BatchResponseBodyItem>[], batchOptions: StandardHandlerInterceptorOptions<T>]>;
|
|
28
28
|
/**
|
|
29
29
|
* success batch response headers.
|
|
30
30
|
*
|
|
31
31
|
* @default {}
|
|
32
32
|
*/
|
|
33
|
-
headers?: Value<StandardHeaders
|
|
33
|
+
headers?: Value<Promisable<StandardHeaders>, [responses: Promise<BatchResponseBodyItem>[], batchOptions: StandardHandlerInterceptorOptions<T>]>;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* The Batch
|
|
36
|
+
* The Batch Requests Plugin allows you to combine multiple requests and responses into a single batch,
|
|
37
37
|
* reducing the overhead of sending each one separately.
|
|
38
38
|
*
|
|
39
|
-
* @see {@link https://orpc.unnoq.com/docs/plugins/batch-
|
|
39
|
+
* @see {@link https://orpc.unnoq.com/docs/plugins/batch-requests Batch Requests Plugin Docs}
|
|
40
40
|
*/
|
|
41
41
|
declare class BatchHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
42
42
|
private readonly maxSize;
|
|
@@ -49,8 +49,8 @@ declare class BatchHandlerPlugin<T extends Context> implements StandardHandlerPl
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
interface CORSOptions<T extends Context> {
|
|
52
|
-
origin?: Value<string | readonly string[] | null | undefined
|
|
53
|
-
timingOrigin?: Value<string | readonly string[] | null | undefined
|
|
52
|
+
origin?: Value<Promisable<string | readonly string[] | null | undefined>, [origin: string, options: StandardHandlerInterceptorOptions<T>]>;
|
|
53
|
+
timingOrigin?: Value<Promisable<string | readonly string[] | null | undefined>, [origin: string, options: StandardHandlerInterceptorOptions<T>]>;
|
|
54
54
|
allowMethods?: readonly string[];
|
|
55
55
|
allowHeaders?: readonly string[];
|
|
56
56
|
maxAge?: number;
|
|
@@ -69,6 +69,19 @@ declare class CORSPlugin<T extends Context> implements StandardHandlerPlugin<T>
|
|
|
69
69
|
init(options: StandardHandlerOptions<T>): void;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
interface RequestHeadersPluginContext {
|
|
73
|
+
reqHeaders?: Headers;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The Request Headers Plugin injects a `reqHeaders` instance into the context,
|
|
77
|
+
* allowing access to request headers in oRPC.
|
|
78
|
+
*
|
|
79
|
+
* @see {@link https://orpc.unnoq.com/docs/plugins/request-headers Request Headers Plugin Docs}
|
|
80
|
+
*/
|
|
81
|
+
declare class RequestHeadersPlugin<T extends RequestHeadersPluginContext> implements StandardHandlerPlugin<T> {
|
|
82
|
+
init(options: StandardHandlerOptions<T>): void;
|
|
83
|
+
}
|
|
84
|
+
|
|
72
85
|
interface ResponseHeadersPluginContext {
|
|
73
86
|
resHeaders?: Headers;
|
|
74
87
|
}
|
|
@@ -88,21 +101,21 @@ interface SimpleCsrfProtectionHandlerPluginOptions<T extends Context> {
|
|
|
88
101
|
*
|
|
89
102
|
* @default 'x-csrf-token'
|
|
90
103
|
*/
|
|
91
|
-
headerName?: Value<string
|
|
104
|
+
headerName?: Value<Promisable<string>, [options: StandardHandlerInterceptorOptions<T>]>;
|
|
92
105
|
/**
|
|
93
106
|
* The value of the header to check.
|
|
94
107
|
*
|
|
95
108
|
* @default 'orpc'
|
|
96
109
|
*
|
|
97
110
|
*/
|
|
98
|
-
headerValue?: Value<string
|
|
111
|
+
headerValue?: Value<Promisable<string>, [options: StandardHandlerInterceptorOptions<T>]>;
|
|
99
112
|
/**
|
|
100
113
|
* Exclude a procedure from the plugin.
|
|
101
114
|
*
|
|
102
115
|
* @default false
|
|
103
116
|
*
|
|
104
117
|
*/
|
|
105
|
-
exclude?: Value<boolean
|
|
118
|
+
exclude?: Value<Promisable<boolean>, [options: ProcedureClientInterceptorOptions<T, Record<never, never>, Meta>]>;
|
|
106
119
|
/**
|
|
107
120
|
* The error thrown when the CSRF token is invalid.
|
|
108
121
|
*
|
|
@@ -152,5 +165,5 @@ declare class StrictGetMethodPlugin<T extends Context> implements StandardHandle
|
|
|
152
165
|
init(options: StandardHandlerOptions<T>): void;
|
|
153
166
|
}
|
|
154
167
|
|
|
155
|
-
export { BatchHandlerPlugin, CORSPlugin, ResponseHeadersPlugin, SimpleCsrfProtectionHandlerPlugin, StrictGetMethodPlugin };
|
|
156
|
-
export type { BatchHandlerOptions, CORSOptions, ResponseHeadersPluginContext, SimpleCsrfProtectionHandlerPluginOptions, StrictGetMethodPluginOptions };
|
|
168
|
+
export { BatchHandlerPlugin, CORSPlugin, RequestHeadersPlugin, ResponseHeadersPlugin, SimpleCsrfProtectionHandlerPlugin, StrictGetMethodPlugin };
|
|
169
|
+
export type { BatchHandlerOptions, CORSOptions, RequestHeadersPluginContext, ResponseHeadersPluginContext, SimpleCsrfProtectionHandlerPluginOptions, StrictGetMethodPluginOptions };
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Value } from '@orpc/shared';
|
|
1
|
+
import { Value, Promisable } from '@orpc/shared';
|
|
2
2
|
import { StandardRequest, StandardHeaders } from '@orpc/standard-server';
|
|
3
3
|
import { BatchResponseBodyItem } from '@orpc/standard-server/batch';
|
|
4
|
-
import {
|
|
5
|
-
import { C as Context,
|
|
4
|
+
import { d as StandardHandlerInterceptorOptions, g as StandardHandlerPlugin, e as StandardHandlerOptions } from '../shared/server.Bmh5xd4n.js';
|
|
5
|
+
import { C as Context, d as ProcedureClientInterceptorOptions } from '../shared/server.CYNGeoCm.js';
|
|
6
6
|
import { Meta, ORPCError as ORPCError$1 } from '@orpc/contract';
|
|
7
7
|
import { ORPCError } from '@orpc/client';
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ interface BatchHandlerOptions<T extends Context> {
|
|
|
12
12
|
*
|
|
13
13
|
* @default 10
|
|
14
14
|
*/
|
|
15
|
-
maxSize?: Value<number
|
|
15
|
+
maxSize?: Value<Promisable<number>, [StandardHandlerInterceptorOptions<T>]>;
|
|
16
16
|
/**
|
|
17
17
|
* Map the request before processing it.
|
|
18
18
|
*
|
|
@@ -24,19 +24,19 @@ interface BatchHandlerOptions<T extends Context> {
|
|
|
24
24
|
*
|
|
25
25
|
* @default 207
|
|
26
26
|
*/
|
|
27
|
-
successStatus?: Value<number
|
|
27
|
+
successStatus?: Value<Promisable<number>, [responses: Promise<BatchResponseBodyItem>[], batchOptions: StandardHandlerInterceptorOptions<T>]>;
|
|
28
28
|
/**
|
|
29
29
|
* success batch response headers.
|
|
30
30
|
*
|
|
31
31
|
* @default {}
|
|
32
32
|
*/
|
|
33
|
-
headers?: Value<StandardHeaders
|
|
33
|
+
headers?: Value<Promisable<StandardHeaders>, [responses: Promise<BatchResponseBodyItem>[], batchOptions: StandardHandlerInterceptorOptions<T>]>;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* The Batch
|
|
36
|
+
* The Batch Requests Plugin allows you to combine multiple requests and responses into a single batch,
|
|
37
37
|
* reducing the overhead of sending each one separately.
|
|
38
38
|
*
|
|
39
|
-
* @see {@link https://orpc.unnoq.com/docs/plugins/batch-
|
|
39
|
+
* @see {@link https://orpc.unnoq.com/docs/plugins/batch-requests Batch Requests Plugin Docs}
|
|
40
40
|
*/
|
|
41
41
|
declare class BatchHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
42
42
|
private readonly maxSize;
|
|
@@ -49,8 +49,8 @@ declare class BatchHandlerPlugin<T extends Context> implements StandardHandlerPl
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
interface CORSOptions<T extends Context> {
|
|
52
|
-
origin?: Value<string | readonly string[] | null | undefined
|
|
53
|
-
timingOrigin?: Value<string | readonly string[] | null | undefined
|
|
52
|
+
origin?: Value<Promisable<string | readonly string[] | null | undefined>, [origin: string, options: StandardHandlerInterceptorOptions<T>]>;
|
|
53
|
+
timingOrigin?: Value<Promisable<string | readonly string[] | null | undefined>, [origin: string, options: StandardHandlerInterceptorOptions<T>]>;
|
|
54
54
|
allowMethods?: readonly string[];
|
|
55
55
|
allowHeaders?: readonly string[];
|
|
56
56
|
maxAge?: number;
|
|
@@ -69,6 +69,19 @@ declare class CORSPlugin<T extends Context> implements StandardHandlerPlugin<T>
|
|
|
69
69
|
init(options: StandardHandlerOptions<T>): void;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
interface RequestHeadersPluginContext {
|
|
73
|
+
reqHeaders?: Headers;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The Request Headers Plugin injects a `reqHeaders` instance into the context,
|
|
77
|
+
* allowing access to request headers in oRPC.
|
|
78
|
+
*
|
|
79
|
+
* @see {@link https://orpc.unnoq.com/docs/plugins/request-headers Request Headers Plugin Docs}
|
|
80
|
+
*/
|
|
81
|
+
declare class RequestHeadersPlugin<T extends RequestHeadersPluginContext> implements StandardHandlerPlugin<T> {
|
|
82
|
+
init(options: StandardHandlerOptions<T>): void;
|
|
83
|
+
}
|
|
84
|
+
|
|
72
85
|
interface ResponseHeadersPluginContext {
|
|
73
86
|
resHeaders?: Headers;
|
|
74
87
|
}
|
|
@@ -88,21 +101,21 @@ interface SimpleCsrfProtectionHandlerPluginOptions<T extends Context> {
|
|
|
88
101
|
*
|
|
89
102
|
* @default 'x-csrf-token'
|
|
90
103
|
*/
|
|
91
|
-
headerName?: Value<string
|
|
104
|
+
headerName?: Value<Promisable<string>, [options: StandardHandlerInterceptorOptions<T>]>;
|
|
92
105
|
/**
|
|
93
106
|
* The value of the header to check.
|
|
94
107
|
*
|
|
95
108
|
* @default 'orpc'
|
|
96
109
|
*
|
|
97
110
|
*/
|
|
98
|
-
headerValue?: Value<string
|
|
111
|
+
headerValue?: Value<Promisable<string>, [options: StandardHandlerInterceptorOptions<T>]>;
|
|
99
112
|
/**
|
|
100
113
|
* Exclude a procedure from the plugin.
|
|
101
114
|
*
|
|
102
115
|
* @default false
|
|
103
116
|
*
|
|
104
117
|
*/
|
|
105
|
-
exclude?: Value<boolean
|
|
118
|
+
exclude?: Value<Promisable<boolean>, [options: ProcedureClientInterceptorOptions<T, Record<never, never>, Meta>]>;
|
|
106
119
|
/**
|
|
107
120
|
* The error thrown when the CSRF token is invalid.
|
|
108
121
|
*
|
|
@@ -152,5 +165,5 @@ declare class StrictGetMethodPlugin<T extends Context> implements StandardHandle
|
|
|
152
165
|
init(options: StandardHandlerOptions<T>): void;
|
|
153
166
|
}
|
|
154
167
|
|
|
155
|
-
export { BatchHandlerPlugin, CORSPlugin, ResponseHeadersPlugin, SimpleCsrfProtectionHandlerPlugin, StrictGetMethodPlugin };
|
|
156
|
-
export type { BatchHandlerOptions, CORSOptions, ResponseHeadersPluginContext, SimpleCsrfProtectionHandlerPluginOptions, StrictGetMethodPluginOptions };
|
|
168
|
+
export { BatchHandlerPlugin, CORSPlugin, RequestHeadersPlugin, ResponseHeadersPlugin, SimpleCsrfProtectionHandlerPlugin, StrictGetMethodPlugin };
|
|
169
|
+
export type { BatchHandlerOptions, CORSOptions, RequestHeadersPluginContext, ResponseHeadersPluginContext, SimpleCsrfProtectionHandlerPluginOptions, StrictGetMethodPluginOptions };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { value, isAsyncIteratorObject } from '@orpc/shared';
|
|
2
|
-
import { parseBatchRequest, toBatchResponse } from '@orpc/standard-server/batch';
|
|
1
|
+
import { runWithSpan, value, setSpanError, isAsyncIteratorObject, clone } from '@orpc/shared';
|
|
3
2
|
import { flattenHeader } from '@orpc/standard-server';
|
|
3
|
+
import { parseBatchRequest, toBatchResponse } from '@orpc/standard-server/batch';
|
|
4
|
+
import { toFetchHeaders } from '@orpc/standard-server-fetch';
|
|
4
5
|
import { ORPCError } from '@orpc/client';
|
|
5
6
|
export { S as StrictGetMethodPlugin } from '../shared/server.BW-nUGgA.mjs';
|
|
6
7
|
import '@orpc/contract';
|
|
@@ -26,69 +27,80 @@ class BatchHandlerPlugin {
|
|
|
26
27
|
init(options) {
|
|
27
28
|
options.rootInterceptors ??= [];
|
|
28
29
|
options.rootInterceptors.unshift(async (options2) => {
|
|
29
|
-
|
|
30
|
+
const xHeader = flattenHeader(options2.request.headers["x-orpc-batch"]);
|
|
31
|
+
if (xHeader === void 0) {
|
|
30
32
|
return options2.next();
|
|
31
33
|
}
|
|
32
34
|
let isParsing = false;
|
|
33
35
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return options2.next({ ...options2, request: { ...mapped, body: () => Promise.resolve(mapped.body) } }).then(({ response: response2, matched }) => {
|
|
52
|
-
if (matched) {
|
|
53
|
-
if (response2.body instanceof Blob || response2.body instanceof FormData || isAsyncIteratorObject(response2.body)) {
|
|
54
|
-
return {
|
|
55
|
-
index,
|
|
56
|
-
status: 500,
|
|
57
|
-
headers: {},
|
|
58
|
-
body: "Batch responses do not support file/blob, or event-iterator. Please call this procedure separately outside of the batch request."
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
return { ...response2, index };
|
|
36
|
+
return await runWithSpan({ name: "handle_batch_request" }, async (span) => {
|
|
37
|
+
const mode = xHeader === "buffered" ? "buffered" : "streaming";
|
|
38
|
+
isParsing = true;
|
|
39
|
+
const parsed = parseBatchRequest({ ...options2.request, body: await options2.request.body() });
|
|
40
|
+
isParsing = false;
|
|
41
|
+
span?.setAttribute("batch.mode", mode);
|
|
42
|
+
span?.setAttribute("batch.size", parsed.length);
|
|
43
|
+
const maxSize = await value(this.maxSize, options2);
|
|
44
|
+
if (parsed.length > maxSize) {
|
|
45
|
+
const message = "Batch request size exceeds the maximum allowed size";
|
|
46
|
+
setSpanError(span, message);
|
|
47
|
+
return {
|
|
48
|
+
matched: true,
|
|
49
|
+
response: {
|
|
50
|
+
status: 413,
|
|
51
|
+
headers: {},
|
|
52
|
+
body: message
|
|
62
53
|
}
|
|
63
|
-
|
|
64
|
-
}).catch(() => {
|
|
65
|
-
return { index, status: 500, headers: {}, body: "Internal server error" };
|
|
66
|
-
});
|
|
54
|
+
};
|
|
67
55
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
56
|
+
const responses = parsed.map(
|
|
57
|
+
(request, index) => {
|
|
58
|
+
const mapped = this.mapRequestItem(request, options2);
|
|
59
|
+
return options2.next({ ...options2, request: { ...mapped, body: () => Promise.resolve(mapped.body) } }).then(({ response: response2, matched }) => {
|
|
60
|
+
span?.addEvent(`response.${index}.${matched ? "success" : "not_matched"}`);
|
|
61
|
+
if (matched) {
|
|
62
|
+
if (response2.body instanceof Blob || response2.body instanceof FormData || isAsyncIteratorObject(response2.body)) {
|
|
63
|
+
return {
|
|
64
|
+
index,
|
|
65
|
+
status: 500,
|
|
66
|
+
headers: {},
|
|
67
|
+
body: "Batch responses do not support file/blob, or event-iterator. Please call this procedure separately outside of the batch request."
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return { ...response2, index };
|
|
71
|
+
}
|
|
72
|
+
return { index, status: 404, headers: {}, body: "No procedure matched" };
|
|
73
|
+
}).catch((err) => {
|
|
74
|
+
Promise.reject(err);
|
|
75
|
+
return { index, status: 500, headers: {}, body: "Internal server error" };
|
|
76
|
+
});
|
|
85
77
|
}
|
|
86
|
-
|
|
78
|
+
);
|
|
79
|
+
await Promise.race(responses);
|
|
80
|
+
const status = await value(this.successStatus, responses, options2);
|
|
81
|
+
const headers = await value(this.headers, responses, options2);
|
|
82
|
+
const response = await toBatchResponse({
|
|
83
|
+
status,
|
|
84
|
+
headers,
|
|
85
|
+
mode,
|
|
86
|
+
body: (async function* () {
|
|
87
|
+
const promises = [...responses];
|
|
88
|
+
while (true) {
|
|
89
|
+
const handling = promises.filter((p) => p !== void 0);
|
|
90
|
+
if (handling.length === 0) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const result = await Promise.race(handling);
|
|
94
|
+
promises[result.index] = void 0;
|
|
95
|
+
yield result;
|
|
96
|
+
}
|
|
97
|
+
})()
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
matched: true,
|
|
101
|
+
response
|
|
102
|
+
};
|
|
87
103
|
});
|
|
88
|
-
return {
|
|
89
|
-
matched: true,
|
|
90
|
-
response
|
|
91
|
-
};
|
|
92
104
|
} catch (cause) {
|
|
93
105
|
if (isParsing) {
|
|
94
106
|
return {
|
|
@@ -175,6 +187,22 @@ class CORSPlugin {
|
|
|
175
187
|
}
|
|
176
188
|
}
|
|
177
189
|
|
|
190
|
+
class RequestHeadersPlugin {
|
|
191
|
+
init(options) {
|
|
192
|
+
options.rootInterceptors ??= [];
|
|
193
|
+
options.rootInterceptors.push((interceptorOptions) => {
|
|
194
|
+
const reqHeaders = interceptorOptions.context.reqHeaders ?? toFetchHeaders(interceptorOptions.request.headers);
|
|
195
|
+
return interceptorOptions.next({
|
|
196
|
+
...interceptorOptions,
|
|
197
|
+
context: {
|
|
198
|
+
...interceptorOptions.context,
|
|
199
|
+
reqHeaders
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
178
206
|
class ResponseHeadersPlugin {
|
|
179
207
|
init(options) {
|
|
180
208
|
options.rootInterceptors ??= [];
|
|
@@ -190,7 +218,7 @@ class ResponseHeadersPlugin {
|
|
|
190
218
|
if (!result.matched) {
|
|
191
219
|
return result;
|
|
192
220
|
}
|
|
193
|
-
const responseHeaders = result.response.headers;
|
|
221
|
+
const responseHeaders = clone(result.response.headers);
|
|
194
222
|
for (const [key, value] of resHeaders) {
|
|
195
223
|
if (Array.isArray(responseHeaders[key])) {
|
|
196
224
|
responseHeaders[key].push(value);
|
|
@@ -200,7 +228,13 @@ class ResponseHeadersPlugin {
|
|
|
200
228
|
responseHeaders[key] = value;
|
|
201
229
|
}
|
|
202
230
|
}
|
|
203
|
-
return
|
|
231
|
+
return {
|
|
232
|
+
...result,
|
|
233
|
+
response: {
|
|
234
|
+
...result.response,
|
|
235
|
+
headers: responseHeaders
|
|
236
|
+
}
|
|
237
|
+
};
|
|
204
238
|
});
|
|
205
239
|
}
|
|
206
240
|
}
|
|
@@ -248,4 +282,4 @@ class SimpleCsrfProtectionHandlerPlugin {
|
|
|
248
282
|
}
|
|
249
283
|
}
|
|
250
284
|
|
|
251
|
-
export { BatchHandlerPlugin, CORSPlugin, ResponseHeadersPlugin, SimpleCsrfProtectionHandlerPlugin };
|
|
285
|
+
export { BatchHandlerPlugin, CORSPlugin, RequestHeadersPlugin, ResponseHeadersPlugin, SimpleCsrfProtectionHandlerPlugin };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { toHttpPath, StandardRPCJsonSerializer, StandardRPCSerializer } from '@orpc/client/standard';
|
|
2
2
|
import { ORPCError, toORPCError } from '@orpc/client';
|
|
3
|
-
import { toArray, intercept, parseEmptyableJSON } from '@orpc/shared';
|
|
3
|
+
import { toArray, intercept, runWithSpan, ORPC_NAME, isAsyncIteratorObject, asyncIteratorWithSpan, setSpanError, parseEmptyableJSON, NullProtoObj, value } from '@orpc/shared';
|
|
4
4
|
import { flattenHeader } from '@orpc/standard-server';
|
|
5
|
-
import { c as createProcedureClient, t as traverseContractProcedures, i as isProcedure, u as unlazy, g as getRouter, a as createContractedProcedure } from './server.
|
|
5
|
+
import { c as createProcedureClient, t as traverseContractProcedures, i as isProcedure, u as unlazy, g as getRouter, a as createContractedProcedure } from './server.Dp6pyBjF.mjs';
|
|
6
6
|
|
|
7
7
|
class CompositeStandardHandlerPlugin {
|
|
8
8
|
plugins;
|
|
@@ -39,49 +39,74 @@ class StandardHandler {
|
|
|
39
39
|
this.rootInterceptors,
|
|
40
40
|
{ ...options, request, prefix },
|
|
41
41
|
async (interceptorOptions) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
return runWithSpan(
|
|
43
|
+
{ name: `${request.method} ${request.url.pathname}` },
|
|
44
|
+
async (span) => {
|
|
45
|
+
let step;
|
|
46
|
+
try {
|
|
47
|
+
return await intercept(
|
|
48
|
+
this.interceptors,
|
|
49
|
+
interceptorOptions,
|
|
50
|
+
async ({ request: request2, context, prefix: prefix2 }) => {
|
|
51
|
+
const method = request2.method;
|
|
52
|
+
const url = request2.url;
|
|
53
|
+
const pathname = prefix2 ? url.pathname.replace(prefix2, "") : url.pathname;
|
|
54
|
+
const match = await runWithSpan(
|
|
55
|
+
{ name: "find_procedure" },
|
|
56
|
+
() => this.matcher.match(method, `/${pathname.replace(/^\/|\/$/g, "")}`)
|
|
57
|
+
);
|
|
58
|
+
if (!match) {
|
|
59
|
+
return { matched: false, response: void 0 };
|
|
60
|
+
}
|
|
61
|
+
span?.updateName(`${ORPC_NAME}.${match.path.join("/")}`);
|
|
62
|
+
span?.setAttribute("rpc.system", ORPC_NAME);
|
|
63
|
+
span?.setAttribute("rpc.method", match.path.join("."));
|
|
64
|
+
step = "decode_input";
|
|
65
|
+
let input = await runWithSpan(
|
|
66
|
+
{ name: "decode_input" },
|
|
67
|
+
() => this.codec.decode(request2, match.params, match.procedure)
|
|
68
|
+
);
|
|
69
|
+
step = void 0;
|
|
70
|
+
if (isAsyncIteratorObject(input)) {
|
|
71
|
+
input = asyncIteratorWithSpan(
|
|
72
|
+
{ name: "consume_event_iterator_input", signal: request2.signal },
|
|
73
|
+
input
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
const client = createProcedureClient(match.procedure, {
|
|
77
|
+
context,
|
|
78
|
+
path: match.path,
|
|
79
|
+
interceptors: this.clientInterceptors
|
|
80
|
+
});
|
|
81
|
+
step = "call_procedure";
|
|
82
|
+
const output = await client(input, {
|
|
83
|
+
signal: request2.signal,
|
|
84
|
+
lastEventId: flattenHeader(request2.headers["last-event-id"])
|
|
85
|
+
});
|
|
86
|
+
step = void 0;
|
|
87
|
+
const response = this.codec.encode(output, match.procedure);
|
|
88
|
+
return {
|
|
89
|
+
matched: true,
|
|
90
|
+
response
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
} catch (e) {
|
|
95
|
+
if (step !== "call_procedure") {
|
|
96
|
+
setSpanError(span, e);
|
|
54
97
|
}
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
isDecoding = true;
|
|
61
|
-
const input = await this.codec.decode(request2, match.params, match.procedure);
|
|
62
|
-
isDecoding = false;
|
|
63
|
-
const output = await client(input, {
|
|
64
|
-
signal: request2.signal,
|
|
65
|
-
lastEventId: flattenHeader(request2.headers["last-event-id"])
|
|
66
|
-
});
|
|
67
|
-
const response = this.codec.encode(output, match.procedure);
|
|
98
|
+
const error = step === "decode_input" && !(e instanceof ORPCError) ? new ORPCError("BAD_REQUEST", {
|
|
99
|
+
message: `Malformed request. Ensure the request body is properly formatted and the 'Content-Type' header is set correctly.`,
|
|
100
|
+
cause: e
|
|
101
|
+
}) : toORPCError(e);
|
|
102
|
+
const response = this.codec.encodeError(error);
|
|
68
103
|
return {
|
|
69
104
|
matched: true,
|
|
70
105
|
response
|
|
71
106
|
};
|
|
72
107
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const error = isDecoding && !(e instanceof ORPCError) ? new ORPCError("BAD_REQUEST", {
|
|
76
|
-
message: `Malformed request. Ensure the request body is properly formatted and the 'Content-Type' header is set correctly.`,
|
|
77
|
-
cause: e
|
|
78
|
-
}) : toORPCError(e);
|
|
79
|
-
const response = this.codec.encodeError(error);
|
|
80
|
-
return {
|
|
81
|
-
matched: true,
|
|
82
|
-
response
|
|
83
|
-
};
|
|
84
|
-
}
|
|
108
|
+
}
|
|
109
|
+
);
|
|
85
110
|
}
|
|
86
111
|
);
|
|
87
112
|
}
|
|
@@ -112,10 +137,18 @@ class StandardRPCCodec {
|
|
|
112
137
|
}
|
|
113
138
|
|
|
114
139
|
class StandardRPCMatcher {
|
|
115
|
-
|
|
140
|
+
filter;
|
|
141
|
+
tree = new NullProtoObj();
|
|
116
142
|
pendingRouters = [];
|
|
143
|
+
constructor(options = {}) {
|
|
144
|
+
this.filter = options.filter ?? true;
|
|
145
|
+
}
|
|
117
146
|
init(router, path = []) {
|
|
118
|
-
const laziedOptions = traverseContractProcedures({ router, path }, (
|
|
147
|
+
const laziedOptions = traverseContractProcedures({ router, path }, (traverseOptions) => {
|
|
148
|
+
if (!value(this.filter, traverseOptions)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const { path: path2, contract } = traverseOptions;
|
|
119
152
|
const httpPath = toHttpPath(path2);
|
|
120
153
|
if (isProcedure(contract)) {
|
|
121
154
|
this.tree[httpPath] = {
|
|
@@ -177,7 +210,7 @@ class StandardRPCHandler extends StandardHandler {
|
|
|
177
210
|
constructor(router, options = {}) {
|
|
178
211
|
const jsonSerializer = new StandardRPCJsonSerializer(options);
|
|
179
212
|
const serializer = new StandardRPCSerializer(jsonSerializer);
|
|
180
|
-
const matcher = new StandardRPCMatcher();
|
|
213
|
+
const matcher = new StandardRPCMatcher(options);
|
|
181
214
|
const codec = new StandardRPCCodec(serializer);
|
|
182
215
|
super(router, matcher, codec, options);
|
|
183
216
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { C as Context } from './server.CYNGeoCm.js';
|
|
2
|
+
import { b as StandardHandleOptions } from './server.Bmh5xd4n.js';
|
|
3
|
+
|
|
4
|
+
type FriendlyStandardHandleOptions<T extends Context> = Omit<StandardHandleOptions<T>, 'context'> & (Record<never, never> extends T ? {
|
|
5
|
+
context?: T;
|
|
6
|
+
} : {
|
|
7
|
+
context: T;
|
|
8
|
+
});
|
|
9
|
+
declare function resolveFriendlyStandardHandleOptions<T extends Context>(options: FriendlyStandardHandleOptions<T>): StandardHandleOptions<T>;
|
|
10
|
+
|
|
11
|
+
export { resolveFriendlyStandardHandleOptions as r };
|
|
12
|
+
export type { FriendlyStandardHandleOptions as F };
|