@orpc/server 0.0.0-next.b11d127 → 0.0.0-next.b12bcdb
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 -8
- 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 +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/fetch/index.d.mts +64 -10
- package/dist/adapters/fetch/index.d.ts +64 -10
- package/dist/adapters/fetch/index.mjs +80 -5
- 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 +40 -10
- package/dist/adapters/node/index.d.ts +40 -10
- package/dist/adapters/node/index.mjs +76 -14
- 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 +7 -0
- package/dist/adapters/websocket/index.d.mts +54 -0
- package/dist/adapters/websocket/index.d.ts +54 -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 +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 +24 -50
- package/dist/index.d.ts +24 -50
- package/dist/index.mjs +28 -10
- package/dist/plugins/index.d.mts +28 -15
- package/dist/plugins/index.d.ts +28 -15
- package/dist/plugins/index.mjs +99 -66
- package/dist/shared/{server.DPWk5pjW.d.mts → server.B4BGqy3Y.d.mts} +10 -9
- package/dist/shared/{server.DPWk5pjW.d.ts → server.B4BGqy3Y.d.ts} +10 -9
- package/dist/shared/server.COL12UTb.d.ts +32 -0
- package/dist/shared/server.CVKCo60T.d.mts +12 -0
- package/dist/shared/{server.DG7Tamti.mjs → server.CaqDCZX1.mjs} +116 -74
- package/dist/shared/server.Cb6yD7DZ.d.ts +42 -0
- package/dist/shared/server.Ck-gOLzq.d.mts +32 -0
- package/dist/shared/{server.D5fBlF9j.d.ts → server.DBCUJijK.d.mts} +11 -11
- package/dist/shared/server.DNtJ-p60.d.ts +12 -0
- package/dist/shared/{server.DY7OKEoj.d.mts → server.DPIFWpxG.d.ts} +11 -11
- package/dist/shared/{server.BVwwTHyO.mjs → server.DZ5BIITo.mjs} +1 -1
- package/dist/shared/server.DzV1hr3z.d.mts +42 -0
- package/dist/shared/server.UVMTOWrk.mjs +26 -0
- package/dist/shared/{server.qf03T-Xn.mjs → server.vzZSq5UM.mjs} +80 -51
- package/package.json +73 -8
- package/dist/shared/server.CN0534_m.d.mts +0 -18
- package/dist/shared/server.CjlA3NKP.d.ts +0 -10
- package/dist/shared/server.CuD15qZB.d.ts +0 -18
- package/dist/shared/server.DjgtLwKi.d.mts +0 -10
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { value, isAsyncIteratorObject } from '@orpc/shared';
|
|
1
|
+
import { runWithSpan, value, setSpanError, isAsyncIteratorObject, clone } from '@orpc/shared';
|
|
2
|
+
import { flattenHeader } from '@orpc/standard-server';
|
|
2
3
|
import { parseBatchRequest, toBatchResponse } from '@orpc/standard-server/batch';
|
|
4
|
+
import { toFetchHeaders } from '@orpc/standard-server-fetch';
|
|
3
5
|
import { ORPCError } from '@orpc/client';
|
|
4
6
|
export { S as StrictGetMethodPlugin } from '../shared/server.BW-nUGgA.mjs';
|
|
5
7
|
import '@orpc/contract';
|
|
@@ -25,69 +27,80 @@ class BatchHandlerPlugin {
|
|
|
25
27
|
init(options) {
|
|
26
28
|
options.rootInterceptors ??= [];
|
|
27
29
|
options.rootInterceptors.unshift(async (options2) => {
|
|
28
|
-
|
|
30
|
+
const xHeader = flattenHeader(options2.request.headers["x-orpc-batch"]);
|
|
31
|
+
if (xHeader === void 0) {
|
|
29
32
|
return options2.next();
|
|
30
33
|
}
|
|
31
34
|
let isParsing = false;
|
|
32
35
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return options2.next({ ...options2, request: { ...mapped, body: () => Promise.resolve(mapped.body) } }).then(({ response: response2, matched }) => {
|
|
51
|
-
if (matched) {
|
|
52
|
-
if (response2.body instanceof Blob || response2.body instanceof FormData || isAsyncIteratorObject(response2.body)) {
|
|
53
|
-
return {
|
|
54
|
-
index,
|
|
55
|
-
status: 500,
|
|
56
|
-
headers: {},
|
|
57
|
-
body: "Batch responses do not support file/blob, or event-iterator. Please call this procedure separately outside of the batch request."
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
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
|
|
61
53
|
}
|
|
62
|
-
|
|
63
|
-
}).catch(() => {
|
|
64
|
-
return { index, status: 500, headers: {}, body: "Internal server error" };
|
|
65
|
-
});
|
|
54
|
+
};
|
|
66
55
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
+
});
|
|
84
77
|
}
|
|
85
|
-
|
|
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
|
+
};
|
|
86
103
|
});
|
|
87
|
-
return {
|
|
88
|
-
matched: true,
|
|
89
|
-
response
|
|
90
|
-
};
|
|
91
104
|
} catch (cause) {
|
|
92
105
|
if (isParsing) {
|
|
93
106
|
return {
|
|
@@ -123,13 +136,11 @@ class CORSPlugin {
|
|
|
123
136
|
resHeaders["access-control-max-age"] = this.options.maxAge.toString();
|
|
124
137
|
}
|
|
125
138
|
if (this.options.allowMethods?.length) {
|
|
126
|
-
resHeaders["access-control-allow-methods"] = this.options.allowMethods
|
|
139
|
+
resHeaders["access-control-allow-methods"] = flattenHeader(this.options.allowMethods);
|
|
127
140
|
}
|
|
128
141
|
const allowHeaders = this.options.allowHeaders ?? interceptorOptions.request.headers["access-control-request-headers"];
|
|
129
|
-
if (
|
|
130
|
-
resHeaders["access-control-allow-headers"] = allowHeaders
|
|
131
|
-
} else if (typeof allowHeaders === "string") {
|
|
132
|
-
resHeaders["access-control-allow-headers"] = allowHeaders;
|
|
142
|
+
if (typeof allowHeaders === "string" || allowHeaders?.length) {
|
|
143
|
+
resHeaders["access-control-allow-headers"] = flattenHeader(allowHeaders);
|
|
133
144
|
}
|
|
134
145
|
return {
|
|
135
146
|
matched: true,
|
|
@@ -147,7 +158,7 @@ class CORSPlugin {
|
|
|
147
158
|
if (!result.matched) {
|
|
148
159
|
return result;
|
|
149
160
|
}
|
|
150
|
-
const origin =
|
|
161
|
+
const origin = flattenHeader(interceptorOptions.request.headers.origin) ?? "";
|
|
151
162
|
const allowedOrigin = await value(this.options.origin, origin, interceptorOptions);
|
|
152
163
|
const allowedOriginArr = Array.isArray(allowedOrigin) ? allowedOrigin : [allowedOrigin];
|
|
153
164
|
if (allowedOriginArr.includes("*")) {
|
|
@@ -169,13 +180,29 @@ class CORSPlugin {
|
|
|
169
180
|
result.response.headers["access-control-allow-credentials"] = "true";
|
|
170
181
|
}
|
|
171
182
|
if (this.options.exposeHeaders?.length) {
|
|
172
|
-
result.response.headers["access-control-expose-headers"] = this.options.exposeHeaders
|
|
183
|
+
result.response.headers["access-control-expose-headers"] = flattenHeader(this.options.exposeHeaders);
|
|
173
184
|
}
|
|
174
185
|
return result;
|
|
175
186
|
});
|
|
176
187
|
}
|
|
177
188
|
}
|
|
178
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
|
+
|
|
179
206
|
class ResponseHeadersPlugin {
|
|
180
207
|
init(options) {
|
|
181
208
|
options.rootInterceptors ??= [];
|
|
@@ -191,7 +218,7 @@ class ResponseHeadersPlugin {
|
|
|
191
218
|
if (!result.matched) {
|
|
192
219
|
return result;
|
|
193
220
|
}
|
|
194
|
-
const responseHeaders = result.response.headers;
|
|
221
|
+
const responseHeaders = clone(result.response.headers);
|
|
195
222
|
for (const [key, value] of resHeaders) {
|
|
196
223
|
if (Array.isArray(responseHeaders[key])) {
|
|
197
224
|
responseHeaders[key].push(value);
|
|
@@ -201,7 +228,13 @@ class ResponseHeadersPlugin {
|
|
|
201
228
|
responseHeaders[key] = value;
|
|
202
229
|
}
|
|
203
230
|
}
|
|
204
|
-
return
|
|
231
|
+
return {
|
|
232
|
+
...result,
|
|
233
|
+
response: {
|
|
234
|
+
...result.response,
|
|
235
|
+
headers: responseHeaders
|
|
236
|
+
}
|
|
237
|
+
};
|
|
205
238
|
});
|
|
206
239
|
}
|
|
207
240
|
}
|
|
@@ -249,4 +282,4 @@ class SimpleCsrfProtectionHandlerPlugin {
|
|
|
249
282
|
}
|
|
250
283
|
}
|
|
251
284
|
|
|
252
|
-
export { BatchHandlerPlugin, CORSPlugin, ResponseHeadersPlugin, SimpleCsrfProtectionHandlerPlugin };
|
|
285
|
+
export { BatchHandlerPlugin, CORSPlugin, RequestHeadersPlugin, ResponseHeadersPlugin, SimpleCsrfProtectionHandlerPlugin };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ORPCErrorCode, ORPCErrorOptions, ORPCError, HTTPPath, ClientContext, Client } from '@orpc/client';
|
|
2
2
|
import { ErrorMap, ErrorMapItem, InferSchemaInput, AnySchema, Meta, ContractProcedureDef, InferSchemaOutput, ErrorFromErrorMap, AnyContractRouter, ContractProcedure } from '@orpc/contract';
|
|
3
|
-
import { MaybeOptionalOptions, Promisable, Interceptor, Value } from '@orpc/shared';
|
|
3
|
+
import { MaybeOptionalOptions, Promisable, Interceptor, PromiseWithError, Value } from '@orpc/shared';
|
|
4
4
|
|
|
5
5
|
type Context = Record<PropertyKey, any>;
|
|
6
6
|
type MergedInitialContext<TInitial extends Context, TAdditional extends Context, TCurrent extends Context> = TInitial & Omit<TAdditional, keyof TCurrent>;
|
|
@@ -13,7 +13,6 @@ type ORPCErrorConstructorMap<T extends ErrorMap> = {
|
|
|
13
13
|
[K in keyof T]: K extends ORPCErrorCode ? T[K] extends ErrorMapItem<infer UInputSchema> ? ORPCErrorConstructorMapItem<K, InferSchemaInput<UInputSchema>> : never : never;
|
|
14
14
|
};
|
|
15
15
|
declare function createORPCErrorConstructorMap<T extends ErrorMap>(errors: T): ORPCErrorConstructorMap<T>;
|
|
16
|
-
declare function validateORPCError(map: ErrorMap, error: ORPCError<any, any>): Promise<ORPCError<string, unknown>>;
|
|
17
16
|
|
|
18
17
|
declare const LAZY_SYMBOL: unique symbol;
|
|
19
18
|
interface LazyMeta {
|
|
@@ -29,7 +28,9 @@ interface Lazy<T> {
|
|
|
29
28
|
}
|
|
30
29
|
type Lazyable<T> = T | Lazy<T>;
|
|
31
30
|
/**
|
|
32
|
-
*
|
|
31
|
+
* Creates a lazy-loaded item.
|
|
32
|
+
*
|
|
33
|
+
* @warning The `prefix` in `meta` only holds metadata and does not apply the prefix to the lazy router, use `os.prefix(...).lazy(...)` instead.
|
|
33
34
|
*/
|
|
34
35
|
declare function lazy<T>(loader: () => Promise<{
|
|
35
36
|
default: T;
|
|
@@ -127,18 +128,18 @@ type CreateProcedureClientOptions<TInitialContext extends Context, TOutputSchema
|
|
|
127
128
|
* This is helpful for logging and analytics.
|
|
128
129
|
*/
|
|
129
130
|
path?: readonly string[];
|
|
130
|
-
interceptors?: Interceptor<ProcedureClientInterceptorOptions<TInitialContext, TErrorMap, TMeta>, InferSchemaOutput<TOutputSchema>, ErrorFromErrorMap<TErrorMap
|
|
131
|
+
interceptors?: Interceptor<ProcedureClientInterceptorOptions<TInitialContext, TErrorMap, TMeta>, PromiseWithError<InferSchemaOutput<TOutputSchema>, ErrorFromErrorMap<TErrorMap>>>[];
|
|
131
132
|
} & (Record<never, never> extends TInitialContext ? {
|
|
132
|
-
context?: Value<TInitialContext
|
|
133
|
+
context?: Value<Promisable<TInitialContext>, [clientContext: TClientContext]>;
|
|
133
134
|
} : {
|
|
134
|
-
context: Value<TInitialContext
|
|
135
|
+
context: Value<Promisable<TInitialContext>, [clientContext: TClientContext]>;
|
|
135
136
|
});
|
|
136
137
|
/**
|
|
137
138
|
* Create Server-side client from a procedure.
|
|
138
139
|
*
|
|
139
140
|
* @see {@link https://orpc.unnoq.com/docs/client/server-side Server-side Client Docs}
|
|
140
141
|
*/
|
|
141
|
-
declare function createProcedureClient<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TMeta extends Meta, TClientContext extends ClientContext>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap, TMeta>>, ...
|
|
142
|
+
declare function createProcedureClient<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TMeta extends Meta, TClientContext extends ClientContext>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap, TMeta>>, ...rest: MaybeOptionalOptions<CreateProcedureClientOptions<TInitialContext, TOutputSchema, TErrorMap, TMeta, TClientContext>>): ProcedureClient<TClientContext, TInputSchema, TOutputSchema, TErrorMap>;
|
|
142
143
|
|
|
143
144
|
/**
|
|
144
145
|
* Represents a router, which defines a hierarchical structure of procedures.
|
|
@@ -188,5 +189,5 @@ type InferRouterOutputs<T extends AnyRouter> = T extends Procedure<any, any, any
|
|
|
188
189
|
[K in keyof T]: T[K] extends Lazyable<infer U extends AnyRouter> ? InferRouterOutputs<U> : never;
|
|
189
190
|
};
|
|
190
191
|
|
|
191
|
-
export { isProcedure as E, createProcedureClient as
|
|
192
|
-
export type {
|
|
192
|
+
export { isProcedure as E, createProcedureClient as F, Procedure as P, mergeCurrentContext as m, createORPCErrorConstructorMap as n, LAZY_SYMBOL as o, lazy as q, isLazy as r, getLazyMeta as s, unlazy as u, middlewareOutputFn as z };
|
|
193
|
+
export type { AnyProcedure as A, ProcedureHandlerOptions as B, Context as C, ProcedureDef as D, InferRouterInitialContexts as G, InferRouterCurrentContexts as H, InferRouterInitialContext as I, InferRouterInputs as J, InferRouterOutputs as K, Lazyable as L, MergedInitialContext as M, ORPCErrorConstructorMap as O, Router as R, AnyMiddleware as a, AnyRouter as b, Lazy as c, ProcedureClientInterceptorOptions as d, Middleware as e, MergedCurrentContext as f, MapInputMiddleware as g, CreateProcedureClientOptions as h, ProcedureClient as i, ProcedureHandler as j, ORPCErrorConstructorMapItemOptions as k, ORPCErrorConstructorMapItem as l, LazyMeta as p, MiddlewareResult as t, MiddlewareNextFnOptions as v, MiddlewareNextFn as w, MiddlewareOutputFn as x, MiddlewareOptions as y };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ORPCErrorCode, ORPCErrorOptions, ORPCError, HTTPPath, ClientContext, Client } from '@orpc/client';
|
|
2
2
|
import { ErrorMap, ErrorMapItem, InferSchemaInput, AnySchema, Meta, ContractProcedureDef, InferSchemaOutput, ErrorFromErrorMap, AnyContractRouter, ContractProcedure } from '@orpc/contract';
|
|
3
|
-
import { MaybeOptionalOptions, Promisable, Interceptor, Value } from '@orpc/shared';
|
|
3
|
+
import { MaybeOptionalOptions, Promisable, Interceptor, PromiseWithError, Value } from '@orpc/shared';
|
|
4
4
|
|
|
5
5
|
type Context = Record<PropertyKey, any>;
|
|
6
6
|
type MergedInitialContext<TInitial extends Context, TAdditional extends Context, TCurrent extends Context> = TInitial & Omit<TAdditional, keyof TCurrent>;
|
|
@@ -13,7 +13,6 @@ type ORPCErrorConstructorMap<T extends ErrorMap> = {
|
|
|
13
13
|
[K in keyof T]: K extends ORPCErrorCode ? T[K] extends ErrorMapItem<infer UInputSchema> ? ORPCErrorConstructorMapItem<K, InferSchemaInput<UInputSchema>> : never : never;
|
|
14
14
|
};
|
|
15
15
|
declare function createORPCErrorConstructorMap<T extends ErrorMap>(errors: T): ORPCErrorConstructorMap<T>;
|
|
16
|
-
declare function validateORPCError(map: ErrorMap, error: ORPCError<any, any>): Promise<ORPCError<string, unknown>>;
|
|
17
16
|
|
|
18
17
|
declare const LAZY_SYMBOL: unique symbol;
|
|
19
18
|
interface LazyMeta {
|
|
@@ -29,7 +28,9 @@ interface Lazy<T> {
|
|
|
29
28
|
}
|
|
30
29
|
type Lazyable<T> = T | Lazy<T>;
|
|
31
30
|
/**
|
|
32
|
-
*
|
|
31
|
+
* Creates a lazy-loaded item.
|
|
32
|
+
*
|
|
33
|
+
* @warning The `prefix` in `meta` only holds metadata and does not apply the prefix to the lazy router, use `os.prefix(...).lazy(...)` instead.
|
|
33
34
|
*/
|
|
34
35
|
declare function lazy<T>(loader: () => Promise<{
|
|
35
36
|
default: T;
|
|
@@ -127,18 +128,18 @@ type CreateProcedureClientOptions<TInitialContext extends Context, TOutputSchema
|
|
|
127
128
|
* This is helpful for logging and analytics.
|
|
128
129
|
*/
|
|
129
130
|
path?: readonly string[];
|
|
130
|
-
interceptors?: Interceptor<ProcedureClientInterceptorOptions<TInitialContext, TErrorMap, TMeta>, InferSchemaOutput<TOutputSchema>, ErrorFromErrorMap<TErrorMap
|
|
131
|
+
interceptors?: Interceptor<ProcedureClientInterceptorOptions<TInitialContext, TErrorMap, TMeta>, PromiseWithError<InferSchemaOutput<TOutputSchema>, ErrorFromErrorMap<TErrorMap>>>[];
|
|
131
132
|
} & (Record<never, never> extends TInitialContext ? {
|
|
132
|
-
context?: Value<TInitialContext
|
|
133
|
+
context?: Value<Promisable<TInitialContext>, [clientContext: TClientContext]>;
|
|
133
134
|
} : {
|
|
134
|
-
context: Value<TInitialContext
|
|
135
|
+
context: Value<Promisable<TInitialContext>, [clientContext: TClientContext]>;
|
|
135
136
|
});
|
|
136
137
|
/**
|
|
137
138
|
* Create Server-side client from a procedure.
|
|
138
139
|
*
|
|
139
140
|
* @see {@link https://orpc.unnoq.com/docs/client/server-side Server-side Client Docs}
|
|
140
141
|
*/
|
|
141
|
-
declare function createProcedureClient<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TMeta extends Meta, TClientContext extends ClientContext>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap, TMeta>>, ...
|
|
142
|
+
declare function createProcedureClient<TInitialContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, TMeta extends Meta, TClientContext extends ClientContext>(lazyableProcedure: Lazyable<Procedure<TInitialContext, any, TInputSchema, TOutputSchema, TErrorMap, TMeta>>, ...rest: MaybeOptionalOptions<CreateProcedureClientOptions<TInitialContext, TOutputSchema, TErrorMap, TMeta, TClientContext>>): ProcedureClient<TClientContext, TInputSchema, TOutputSchema, TErrorMap>;
|
|
142
143
|
|
|
143
144
|
/**
|
|
144
145
|
* Represents a router, which defines a hierarchical structure of procedures.
|
|
@@ -188,5 +189,5 @@ type InferRouterOutputs<T extends AnyRouter> = T extends Procedure<any, any, any
|
|
|
188
189
|
[K in keyof T]: T[K] extends Lazyable<infer U extends AnyRouter> ? InferRouterOutputs<U> : never;
|
|
189
190
|
};
|
|
190
191
|
|
|
191
|
-
export { isProcedure as E, createProcedureClient as
|
|
192
|
-
export type {
|
|
192
|
+
export { isProcedure as E, createProcedureClient as F, Procedure as P, mergeCurrentContext as m, createORPCErrorConstructorMap as n, LAZY_SYMBOL as o, lazy as q, isLazy as r, getLazyMeta as s, unlazy as u, middlewareOutputFn as z };
|
|
193
|
+
export type { AnyProcedure as A, ProcedureHandlerOptions as B, Context as C, ProcedureDef as D, InferRouterInitialContexts as G, InferRouterCurrentContexts as H, InferRouterInitialContext as I, InferRouterInputs as J, InferRouterOutputs as K, Lazyable as L, MergedInitialContext as M, ORPCErrorConstructorMap as O, Router as R, AnyMiddleware as a, AnyRouter as b, Lazy as c, ProcedureClientInterceptorOptions as d, Middleware as e, MergedCurrentContext as f, MapInputMiddleware as g, CreateProcedureClientOptions as h, ProcedureClient as i, ProcedureHandler as j, ORPCErrorConstructorMapItemOptions as k, ORPCErrorConstructorMapItem as l, LazyMeta as p, MiddlewareResult as t, MiddlewareNextFnOptions as v, MiddlewareNextFn as w, MiddlewareOutputFn as x, MiddlewareOptions as y };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { StandardRPCJsonSerializerOptions } from '@orpc/client/standard';
|
|
2
|
+
import { b as AnyRouter, C as Context, R as Router } from './server.B4BGqy3Y.js';
|
|
3
|
+
import { i as StandardMatcher, h as StandardMatchResult, e as StandardHandlerOptions, f as StandardHandler } from './server.DPIFWpxG.js';
|
|
4
|
+
import { HTTPPath } from '@orpc/client';
|
|
5
|
+
import { Value } from '@orpc/shared';
|
|
6
|
+
import { T as TraverseContractProcedureCallbackOptions } from './server.Cb6yD7DZ.js';
|
|
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,12 @@
|
|
|
1
|
+
import { C as Context } from './server.B4BGqy3Y.mjs';
|
|
2
|
+
import { b as StandardHandleOptions } from './server.DBCUJijK.mjs';
|
|
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 };
|
|
@@ -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, asyncIteratorWithSpan } 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 = {}) {
|
|
@@ -71,14 +72,15 @@ function createORPCErrorConstructorMap(errors) {
|
|
|
71
72
|
if (typeof code !== "string") {
|
|
72
73
|
return Reflect.get(target, code);
|
|
73
74
|
}
|
|
74
|
-
const item = (...
|
|
75
|
+
const item = (...rest) => {
|
|
76
|
+
const options = resolveMaybeOptionalOptions(rest);
|
|
75
77
|
const config = errors[code];
|
|
76
78
|
return new ORPCError(code, {
|
|
77
79
|
defined: Boolean(config),
|
|
78
80
|
status: config?.status,
|
|
79
|
-
message: options
|
|
80
|
-
data: options
|
|
81
|
-
cause: options
|
|
81
|
+
message: options.message ?? config?.message,
|
|
82
|
+
data: options.data,
|
|
83
|
+
cause: options.cause
|
|
82
84
|
});
|
|
83
85
|
};
|
|
84
86
|
return item;
|
|
@@ -86,54 +88,64 @@ function createORPCErrorConstructorMap(errors) {
|
|
|
86
88
|
});
|
|
87
89
|
return proxy;
|
|
88
90
|
}
|
|
89
|
-
async function validateORPCError(map, error) {
|
|
90
|
-
const { code, status, message, data, cause, defined } = error;
|
|
91
|
-
const config = map?.[error.code];
|
|
92
|
-
if (!config || fallbackORPCErrorStatus(error.code, config.status) !== error.status) {
|
|
93
|
-
return defined ? new ORPCError(code, { defined: false, status, message, data, cause }) : error;
|
|
94
|
-
}
|
|
95
|
-
if (!config.data) {
|
|
96
|
-
return defined ? error : new ORPCError(code, { defined: true, status, message, data, cause });
|
|
97
|
-
}
|
|
98
|
-
const validated = await config.data["~standard"].validate(error.data);
|
|
99
|
-
if (validated.issues) {
|
|
100
|
-
return defined ? new ORPCError(code, { defined: false, status, message, data, cause }) : error;
|
|
101
|
-
}
|
|
102
|
-
return new ORPCError(code, { defined: true, status, message, data: validated.value, cause });
|
|
103
|
-
}
|
|
104
91
|
|
|
105
92
|
function middlewareOutputFn(output) {
|
|
106
93
|
return { output, context: {} };
|
|
107
94
|
}
|
|
108
95
|
|
|
109
|
-
function createProcedureClient(lazyableProcedure, ...
|
|
96
|
+
function createProcedureClient(lazyableProcedure, ...rest) {
|
|
97
|
+
const options = resolveMaybeOptionalOptions(rest);
|
|
110
98
|
return async (...[input, callerOptions]) => {
|
|
111
|
-
const path = options
|
|
99
|
+
const path = toArray(options.path);
|
|
112
100
|
const { default: procedure } = await unlazy(lazyableProcedure);
|
|
113
101
|
const clientContext = callerOptions?.context ?? {};
|
|
114
|
-
const context = await value(options
|
|
102
|
+
const context = await value(options.context ?? {}, clientContext);
|
|
115
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
|
+
};
|
|
116
110
|
try {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
{
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
+
}
|
|
130
130
|
);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
if (isAsyncIteratorObject(output)) {
|
|
132
|
+
if (output instanceof HibernationEventIterator) {
|
|
133
|
+
return output;
|
|
134
|
+
}
|
|
135
|
+
return 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
|
+
);
|
|
134
145
|
}
|
|
135
|
-
|
|
136
|
-
|
|
146
|
+
return output;
|
|
147
|
+
} catch (e) {
|
|
148
|
+
throw await validateError(e);
|
|
137
149
|
}
|
|
138
150
|
};
|
|
139
151
|
}
|
|
@@ -142,31 +154,49 @@ async function validateInput(procedure, input) {
|
|
|
142
154
|
if (!schema) {
|
|
143
155
|
return input;
|
|
144
156
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
+
);
|
|
156
177
|
}
|
|
157
178
|
async function validateOutput(procedure, output) {
|
|
158
179
|
const schema = procedure["~orpc"].outputSchema;
|
|
159
180
|
if (!schema) {
|
|
160
181
|
return output;
|
|
161
182
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
+
);
|
|
170
200
|
}
|
|
171
201
|
async function executeProcedureInternal(procedure, options) {
|
|
172
202
|
const middlewares = procedure["~orpc"].middlewares;
|
|
@@ -178,17 +208,28 @@ async function executeProcedureInternal(procedure, options) {
|
|
|
178
208
|
currentInput = await validateInput(procedure, currentInput);
|
|
179
209
|
}
|
|
180
210
|
const mid = middlewares[index];
|
|
181
|
-
const output = mid ?
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
context
|
|
189
|
-
|
|
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;
|
|
190
228
|
}
|
|
191
|
-
|
|
229
|
+
) : await runWithSpan(
|
|
230
|
+
{ name: "handler", signal: options.signal },
|
|
231
|
+
() => procedure["~orpc"].handler({ ...options, context, input: currentInput })
|
|
232
|
+
);
|
|
192
233
|
if (index === outputValidationIndex) {
|
|
193
234
|
return await validateOutput(procedure, output);
|
|
194
235
|
}
|
|
@@ -361,7 +402,8 @@ function createContractedProcedure(procedure, contract) {
|
|
|
361
402
|
});
|
|
362
403
|
}
|
|
363
404
|
function call(procedure, input, ...rest) {
|
|
364
|
-
|
|
405
|
+
const options = resolveMaybeOptionalOptions(rest);
|
|
406
|
+
return createProcedureClient(procedure, options)(input, options);
|
|
365
407
|
}
|
|
366
408
|
|
|
367
|
-
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,
|
|
409
|
+
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 };
|