@orpc/server 0.0.0-next.75edb88 → 0.0.0-next.7605f6c
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 +142 -35
- 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 +40 -0
- package/dist/adapters/bun-ws/index.d.mts +36 -0
- package/dist/adapters/bun-ws/index.d.ts +36 -0
- package/dist/adapters/bun-ws/index.mjs +47 -0
- package/dist/adapters/crossws/index.d.mts +33 -0
- package/dist/adapters/crossws/index.d.ts +33 -0
- package/dist/adapters/crossws/index.mjs +45 -0
- package/dist/adapters/fastify/index.d.mts +53 -0
- package/dist/adapters/fastify/index.d.ts +53 -0
- package/dist/adapters/fastify/index.mjs +52 -0
- package/dist/adapters/fetch/index.d.mts +74 -8
- package/dist/adapters/fetch/index.d.ts +74 -8
- package/dist/adapters/fetch/index.mjs +81 -7
- package/dist/adapters/message-port/index.d.mts +57 -0
- package/dist/adapters/message-port/index.d.ts +57 -0
- package/dist/adapters/message-port/index.mjs +55 -0
- package/dist/adapters/node/index.d.mts +51 -9
- package/dist/adapters/node/index.d.ts +51 -9
- package/dist/adapters/node/index.mjs +76 -16
- package/dist/adapters/standard/index.d.mts +8 -13
- package/dist/adapters/standard/index.d.ts +8 -13
- package/dist/adapters/standard/index.mjs +5 -5
- 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 +21 -0
- package/dist/adapters/websocket/index.d.mts +56 -0
- package/dist/adapters/websocket/index.d.ts +56 -0
- package/dist/adapters/websocket/index.mjs +67 -0
- package/dist/adapters/ws/index.d.mts +31 -0
- package/dist/adapters/ws/index.d.ts +31 -0
- package/dist/adapters/ws/index.mjs +37 -0
- package/dist/helpers/index.d.mts +149 -0
- package/dist/helpers/index.d.ts +149 -0
- package/dist/helpers/index.mjs +198 -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 +564 -52
- package/dist/index.d.ts +564 -52
- package/dist/index.mjs +143 -14
- package/dist/plugins/index.d.mts +92 -12
- package/dist/plugins/index.d.ts +92 -12
- package/dist/plugins/index.mjs +142 -66
- package/dist/shared/{server.DsVSuKTu.d.ts → server.7cEtMB30.d.ts} +18 -17
- package/dist/shared/server.B8gYOD5g.d.mts +12 -0
- package/dist/shared/{server.ClO23hLW.d.mts → server.BqadksTP.d.mts} +18 -17
- package/dist/shared/server.C8_sRzQB.d.mts +42 -0
- package/dist/shared/server.ChUyt5-i.d.mts +32 -0
- package/dist/shared/server.ChyoA9XY.d.ts +42 -0
- package/dist/shared/{server.C37gDhSZ.mjs → server.DEBcqOjg.mjs} +130 -76
- package/dist/shared/{server.BVwwTHyO.mjs → server.DZ5BIITo.mjs} +1 -1
- package/dist/shared/server.EfTOZ2Q7.d.ts +12 -0
- package/dist/shared/{server.BW-nUGgA.mjs → server.TEVCLCFC.mjs} +3 -0
- package/dist/shared/{server.DFuJLDuo.mjs → server.ZxHCEN1h.mjs} +87 -51
- package/dist/shared/{server.DQJX4Gnf.d.mts → server.qKsRrdxW.d.mts} +60 -10
- package/dist/shared/{server.DQJX4Gnf.d.ts → server.qKsRrdxW.d.ts} +60 -10
- package/dist/shared/server.yoEB3Fx4.d.ts +32 -0
- package/package.json +85 -11
- package/dist/shared/server.B5yVxwZh.d.mts +0 -17
- package/dist/shared/server.By38lRwX.d.ts +0 -17
- package/dist/shared/server.Cqam9L0P.d.mts +0 -10
- package/dist/shared/server.CuXY46Yy.d.ts +0 -10
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { StandardRPCJsonSerializerOptions } from '@orpc/client/standard';
|
|
2
|
+
import { b as AnyRouter, C as Context, R as Router } from './server.qKsRrdxW.mjs';
|
|
3
|
+
import { i as StandardMatcher, h as StandardMatchResult, e as StandardHandlerOptions, f as StandardHandler } from './server.BqadksTP.mjs';
|
|
4
|
+
import { HTTPPath } from '@orpc/client';
|
|
5
|
+
import { Value } from '@orpc/shared';
|
|
6
|
+
import { T as TraverseContractProcedureCallbackOptions } from './server.C8_sRzQB.mjs';
|
|
7
|
+
|
|
8
|
+
interface StandardRPCMatcherOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Filter procedures. Return `false` to exclude a procedure from matching.
|
|
11
|
+
*
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
filter?: Value<boolean, [options: TraverseContractProcedureCallbackOptions]>;
|
|
15
|
+
}
|
|
16
|
+
declare class StandardRPCMatcher implements StandardMatcher {
|
|
17
|
+
private readonly filter;
|
|
18
|
+
private readonly tree;
|
|
19
|
+
private pendingRouters;
|
|
20
|
+
constructor(options?: StandardRPCMatcherOptions);
|
|
21
|
+
init(router: AnyRouter, path?: readonly string[]): void;
|
|
22
|
+
match(_method: string, pathname: HTTPPath): Promise<StandardMatchResult>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface StandardRPCHandlerOptions<T extends Context> extends StandardHandlerOptions<T>, StandardRPCJsonSerializerOptions, StandardRPCMatcherOptions {
|
|
26
|
+
}
|
|
27
|
+
declare class StandardRPCHandler<T extends Context> extends StandardHandler<T> {
|
|
28
|
+
constructor(router: Router<any, T>, options?: StandardRPCHandlerOptions<T>);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { StandardRPCHandler as a, StandardRPCMatcher as c };
|
|
32
|
+
export type { StandardRPCHandlerOptions as S, StandardRPCMatcherOptions as b };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ErrorMap, EnhanceRouteOptions, MergedErrorMap, AnyContractRouter, AnyContractProcedure } from '@orpc/contract';
|
|
2
|
+
import { a as AnyMiddleware, L as Lazyable, b as AnyRouter, C as Context, c as Lazy, A as AnyProcedure, P as Procedure, M as MergedInitialContext } from './server.qKsRrdxW.js';
|
|
3
|
+
|
|
4
|
+
declare function getRouter<T extends Lazyable<AnyRouter | undefined>>(router: T, path: readonly string[]): T extends Lazy<any> ? Lazy<AnyRouter | undefined> : Lazyable<AnyRouter | undefined>;
|
|
5
|
+
type AccessibleLazyRouter<T extends Lazyable<AnyRouter | undefined>> = T extends Lazy<infer U extends AnyRouter | undefined | Lazy<AnyRouter | undefined>> ? AccessibleLazyRouter<U> : T extends AnyProcedure | undefined ? Lazy<T> : Lazy<T> & {
|
|
6
|
+
[K in keyof T]: T[K] extends Lazyable<AnyRouter> ? AccessibleLazyRouter<T[K]> : never;
|
|
7
|
+
};
|
|
8
|
+
declare function createAccessibleLazyRouter<T extends Lazy<AnyRouter | undefined>>(lazied: T): AccessibleLazyRouter<T>;
|
|
9
|
+
type EnhancedRouter<T extends Lazyable<AnyRouter>, TInitialContext extends Context, TCurrentContext extends Context, TErrorMap extends ErrorMap> = T extends Lazy<infer U extends AnyRouter> ? AccessibleLazyRouter<EnhancedRouter<U, TInitialContext, TCurrentContext, TErrorMap>> : T extends Procedure<infer UInitialContext, infer UCurrentContext, infer UInputSchema, infer UOutputSchema, infer UErrorMap, infer UMeta> ? Procedure<MergedInitialContext<TInitialContext, UInitialContext, TCurrentContext>, UCurrentContext, UInputSchema, UOutputSchema, MergedErrorMap<TErrorMap, UErrorMap>, UMeta> : {
|
|
10
|
+
[K in keyof T]: T[K] extends Lazyable<AnyRouter> ? EnhancedRouter<T[K], TInitialContext, TCurrentContext, TErrorMap> : never;
|
|
11
|
+
};
|
|
12
|
+
interface EnhanceRouterOptions<TErrorMap extends ErrorMap> extends EnhanceRouteOptions {
|
|
13
|
+
middlewares: readonly AnyMiddleware[];
|
|
14
|
+
errorMap: TErrorMap;
|
|
15
|
+
dedupeLeadingMiddlewares: boolean;
|
|
16
|
+
}
|
|
17
|
+
declare function enhanceRouter<T extends Lazyable<AnyRouter>, TInitialContext extends Context, TCurrentContext extends Context, TErrorMap extends ErrorMap>(router: T, options: EnhanceRouterOptions<TErrorMap>): EnhancedRouter<T, TInitialContext, TCurrentContext, TErrorMap>;
|
|
18
|
+
interface TraverseContractProceduresOptions {
|
|
19
|
+
router: AnyContractRouter | AnyRouter;
|
|
20
|
+
path: readonly string[];
|
|
21
|
+
}
|
|
22
|
+
interface TraverseContractProcedureCallbackOptions {
|
|
23
|
+
contract: AnyContractProcedure | AnyProcedure;
|
|
24
|
+
path: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @deprecated Use `TraverseContractProcedureCallbackOptions` instead.
|
|
28
|
+
*/
|
|
29
|
+
type ContractProcedureCallbackOptions = TraverseContractProcedureCallbackOptions;
|
|
30
|
+
interface LazyTraverseContractProceduresOptions {
|
|
31
|
+
router: Lazy<AnyRouter>;
|
|
32
|
+
path: readonly string[];
|
|
33
|
+
}
|
|
34
|
+
declare function traverseContractProcedures(options: TraverseContractProceduresOptions, callback: (options: TraverseContractProcedureCallbackOptions) => void, lazyOptions?: LazyTraverseContractProceduresOptions[]): LazyTraverseContractProceduresOptions[];
|
|
35
|
+
declare function resolveContractProcedures(options: TraverseContractProceduresOptions, callback: (options: TraverseContractProcedureCallbackOptions) => void): Promise<void>;
|
|
36
|
+
type UnlaziedRouter<T extends AnyRouter> = T extends AnyProcedure ? T : {
|
|
37
|
+
[K in keyof T]: T[K] extends Lazyable<infer U extends AnyRouter> ? UnlaziedRouter<U> : never;
|
|
38
|
+
};
|
|
39
|
+
declare function unlazyRouter<T extends AnyRouter>(router: T): Promise<UnlaziedRouter<T>>;
|
|
40
|
+
|
|
41
|
+
export { createAccessibleLazyRouter as c, enhanceRouter as e, getRouter as g, resolveContractProcedures as r, traverseContractProcedures as t, unlazyRouter as u };
|
|
42
|
+
export type { AccessibleLazyRouter as A, ContractProcedureCallbackOptions as C, EnhanceRouterOptions as E, LazyTraverseContractProceduresOptions as L, TraverseContractProcedureCallbackOptions as T, UnlaziedRouter as U, EnhancedRouter as a, TraverseContractProceduresOptions as b };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { isContractProcedure, ValidationError, mergePrefix, mergeErrorMap, enhanceRoute } from '@orpc/contract';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { isContractProcedure, validateORPCError, ValidationError, mergePrefix, mergeErrorMap, enhanceRoute } from '@orpc/contract';
|
|
2
|
+
import { resolveMaybeOptionalOptions, toArray, value, runWithSpan, intercept, isAsyncIteratorObject, overlayProxy, asyncIteratorWithSpan, isTypescriptObject } from '@orpc/shared';
|
|
3
|
+
import { ORPCError, mapEventIterator } from '@orpc/client';
|
|
4
|
+
import { HibernationEventIterator } from '@orpc/standard-server';
|
|
4
5
|
|
|
5
6
|
const LAZY_SYMBOL = Symbol("ORPC_LAZY_SYMBOL");
|
|
6
7
|
function lazy(loader, meta = {}) {
|
|
@@ -46,6 +47,9 @@ function addMiddleware(middlewares, addition) {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
class Procedure {
|
|
50
|
+
/**
|
|
51
|
+
* This property holds the defined options.
|
|
52
|
+
*/
|
|
49
53
|
"~orpc";
|
|
50
54
|
constructor(def) {
|
|
51
55
|
this["~orpc"] = def;
|
|
@@ -68,14 +72,15 @@ function createORPCErrorConstructorMap(errors) {
|
|
|
68
72
|
if (typeof code !== "string") {
|
|
69
73
|
return Reflect.get(target, code);
|
|
70
74
|
}
|
|
71
|
-
const item = (...
|
|
75
|
+
const item = (...rest) => {
|
|
76
|
+
const options = resolveMaybeOptionalOptions(rest);
|
|
72
77
|
const config = errors[code];
|
|
73
78
|
return new ORPCError(code, {
|
|
74
79
|
defined: Boolean(config),
|
|
75
80
|
status: config?.status,
|
|
76
|
-
message: options
|
|
77
|
-
data: options
|
|
78
|
-
cause: options
|
|
81
|
+
message: options.message ?? config?.message,
|
|
82
|
+
data: options.data,
|
|
83
|
+
cause: options.cause
|
|
79
84
|
});
|
|
80
85
|
};
|
|
81
86
|
return item;
|
|
@@ -83,54 +88,64 @@ function createORPCErrorConstructorMap(errors) {
|
|
|
83
88
|
});
|
|
84
89
|
return proxy;
|
|
85
90
|
}
|
|
86
|
-
async function validateORPCError(map, error) {
|
|
87
|
-
const { code, status, message, data, cause, defined } = error;
|
|
88
|
-
const config = map?.[error.code];
|
|
89
|
-
if (!config || fallbackORPCErrorStatus(error.code, config.status) !== error.status) {
|
|
90
|
-
return defined ? new ORPCError(code, { defined: false, status, message, data, cause }) : error;
|
|
91
|
-
}
|
|
92
|
-
if (!config.data) {
|
|
93
|
-
return defined ? error : new ORPCError(code, { defined: true, status, message, data, cause });
|
|
94
|
-
}
|
|
95
|
-
const validated = await config.data["~standard"].validate(error.data);
|
|
96
|
-
if (validated.issues) {
|
|
97
|
-
return defined ? new ORPCError(code, { defined: false, status, message, data, cause }) : error;
|
|
98
|
-
}
|
|
99
|
-
return new ORPCError(code, { defined: true, status, message, data: validated.value, cause });
|
|
100
|
-
}
|
|
101
91
|
|
|
102
92
|
function middlewareOutputFn(output) {
|
|
103
93
|
return { output, context: {} };
|
|
104
94
|
}
|
|
105
95
|
|
|
106
|
-
function createProcedureClient(lazyableProcedure, ...
|
|
96
|
+
function createProcedureClient(lazyableProcedure, ...rest) {
|
|
97
|
+
const options = resolveMaybeOptionalOptions(rest);
|
|
107
98
|
return async (...[input, callerOptions]) => {
|
|
108
|
-
const path = options
|
|
99
|
+
const path = toArray(options.path);
|
|
109
100
|
const { default: procedure } = await unlazy(lazyableProcedure);
|
|
110
101
|
const clientContext = callerOptions?.context ?? {};
|
|
111
|
-
const context = await value(options
|
|
102
|
+
const context = await value(options.context ?? {}, clientContext);
|
|
112
103
|
const errors = createORPCErrorConstructorMap(procedure["~orpc"].errorMap);
|
|
104
|
+
const validateError = async (e) => {
|
|
105
|
+
if (e instanceof ORPCError) {
|
|
106
|
+
return await validateORPCError(procedure["~orpc"].errorMap, e);
|
|
107
|
+
}
|
|
108
|
+
return e;
|
|
109
|
+
};
|
|
113
110
|
try {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
{
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
111
|
+
const output = await runWithSpan(
|
|
112
|
+
{ name: "call_procedure", signal: callerOptions?.signal },
|
|
113
|
+
(span) => {
|
|
114
|
+
span?.setAttribute("procedure.path", [...path]);
|
|
115
|
+
return intercept(
|
|
116
|
+
toArray(options.interceptors),
|
|
117
|
+
{
|
|
118
|
+
context,
|
|
119
|
+
input,
|
|
120
|
+
// input only optional when it undefinable so we can safely cast it
|
|
121
|
+
errors,
|
|
122
|
+
path,
|
|
123
|
+
procedure,
|
|
124
|
+
signal: callerOptions?.signal,
|
|
125
|
+
lastEventId: callerOptions?.lastEventId
|
|
126
|
+
},
|
|
127
|
+
(interceptorOptions) => executeProcedureInternal(interceptorOptions.procedure, interceptorOptions)
|
|
128
|
+
);
|
|
129
|
+
}
|
|
127
130
|
);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
if (isAsyncIteratorObject(output)) {
|
|
132
|
+
if (output instanceof HibernationEventIterator) {
|
|
133
|
+
return output;
|
|
134
|
+
}
|
|
135
|
+
return overlayProxy(output, mapEventIterator(
|
|
136
|
+
asyncIteratorWithSpan(
|
|
137
|
+
{ name: "consume_event_iterator_output", signal: callerOptions?.signal },
|
|
138
|
+
output
|
|
139
|
+
),
|
|
140
|
+
{
|
|
141
|
+
value: (v) => v,
|
|
142
|
+
error: (e) => validateError(e)
|
|
143
|
+
}
|
|
144
|
+
));
|
|
131
145
|
}
|
|
132
|
-
|
|
133
|
-
|
|
146
|
+
return output;
|
|
147
|
+
} catch (e) {
|
|
148
|
+
throw await validateError(e);
|
|
134
149
|
}
|
|
135
150
|
};
|
|
136
151
|
}
|
|
@@ -139,31 +154,49 @@ async function validateInput(procedure, input) {
|
|
|
139
154
|
if (!schema) {
|
|
140
155
|
return input;
|
|
141
156
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
157
|
+
return runWithSpan(
|
|
158
|
+
{ name: "validate_input" },
|
|
159
|
+
async () => {
|
|
160
|
+
const result = await schema["~standard"].validate(input);
|
|
161
|
+
if (result.issues) {
|
|
162
|
+
throw new ORPCError("BAD_REQUEST", {
|
|
163
|
+
message: "Input validation failed",
|
|
164
|
+
data: {
|
|
165
|
+
issues: result.issues
|
|
166
|
+
},
|
|
167
|
+
cause: new ValidationError({
|
|
168
|
+
message: "Input validation failed",
|
|
169
|
+
issues: result.issues,
|
|
170
|
+
data: input
|
|
171
|
+
})
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return result.value;
|
|
175
|
+
}
|
|
176
|
+
);
|
|
153
177
|
}
|
|
154
178
|
async function validateOutput(procedure, output) {
|
|
155
179
|
const schema = procedure["~orpc"].outputSchema;
|
|
156
180
|
if (!schema) {
|
|
157
181
|
return output;
|
|
158
182
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
183
|
+
return runWithSpan(
|
|
184
|
+
{ name: "validate_output" },
|
|
185
|
+
async () => {
|
|
186
|
+
const result = await schema["~standard"].validate(output);
|
|
187
|
+
if (result.issues) {
|
|
188
|
+
throw new ORPCError("INTERNAL_SERVER_ERROR", {
|
|
189
|
+
message: "Output validation failed",
|
|
190
|
+
cause: new ValidationError({
|
|
191
|
+
message: "Output validation failed",
|
|
192
|
+
issues: result.issues,
|
|
193
|
+
data: output
|
|
194
|
+
})
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return result.value;
|
|
198
|
+
}
|
|
199
|
+
);
|
|
167
200
|
}
|
|
168
201
|
async function executeProcedureInternal(procedure, options) {
|
|
169
202
|
const middlewares = procedure["~orpc"].middlewares;
|
|
@@ -175,17 +208,28 @@ async function executeProcedureInternal(procedure, options) {
|
|
|
175
208
|
currentInput = await validateInput(procedure, currentInput);
|
|
176
209
|
}
|
|
177
210
|
const mid = middlewares[index];
|
|
178
|
-
const output = mid ?
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
context
|
|
186
|
-
|
|
211
|
+
const output = mid ? await runWithSpan(
|
|
212
|
+
{ name: `middleware.${mid.name}`, signal: options.signal },
|
|
213
|
+
async (span) => {
|
|
214
|
+
span?.setAttribute("middleware.index", index);
|
|
215
|
+
span?.setAttribute("middleware.name", mid.name);
|
|
216
|
+
const result = await mid({
|
|
217
|
+
...options,
|
|
218
|
+
context,
|
|
219
|
+
next: async (...[nextOptions]) => {
|
|
220
|
+
const nextContext = nextOptions?.context ?? {};
|
|
221
|
+
return {
|
|
222
|
+
output: await next(index + 1, mergeCurrentContext(context, nextContext), currentInput),
|
|
223
|
+
context: nextContext
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}, currentInput, middlewareOutputFn);
|
|
227
|
+
return result.output;
|
|
187
228
|
}
|
|
188
|
-
|
|
229
|
+
) : await runWithSpan(
|
|
230
|
+
{ name: "handler", signal: options.signal },
|
|
231
|
+
() => procedure["~orpc"].handler({ ...options, context, input: currentInput })
|
|
232
|
+
);
|
|
189
233
|
if (index === outputValidationIndex) {
|
|
190
234
|
return await validateOutput(procedure, output);
|
|
191
235
|
}
|
|
@@ -219,6 +263,9 @@ function getRouter(router, path) {
|
|
|
219
263
|
if (isProcedure(current)) {
|
|
220
264
|
return void 0;
|
|
221
265
|
}
|
|
266
|
+
if (!isTypescriptObject(current)) {
|
|
267
|
+
return void 0;
|
|
268
|
+
}
|
|
222
269
|
if (!isLazy(current)) {
|
|
223
270
|
current = current[segment];
|
|
224
271
|
continue;
|
|
@@ -273,6 +320,9 @@ function enhanceRouter(router, options) {
|
|
|
273
320
|
});
|
|
274
321
|
return enhanced2;
|
|
275
322
|
}
|
|
323
|
+
if (typeof router !== "object" || router === null) {
|
|
324
|
+
return router;
|
|
325
|
+
}
|
|
276
326
|
const enhanced = {};
|
|
277
327
|
for (const key in router) {
|
|
278
328
|
enhanced[key] = enhanceRouter(router[key], options);
|
|
@@ -281,7 +331,7 @@ function enhanceRouter(router, options) {
|
|
|
281
331
|
}
|
|
282
332
|
function traverseContractProcedures(options, callback, lazyOptions = []) {
|
|
283
333
|
let currentRouter = options.router;
|
|
284
|
-
const hiddenContract = getHiddenRouterContract(options.router);
|
|
334
|
+
const hiddenContract = isTypescriptObject(options.router) ? getHiddenRouterContract(options.router) : void 0;
|
|
285
335
|
if (hiddenContract !== void 0) {
|
|
286
336
|
currentRouter = hiddenContract;
|
|
287
337
|
}
|
|
@@ -295,7 +345,7 @@ function traverseContractProcedures(options, callback, lazyOptions = []) {
|
|
|
295
345
|
contract: currentRouter,
|
|
296
346
|
path: options.path
|
|
297
347
|
});
|
|
298
|
-
} else {
|
|
348
|
+
} else if (typeof currentRouter === "object" && currentRouter !== null) {
|
|
299
349
|
for (const key in currentRouter) {
|
|
300
350
|
traverseContractProcedures(
|
|
301
351
|
{
|
|
@@ -326,6 +376,9 @@ async function unlazyRouter(router) {
|
|
|
326
376
|
if (isProcedure(router)) {
|
|
327
377
|
return router;
|
|
328
378
|
}
|
|
379
|
+
if (typeof router !== "object" || router === null) {
|
|
380
|
+
return router;
|
|
381
|
+
}
|
|
329
382
|
const unlazied = {};
|
|
330
383
|
for (const key in router) {
|
|
331
384
|
const item = router[key];
|
|
@@ -358,7 +411,8 @@ function createContractedProcedure(procedure, contract) {
|
|
|
358
411
|
});
|
|
359
412
|
}
|
|
360
413
|
function call(procedure, input, ...rest) {
|
|
361
|
-
|
|
414
|
+
const options = resolveMaybeOptionalOptions(rest);
|
|
415
|
+
return createProcedureClient(procedure, options)(input, options);
|
|
362
416
|
}
|
|
363
417
|
|
|
364
|
-
export { LAZY_SYMBOL as L, Procedure as P, createContractedProcedure as a, addMiddleware as b, createProcedureClient as c, isLazy as d, enhanceRouter as e, createAssertedLazyProcedure as f, getRouter as g, createORPCErrorConstructorMap as h, isProcedure as i, getLazyMeta as j, middlewareOutputFn as k, lazy as l, mergeCurrentContext as m, isStartWithMiddlewares as n, mergeMiddlewares as o, call as p, getHiddenRouterContract as q, createAccessibleLazyRouter as r, setHiddenRouterContract as s, traverseContractProcedures as t, unlazy as u,
|
|
418
|
+
export { LAZY_SYMBOL as L, Procedure as P, createContractedProcedure as a, addMiddleware as b, createProcedureClient as c, isLazy as d, enhanceRouter as e, createAssertedLazyProcedure as f, getRouter as g, createORPCErrorConstructorMap as h, isProcedure as i, getLazyMeta as j, middlewareOutputFn as k, lazy as l, mergeCurrentContext as m, isStartWithMiddlewares as n, mergeMiddlewares as o, call as p, getHiddenRouterContract as q, createAccessibleLazyRouter as r, setHiddenRouterContract as s, traverseContractProcedures as t, unlazy as u, resolveContractProcedures as v, unlazyRouter as w };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { C as Context } from './server.qKsRrdxW.js';
|
|
2
|
+
import { b as StandardHandleOptions } from './server.7cEtMB30.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 };
|
|
@@ -3,6 +3,9 @@ import { ORPCError, fallbackContractConfig } from '@orpc/contract';
|
|
|
3
3
|
const STRICT_GET_METHOD_PLUGIN_IS_GET_METHOD_CONTEXT_SYMBOL = Symbol("STRICT_GET_METHOD_PLUGIN_IS_GET_METHOD_CONTEXT");
|
|
4
4
|
class StrictGetMethodPlugin {
|
|
5
5
|
error;
|
|
6
|
+
/**
|
|
7
|
+
* make sure execute before batch plugin to get real method
|
|
8
|
+
*/
|
|
6
9
|
order = 7e6;
|
|
7
10
|
constructor(options = {}) {
|
|
8
11
|
this.error = options.error ?? new ORPCError("METHOD_NOT_SUPPORTED");
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { toHttpPath, StandardRPCJsonSerializer, StandardRPCSerializer } from '@orpc/client/standard';
|
|
2
|
-
import { toArray, intercept, parseEmptyableJSON } from '@orpc/shared';
|
|
3
|
-
import '@orpc/standard-server/batch';
|
|
4
2
|
import { ORPCError, toORPCError } from '@orpc/client';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { toArray, intercept, runWithSpan, ORPC_NAME, isAsyncIteratorObject, asyncIteratorWithSpan, setSpanError, parseEmptyableJSON, NullProtoObj, value } from '@orpc/shared';
|
|
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.DEBcqOjg.mjs';
|
|
7
6
|
|
|
8
7
|
class CompositeStandardHandlerPlugin {
|
|
9
8
|
plugins;
|
|
10
9
|
constructor(plugins = []) {
|
|
11
10
|
this.plugins = [...plugins].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
12
11
|
}
|
|
13
|
-
init(options) {
|
|
12
|
+
init(options, router) {
|
|
14
13
|
for (const plugin of this.plugins) {
|
|
15
|
-
plugin.init?.(options);
|
|
14
|
+
plugin.init?.(options, router);
|
|
16
15
|
}
|
|
17
16
|
}
|
|
18
17
|
}
|
|
@@ -22,7 +21,7 @@ class StandardHandler {
|
|
|
22
21
|
this.matcher = matcher;
|
|
23
22
|
this.codec = codec;
|
|
24
23
|
const plugins = new CompositeStandardHandlerPlugin(options.plugins);
|
|
25
|
-
plugins.init(options);
|
|
24
|
+
plugins.init(options, router);
|
|
26
25
|
this.interceptors = toArray(options.interceptors);
|
|
27
26
|
this.clientInterceptors = toArray(options.clientInterceptors);
|
|
28
27
|
this.rootInterceptors = toArray(options.rootInterceptors);
|
|
@@ -40,47 +39,74 @@ class StandardHandler {
|
|
|
40
39
|
this.rootInterceptors,
|
|
41
40
|
{ ...options, request, prefix },
|
|
42
41
|
async (interceptorOptions) => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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);
|
|
55
97
|
}
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
isDecoding = true;
|
|
62
|
-
const input = await this.codec.decode(request2, match.params, match.procedure);
|
|
63
|
-
isDecoding = false;
|
|
64
|
-
const lastEventId = Array.isArray(request2.headers["last-event-id"]) ? request2.headers["last-event-id"].at(-1) : request2.headers["last-event-id"];
|
|
65
|
-
const output = await client(input, { signal: request2.signal, lastEventId });
|
|
66
|
-
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);
|
|
67
103
|
return {
|
|
68
104
|
matched: true,
|
|
69
105
|
response
|
|
70
106
|
};
|
|
71
107
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const error = isDecoding && !(e instanceof ORPCError) ? new ORPCError("BAD_REQUEST", {
|
|
75
|
-
message: `Malformed request. Ensure the request body is properly formatted and the 'Content-Type' header is set correctly.`,
|
|
76
|
-
cause: e
|
|
77
|
-
}) : toORPCError(e);
|
|
78
|
-
const response = this.codec.encodeError(error);
|
|
79
|
-
return {
|
|
80
|
-
matched: true,
|
|
81
|
-
response
|
|
82
|
-
};
|
|
83
|
-
}
|
|
108
|
+
}
|
|
109
|
+
);
|
|
84
110
|
}
|
|
85
111
|
);
|
|
86
112
|
}
|
|
@@ -95,6 +121,13 @@ class StandardRPCCodec {
|
|
|
95
121
|
return this.serializer.deserialize(serialized);
|
|
96
122
|
}
|
|
97
123
|
encode(output, _procedure) {
|
|
124
|
+
if (output instanceof ReadableStream) {
|
|
125
|
+
return {
|
|
126
|
+
status: 200,
|
|
127
|
+
headers: {},
|
|
128
|
+
body: output
|
|
129
|
+
};
|
|
130
|
+
}
|
|
98
131
|
return {
|
|
99
132
|
status: 200,
|
|
100
133
|
headers: {},
|
|
@@ -111,10 +144,18 @@ class StandardRPCCodec {
|
|
|
111
144
|
}
|
|
112
145
|
|
|
113
146
|
class StandardRPCMatcher {
|
|
114
|
-
|
|
147
|
+
filter;
|
|
148
|
+
tree = new NullProtoObj();
|
|
115
149
|
pendingRouters = [];
|
|
150
|
+
constructor(options = {}) {
|
|
151
|
+
this.filter = options.filter ?? true;
|
|
152
|
+
}
|
|
116
153
|
init(router, path = []) {
|
|
117
|
-
const laziedOptions = traverseContractProcedures({ router, path }, (
|
|
154
|
+
const laziedOptions = traverseContractProcedures({ router, path }, (traverseOptions) => {
|
|
155
|
+
if (!value(this.filter, traverseOptions)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const { path: path2, contract } = traverseOptions;
|
|
118
159
|
const httpPath = toHttpPath(path2);
|
|
119
160
|
if (isProcedure(contract)) {
|
|
120
161
|
this.tree[httpPath] = {
|
|
@@ -173,15 +214,10 @@ class StandardRPCMatcher {
|
|
|
173
214
|
}
|
|
174
215
|
|
|
175
216
|
class StandardRPCHandler extends StandardHandler {
|
|
176
|
-
constructor(router, options) {
|
|
177
|
-
options.plugins ??= [];
|
|
178
|
-
const strictGetMethodPluginEnabled = options.strictGetMethodPluginEnabled ?? true;
|
|
179
|
-
if (strictGetMethodPluginEnabled) {
|
|
180
|
-
options.plugins.push(new StrictGetMethodPlugin());
|
|
181
|
-
}
|
|
217
|
+
constructor(router, options = {}) {
|
|
182
218
|
const jsonSerializer = new StandardRPCJsonSerializer(options);
|
|
183
219
|
const serializer = new StandardRPCSerializer(jsonSerializer);
|
|
184
|
-
const matcher = new StandardRPCMatcher();
|
|
220
|
+
const matcher = new StandardRPCMatcher(options);
|
|
185
221
|
const codec = new StandardRPCCodec(serializer);
|
|
186
222
|
super(router, matcher, codec, options);
|
|
187
223
|
}
|