@orpc/server 1.7.11 → 1.8.1
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 +2 -1
- package/dist/adapters/aws-lambda/index.mjs +2 -2
- package/dist/adapters/bun-ws/index.mjs +10 -10
- package/dist/adapters/crossws/index.mjs +5 -7
- package/dist/adapters/fetch/index.d.mts +47 -2
- package/dist/adapters/fetch/index.d.ts +47 -2
- package/dist/adapters/fetch/index.mjs +72 -3
- package/dist/adapters/message-port/index.mjs +5 -7
- package/dist/adapters/node/index.d.mts +23 -2
- package/dist/adapters/node/index.d.ts +23 -2
- package/dist/adapters/node/index.mjs +68 -12
- package/dist/adapters/standard/index.mjs +2 -2
- package/dist/adapters/standard-peer/index.d.mts +6 -2
- package/dist/adapters/standard-peer/index.d.ts +6 -2
- package/dist/adapters/standard-peer/index.mjs +1 -1
- package/dist/adapters/websocket/index.mjs +5 -7
- package/dist/adapters/ws/index.mjs +5 -7
- package/dist/hibernation/index.d.mts +9 -9
- package/dist/hibernation/index.d.ts +9 -9
- package/dist/hibernation/index.mjs +8 -8
- package/dist/index.mjs +2 -2
- package/dist/plugins/index.mjs +65 -56
- package/dist/shared/{server.NeumLVdS.mjs → server.B_fj3X5m.mjs} +81 -43
- package/dist/shared/{server.CIL9uKTN.mjs → server.CYRYFTxo.mjs} +64 -39
- package/dist/shared/server.UVMTOWrk.mjs +26 -0
- package/package.json +10 -9
- package/dist/shared/server.C6Q5sqYw.mjs +0 -20
@@ -1,13 +1,13 @@
|
|
1
1
|
import { readAsBuffer, resolveMaybeOptionalOptions } from '@orpc/shared';
|
2
2
|
import { ServerPeer } from '@orpc/standard-server-peer';
|
3
|
-
import {
|
3
|
+
import { c as createServerPeerHandleRequestFn } from '../../shared/server.UVMTOWrk.mjs';
|
4
4
|
import '@orpc/client';
|
5
5
|
import '@orpc/standard-server';
|
6
6
|
import '@orpc/contract';
|
7
|
-
import { b as StandardRPCHandler } from '../../shared/server.
|
7
|
+
import { b as StandardRPCHandler } from '../../shared/server.CYRYFTxo.mjs';
|
8
8
|
import '@orpc/client/standard';
|
9
9
|
import '../../shared/server.DZ5BIITo.mjs';
|
10
|
-
import '../../shared/server.
|
10
|
+
import '../../shared/server.B_fj3X5m.mjs';
|
11
11
|
|
12
12
|
class WsHandler {
|
13
13
|
constructor(standardHandler) {
|
@@ -17,11 +17,9 @@ class WsHandler {
|
|
17
17
|
const peer = new ServerPeer(ws.send.bind(ws));
|
18
18
|
ws.addEventListener("message", async (event) => {
|
19
19
|
const message = Array.isArray(event.data) ? await readAsBuffer(new Blob(event.data)) : event.data;
|
20
|
-
await
|
21
|
-
this.standardHandler,
|
22
|
-
peer,
|
20
|
+
await peer.message(
|
23
21
|
message,
|
24
|
-
resolveMaybeOptionalOptions(rest)
|
22
|
+
createServerPeerHandleRequestFn(this.standardHandler, resolveMaybeOptionalOptions(rest))
|
25
23
|
);
|
26
24
|
});
|
27
25
|
ws.addEventListener("close", () => {
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { StandardRPCJsonSerializerOptions } from '@orpc/client/standard';
|
2
2
|
import { g as StandardHandlerPlugin, e as StandardHandlerOptions } from '../shared/server.gqRxT-yN.mjs';
|
3
|
-
import {
|
4
|
-
export {
|
3
|
+
import { HibernationEventIterator } from '@orpc/standard-server';
|
4
|
+
export { HibernationEventIterator, HibernationEventIteratorCallback } from '@orpc/standard-server';
|
5
5
|
import { C as Context, R as Router } from '../shared/server.CYNGeoCm.mjs';
|
6
6
|
import '@orpc/client';
|
7
7
|
import '@orpc/contract';
|
8
8
|
import '@orpc/shared';
|
9
9
|
|
10
|
-
interface
|
10
|
+
interface EncodeHibernationRPCEventOptions extends StandardRPCJsonSerializerOptions {
|
11
11
|
/**
|
12
12
|
* The type of event, each type corresponds a different operation
|
13
13
|
*
|
@@ -24,21 +24,21 @@ interface experimental_EncodeHibernationRPCEventOptions extends StandardRPCJsonS
|
|
24
24
|
*
|
25
25
|
* @see {@link https://orpc.unnoq.com/docs/plugins/hibernation Hibernation Plugin}
|
26
26
|
*/
|
27
|
-
declare function
|
27
|
+
declare function encodeHibernationRPCEvent(id: string, payload: unknown, options?: EncodeHibernationRPCEventOptions): string;
|
28
28
|
|
29
|
-
interface
|
30
|
-
iterator?:
|
29
|
+
interface HibernationPluginContext {
|
30
|
+
iterator?: HibernationEventIterator<any>;
|
31
31
|
}
|
32
32
|
/**
|
33
33
|
* Enable Hibernation APIs
|
34
34
|
*
|
35
35
|
* @see {@link https://orpc.unnoq.com/docs/plugins/hibernation Hibernation Plugin}
|
36
36
|
*/
|
37
|
-
declare class
|
37
|
+
declare class HibernationPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
38
38
|
readonly CONTEXT_SYMBOL: symbol;
|
39
39
|
order: number;
|
40
40
|
init(options: StandardHandlerOptions<T>, _router: Router<any, T>): void;
|
41
41
|
}
|
42
42
|
|
43
|
-
export {
|
44
|
-
export type {
|
43
|
+
export { HibernationPlugin, encodeHibernationRPCEvent };
|
44
|
+
export type { EncodeHibernationRPCEventOptions, HibernationPluginContext };
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { StandardRPCJsonSerializerOptions } from '@orpc/client/standard';
|
2
2
|
import { g as StandardHandlerPlugin, e as StandardHandlerOptions } from '../shared/server.Bmh5xd4n.js';
|
3
|
-
import {
|
4
|
-
export {
|
3
|
+
import { HibernationEventIterator } from '@orpc/standard-server';
|
4
|
+
export { HibernationEventIterator, HibernationEventIteratorCallback } from '@orpc/standard-server';
|
5
5
|
import { C as Context, R as Router } from '../shared/server.CYNGeoCm.js';
|
6
6
|
import '@orpc/client';
|
7
7
|
import '@orpc/contract';
|
8
8
|
import '@orpc/shared';
|
9
9
|
|
10
|
-
interface
|
10
|
+
interface EncodeHibernationRPCEventOptions extends StandardRPCJsonSerializerOptions {
|
11
11
|
/**
|
12
12
|
* The type of event, each type corresponds a different operation
|
13
13
|
*
|
@@ -24,21 +24,21 @@ interface experimental_EncodeHibernationRPCEventOptions extends StandardRPCJsonS
|
|
24
24
|
*
|
25
25
|
* @see {@link https://orpc.unnoq.com/docs/plugins/hibernation Hibernation Plugin}
|
26
26
|
*/
|
27
|
-
declare function
|
27
|
+
declare function encodeHibernationRPCEvent(id: string, payload: unknown, options?: EncodeHibernationRPCEventOptions): string;
|
28
28
|
|
29
|
-
interface
|
30
|
-
iterator?:
|
29
|
+
interface HibernationPluginContext {
|
30
|
+
iterator?: HibernationEventIterator<any>;
|
31
31
|
}
|
32
32
|
/**
|
33
33
|
* Enable Hibernation APIs
|
34
34
|
*
|
35
35
|
* @see {@link https://orpc.unnoq.com/docs/plugins/hibernation Hibernation Plugin}
|
36
36
|
*/
|
37
|
-
declare class
|
37
|
+
declare class HibernationPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
38
38
|
readonly CONTEXT_SYMBOL: symbol;
|
39
39
|
order: number;
|
40
40
|
init(options: StandardHandlerOptions<T>, _router: Router<any, T>): void;
|
41
41
|
}
|
42
42
|
|
43
|
-
export {
|
44
|
-
export type {
|
43
|
+
export { HibernationPlugin, encodeHibernationRPCEvent };
|
44
|
+
export type { EncodeHibernationRPCEventOptions, HibernationPluginContext };
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { toORPCError } from '@orpc/client';
|
2
2
|
import { StandardRPCJsonSerializer } from '@orpc/client/standard';
|
3
3
|
import { stringifyJSON } from '@orpc/shared';
|
4
|
-
import { getEventMeta,
|
5
|
-
export {
|
4
|
+
import { getEventMeta, HibernationEventIterator } from '@orpc/standard-server';
|
5
|
+
export { HibernationEventIterator } from '@orpc/standard-server';
|
6
6
|
import { MessageType } from '@orpc/standard-server-peer';
|
7
7
|
|
8
|
-
function
|
8
|
+
function encodeHibernationRPCEvent(id, payload, options = {}) {
|
9
9
|
const { event = "message", ...rest } = options;
|
10
10
|
const serializer = new StandardRPCJsonSerializer(rest);
|
11
11
|
const data = event === "error" ? toORPCError(payload).toJSON() : payload;
|
@@ -21,7 +21,7 @@ function experimental_encodeHibernationRPCEvent(id, payload, options = {}) {
|
|
21
21
|
});
|
22
22
|
}
|
23
23
|
|
24
|
-
class
|
24
|
+
class HibernationPlugin {
|
25
25
|
CONTEXT_SYMBOL = Symbol("ORPC_HIBERNATION_CONTEXT");
|
26
26
|
order = 2e6;
|
27
27
|
// make sure execute after the batch plugin
|
@@ -33,8 +33,8 @@ class experimental_HibernationPlugin {
|
|
33
33
|
const result = await options2.next({
|
34
34
|
...options2,
|
35
35
|
context: {
|
36
|
-
|
37
|
-
|
36
|
+
...options2.context,
|
37
|
+
[this.CONTEXT_SYMBOL]: hibernationContext
|
38
38
|
}
|
39
39
|
});
|
40
40
|
if (!result.matched || !hibernationContext.iterator) {
|
@@ -54,7 +54,7 @@ class experimental_HibernationPlugin {
|
|
54
54
|
throw new TypeError("[HibernationPlugin] Hibernation context has been corrupted or modified by another plugin or interceptor");
|
55
55
|
}
|
56
56
|
const output = await options2.next();
|
57
|
-
if (output instanceof
|
57
|
+
if (output instanceof HibernationEventIterator) {
|
58
58
|
hibernationContext.iterator = output;
|
59
59
|
}
|
60
60
|
return output;
|
@@ -62,4 +62,4 @@ class experimental_HibernationPlugin {
|
|
62
62
|
}
|
63
63
|
}
|
64
64
|
|
65
|
-
export {
|
65
|
+
export { HibernationPlugin, encodeHibernationRPCEvent };
|
package/dist/index.mjs
CHANGED
@@ -1,7 +1,7 @@
|
|
1
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, u as unlazy, g as getRouter, i as isProcedure, d as isLazy, f as createAssertedLazyProcedure } from './shared/server.
|
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.
|
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.B_fj3X5m.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.B_fj3X5m.mjs';
|
5
5
|
import { toORPCError } from '@orpc/client';
|
6
6
|
export { ORPCError, isDefinedError, safe } from '@orpc/client';
|
7
7
|
import { resolveMaybeOptionalOptions } from '@orpc/shared';
|
package/dist/plugins/index.mjs
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { value, isAsyncIteratorObject, clone } from '@orpc/shared';
|
1
|
+
import { runWithSpan, value, setSpanError, isAsyncIteratorObject, clone } from '@orpc/shared';
|
2
2
|
import { flattenHeader } from '@orpc/standard-server';
|
3
3
|
import { parseBatchRequest, toBatchResponse } from '@orpc/standard-server/batch';
|
4
4
|
import { toFetchHeaders } from '@orpc/standard-server-fetch';
|
@@ -33,65 +33,74 @@ class BatchHandlerPlugin {
|
|
33
33
|
}
|
34
34
|
let isParsing = false;
|
35
35
|
try {
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
return options2.next({ ...options2, request: { ...mapped, body: () => Promise.resolve(mapped.body) } }).then(({ response: response2, matched }) => {
|
54
|
-
if (matched) {
|
55
|
-
if (response2.body instanceof Blob || response2.body instanceof FormData || isAsyncIteratorObject(response2.body)) {
|
56
|
-
return {
|
57
|
-
index,
|
58
|
-
status: 500,
|
59
|
-
headers: {},
|
60
|
-
body: "Batch responses do not support file/blob, or event-iterator. Please call this procedure separately outside of the batch request."
|
61
|
-
};
|
62
|
-
}
|
63
|
-
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
|
64
53
|
}
|
65
|
-
|
66
|
-
}).catch(() => {
|
67
|
-
return { index, status: 500, headers: {}, body: "Internal server error" };
|
68
|
-
});
|
54
|
+
};
|
69
55
|
}
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
+
});
|
88
77
|
}
|
89
|
-
|
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
|
+
};
|
90
103
|
});
|
91
|
-
return {
|
92
|
-
matched: true,
|
93
|
-
response
|
94
|
-
};
|
95
104
|
} catch (cause) {
|
96
105
|
if (isParsing) {
|
97
106
|
return {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { isContractProcedure, ValidationError, mergePrefix, mergeErrorMap, enhanceRoute } from '@orpc/contract';
|
2
|
-
import { resolveMaybeOptionalOptions, toArray, value, intercept } from '@orpc/shared';
|
2
|
+
import { resolveMaybeOptionalOptions, toArray, value, runWithSpan, intercept, isAsyncIteratorObject, asyncIteratorWithSpan } from '@orpc/shared';
|
3
3
|
import { fallbackORPCErrorStatus, ORPCError } 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 = {}) {
|
@@ -116,20 +117,36 @@ function createProcedureClient(lazyableProcedure, ...rest) {
|
|
116
117
|
const context = await value(options.context ?? {}, clientContext);
|
117
118
|
const errors = createORPCErrorConstructorMap(procedure["~orpc"].errorMap);
|
118
119
|
try {
|
119
|
-
|
120
|
-
|
121
|
-
{
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
120
|
+
const output = await runWithSpan(
|
121
|
+
{ name: "call_procedure", signal: callerOptions?.signal },
|
122
|
+
(span) => {
|
123
|
+
span?.setAttribute("procedure.path", [...path]);
|
124
|
+
return intercept(
|
125
|
+
toArray(options.interceptors),
|
126
|
+
{
|
127
|
+
context,
|
128
|
+
input,
|
129
|
+
// input only optional when it undefinable so we can safely cast it
|
130
|
+
errors,
|
131
|
+
path,
|
132
|
+
procedure,
|
133
|
+
signal: callerOptions?.signal,
|
134
|
+
lastEventId: callerOptions?.lastEventId
|
135
|
+
},
|
136
|
+
(interceptorOptions) => executeProcedureInternal(interceptorOptions.procedure, interceptorOptions)
|
137
|
+
);
|
138
|
+
}
|
132
139
|
);
|
140
|
+
if (isAsyncIteratorObject(output)) {
|
141
|
+
if (output instanceof HibernationEventIterator) {
|
142
|
+
return output;
|
143
|
+
}
|
144
|
+
return asyncIteratorWithSpan(
|
145
|
+
{ name: "consume_event_iterator_output", signal: callerOptions?.signal },
|
146
|
+
output
|
147
|
+
);
|
148
|
+
}
|
149
|
+
return output;
|
133
150
|
} catch (e) {
|
134
151
|
if (!(e instanceof ORPCError)) {
|
135
152
|
throw e;
|
@@ -144,31 +161,41 @@ async function validateInput(procedure, input) {
|
|
144
161
|
if (!schema) {
|
145
162
|
return input;
|
146
163
|
}
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
164
|
+
return runWithSpan(
|
165
|
+
{ name: "validate_input" },
|
166
|
+
async () => {
|
167
|
+
const result = await schema["~standard"].validate(input);
|
168
|
+
if (result.issues) {
|
169
|
+
throw new ORPCError("BAD_REQUEST", {
|
170
|
+
message: "Input validation failed",
|
171
|
+
data: {
|
172
|
+
issues: result.issues
|
173
|
+
},
|
174
|
+
cause: new ValidationError({ message: "Input validation failed", issues: result.issues })
|
175
|
+
});
|
176
|
+
}
|
177
|
+
return result.value;
|
178
|
+
}
|
179
|
+
);
|
158
180
|
}
|
159
181
|
async function validateOutput(procedure, output) {
|
160
182
|
const schema = procedure["~orpc"].outputSchema;
|
161
183
|
if (!schema) {
|
162
184
|
return output;
|
163
185
|
}
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
186
|
+
return runWithSpan(
|
187
|
+
{ name: "validate_output" },
|
188
|
+
async () => {
|
189
|
+
const result = await schema["~standard"].validate(output);
|
190
|
+
if (result.issues) {
|
191
|
+
throw new ORPCError("INTERNAL_SERVER_ERROR", {
|
192
|
+
message: "Output validation failed",
|
193
|
+
cause: new ValidationError({ message: "Output validation failed", issues: result.issues })
|
194
|
+
});
|
195
|
+
}
|
196
|
+
return result.value;
|
197
|
+
}
|
198
|
+
);
|
172
199
|
}
|
173
200
|
async function executeProcedureInternal(procedure, options) {
|
174
201
|
const middlewares = procedure["~orpc"].middlewares;
|
@@ -180,17 +207,28 @@ async function executeProcedureInternal(procedure, options) {
|
|
180
207
|
currentInput = await validateInput(procedure, currentInput);
|
181
208
|
}
|
182
209
|
const mid = middlewares[index];
|
183
|
-
const output = mid ?
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
context
|
191
|
-
|
210
|
+
const output = mid ? await runWithSpan(
|
211
|
+
{ name: `middleware.${mid.name}`, signal: options.signal },
|
212
|
+
async (span) => {
|
213
|
+
span?.setAttribute("middleware.index", index);
|
214
|
+
span?.setAttribute("middleware.name", mid.name);
|
215
|
+
const result = await mid({
|
216
|
+
...options,
|
217
|
+
context,
|
218
|
+
next: async (...[nextOptions]) => {
|
219
|
+
const nextContext = nextOptions?.context ?? {};
|
220
|
+
return {
|
221
|
+
output: await next(index + 1, mergeCurrentContext(context, nextContext), currentInput),
|
222
|
+
context: nextContext
|
223
|
+
};
|
224
|
+
}
|
225
|
+
}, currentInput, middlewareOutputFn);
|
226
|
+
return result.output;
|
192
227
|
}
|
193
|
-
|
228
|
+
) : await runWithSpan(
|
229
|
+
{ name: "handler", signal: options.signal },
|
230
|
+
() => procedure["~orpc"].handler({ ...options, context, input: currentInput })
|
231
|
+
);
|
194
232
|
if (index === outputValidationIndex) {
|
195
233
|
return await validateOutput(procedure, output);
|
196
234
|
}
|
@@ -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, NullProtoObj, value } 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.B_fj3X5m.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
|
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import '@orpc/client';
|
2
|
+
import '@orpc/shared';
|
3
|
+
import '@orpc/standard-server';
|
4
|
+
import '@orpc/contract';
|
5
|
+
import '@orpc/client/standard';
|
6
|
+
import { r as resolveFriendlyStandardHandleOptions } from './server.DZ5BIITo.mjs';
|
7
|
+
|
8
|
+
async function handleStandardServerPeerMessage(handler, peer, message, options) {
|
9
|
+
const [id, request] = await peer.message(message);
|
10
|
+
if (!request) {
|
11
|
+
return;
|
12
|
+
}
|
13
|
+
const handle = createServerPeerHandleRequestFn(handler, options);
|
14
|
+
await peer.response(id, await handle(request));
|
15
|
+
}
|
16
|
+
function createServerPeerHandleRequestFn(handler, options) {
|
17
|
+
return async (request) => {
|
18
|
+
const { response } = await handler.handle(
|
19
|
+
{ ...request, body: () => Promise.resolve(request.body) },
|
20
|
+
resolveFriendlyStandardHandleOptions(options)
|
21
|
+
);
|
22
|
+
return response ?? { status: 404, headers: {}, body: "No procedure matched" };
|
23
|
+
};
|
24
|
+
}
|
25
|
+
|
26
|
+
export { createServerPeerHandleRequestFn as c, handleStandardServerPeerMessage as h };
|