@orpc/server 0.0.0-next.94096b2 → 0.0.0-next.9540489

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.
Files changed (62) hide show
  1. package/README.md +7 -2
  2. package/dist/adapters/aws-lambda/index.d.mts +5 -5
  3. package/dist/adapters/aws-lambda/index.d.ts +5 -5
  4. package/dist/adapters/aws-lambda/index.mjs +4 -3
  5. package/dist/adapters/bun-ws/index.d.mts +5 -5
  6. package/dist/adapters/bun-ws/index.d.ts +5 -5
  7. package/dist/adapters/bun-ws/index.mjs +10 -10
  8. package/dist/adapters/crossws/index.d.mts +5 -5
  9. package/dist/adapters/crossws/index.d.ts +5 -5
  10. package/dist/adapters/crossws/index.mjs +5 -7
  11. package/dist/adapters/fastify/index.d.mts +53 -0
  12. package/dist/adapters/fastify/index.d.ts +53 -0
  13. package/dist/adapters/fastify/index.mjs +54 -0
  14. package/dist/adapters/fetch/index.d.mts +54 -9
  15. package/dist/adapters/fetch/index.d.ts +54 -9
  16. package/dist/adapters/fetch/index.mjs +74 -4
  17. package/dist/adapters/message-port/index.d.mts +35 -9
  18. package/dist/adapters/message-port/index.d.ts +35 -9
  19. package/dist/adapters/message-port/index.mjs +29 -15
  20. package/dist/adapters/node/index.d.mts +31 -10
  21. package/dist/adapters/node/index.d.ts +31 -10
  22. package/dist/adapters/node/index.mjs +70 -13
  23. package/dist/adapters/standard/index.d.mts +6 -6
  24. package/dist/adapters/standard/index.d.ts +6 -6
  25. package/dist/adapters/standard/index.mjs +2 -2
  26. package/dist/adapters/standard-peer/index.d.mts +9 -5
  27. package/dist/adapters/standard-peer/index.d.ts +9 -5
  28. package/dist/adapters/standard-peer/index.mjs +1 -1
  29. package/dist/adapters/websocket/index.d.mts +9 -7
  30. package/dist/adapters/websocket/index.d.ts +9 -7
  31. package/dist/adapters/websocket/index.mjs +5 -7
  32. package/dist/adapters/ws/index.d.mts +5 -5
  33. package/dist/adapters/ws/index.d.ts +5 -5
  34. package/dist/adapters/ws/index.mjs +5 -7
  35. package/dist/helpers/index.d.mts +149 -0
  36. package/dist/helpers/index.d.ts +149 -0
  37. package/dist/helpers/index.mjs +198 -0
  38. package/dist/hibernation/index.d.mts +11 -11
  39. package/dist/hibernation/index.d.ts +11 -11
  40. package/dist/hibernation/index.mjs +8 -8
  41. package/dist/index.d.mts +6 -6
  42. package/dist/index.d.ts +6 -6
  43. package/dist/index.mjs +12 -8
  44. package/dist/plugins/index.d.mts +20 -4
  45. package/dist/plugins/index.d.ts +20 -4
  46. package/dist/plugins/index.mjs +86 -58
  47. package/dist/shared/{server.CRejaM08.d.mts → server.B4BGqy3Y.d.mts} +6 -5
  48. package/dist/shared/{server.CRejaM08.d.ts → server.B4BGqy3Y.d.ts} +6 -5
  49. package/dist/shared/{server.Aqc4pYFD.mjs → server.Bxx6tqNe.mjs} +64 -39
  50. package/dist/shared/{server.CPC5w4d2.d.ts → server.COL12UTb.d.ts} +3 -3
  51. package/dist/shared/{server.VjZAmjFs.d.mts → server.CVKCo60T.d.mts} +2 -2
  52. package/dist/shared/{server.Bi2_bIHo.d.ts → server.Cb6yD7DZ.d.ts} +1 -1
  53. package/dist/shared/{server.C-F_fMXW.d.mts → server.Ck-gOLzq.d.mts} +3 -3
  54. package/dist/shared/{server.De2J-WNx.d.mts → server.DBCUJijK.d.mts} +1 -1
  55. package/dist/shared/{server.mGrd7l1v.d.ts → server.DNtJ-p60.d.ts} +2 -2
  56. package/dist/shared/{server.BX8Iro5z.d.ts → server.DPIFWpxG.d.ts} +1 -1
  57. package/dist/shared/{server.DLJzqnSX.mjs → server.Ds4HPpvH.mjs} +114 -73
  58. package/dist/shared/{server.DrG30u7a.d.mts → server.DzV1hr3z.d.mts} +1 -1
  59. package/dist/shared/{server.BW-nUGgA.mjs → server.TEVCLCFC.mjs} +3 -0
  60. package/dist/shared/server.UVMTOWrk.mjs +26 -0
  61. package/package.json +28 -12
  62. package/dist/shared/server.C6Q5sqYw.mjs +0 -20
@@ -1,6 +1,7 @@
1
- import { isContractProcedure, ValidationError, mergePrefix, mergeErrorMap, enhanceRoute } from '@orpc/contract';
2
- import { value, intercept, resolveMaybeOptionalOptions } from '@orpc/shared';
3
- import { fallbackORPCErrorStatus, ORPCError } from '@orpc/client';
1
+ import { isContractProcedure, validateORPCError, ValidationError, mergePrefix, mergeErrorMap, enhanceRoute } from '@orpc/contract';
2
+ import { resolveMaybeOptionalOptions, toArray, value, runWithSpan, intercept, isAsyncIteratorObject, overlayProxy, 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 = (...[options]) => {
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?.message ?? config?.message,
80
- data: options?.data,
81
- cause: options?.cause
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, ...[options]) {
96
+ function createProcedureClient(lazyableProcedure, ...rest) {
97
+ const options = resolveMaybeOptionalOptions(rest);
110
98
  return async (...[input, callerOptions]) => {
111
- const path = options?.path ?? [];
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?.context ?? {}, clientContext);
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
- return await intercept(
118
- options?.interceptors ?? [],
119
- {
120
- context,
121
- input,
122
- // input only optional when it undefinable so we can safely cast it
123
- errors,
124
- path,
125
- procedure,
126
- signal: callerOptions?.signal,
127
- lastEventId: callerOptions?.lastEventId
128
- },
129
- (interceptorOptions) => executeProcedureInternal(interceptorOptions.procedure, interceptorOptions)
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
- } catch (e) {
132
- if (!(e instanceof ORPCError)) {
133
- throw e;
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
+ ));
134
145
  }
135
- const validated = await validateORPCError(procedure["~orpc"].errorMap, e);
136
- throw validated;
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
- const result = await schema["~standard"].validate(input);
146
- if (result.issues) {
147
- throw new ORPCError("BAD_REQUEST", {
148
- message: "Input validation failed",
149
- data: {
150
- issues: result.issues
151
- },
152
- cause: new ValidationError({ message: "Input validation failed", issues: result.issues })
153
- });
154
- }
155
- return result.value;
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
- const result = await schema["~standard"].validate(output);
163
- if (result.issues) {
164
- throw new ORPCError("INTERNAL_SERVER_ERROR", {
165
- message: "Output validation failed",
166
- cause: new ValidationError({ message: "Output validation failed", issues: result.issues })
167
- });
168
- }
169
- return result.value;
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 ? (await mid({
182
- ...options,
183
- context,
184
- next: async (...[nextOptions]) => {
185
- const nextContext = nextOptions?.context ?? {};
186
- return {
187
- output: await next(index + 1, mergeCurrentContext(context, nextContext), currentInput),
188
- context: nextContext
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
- }, currentInput, middlewareOutputFn)).output : await procedure["~orpc"].handler({ ...options, context, input: currentInput });
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
  }
@@ -365,4 +406,4 @@ function call(procedure, input, ...rest) {
365
406
  return createProcedureClient(procedure, options)(input, options);
366
407
  }
367
408
 
368
- 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, validateORPCError as v, resolveContractProcedures as w, unlazyRouter as x };
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 };
@@ -1,5 +1,5 @@
1
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.CRejaM08.mjs';
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.B4BGqy3Y.mjs';
3
3
 
4
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
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> & {
@@ -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");
@@ -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 };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/server",
3
3
  "type": "module",
4
- "version": "0.0.0-next.94096b2",
4
+ "version": "0.0.0-next.9540489",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -19,6 +19,11 @@
19
19
  "import": "./dist/index.mjs",
20
20
  "default": "./dist/index.mjs"
21
21
  },
22
+ "./helpers": {
23
+ "types": "./dist/helpers/index.d.mts",
24
+ "import": "./dist/helpers/index.mjs",
25
+ "default": "./dist/helpers/index.mjs"
26
+ },
22
27
  "./plugins": {
23
28
  "types": "./dist/plugins/index.d.mts",
24
29
  "import": "./dist/plugins/index.mjs",
@@ -49,6 +54,11 @@
49
54
  "import": "./dist/adapters/node/index.mjs",
50
55
  "default": "./dist/adapters/node/index.mjs"
51
56
  },
57
+ "./fastify": {
58
+ "types": "./dist/adapters/fastify/index.d.mts",
59
+ "import": "./dist/adapters/fastify/index.mjs",
60
+ "default": "./dist/adapters/fastify/index.mjs"
61
+ },
52
62
  "./aws-lambda": {
53
63
  "types": "./dist/adapters/aws-lambda/index.d.mts",
54
64
  "import": "./dist/adapters/aws-lambda/index.mjs",
@@ -96,21 +106,27 @@
96
106
  }
97
107
  },
98
108
  "dependencies": {
99
- "@orpc/client": "0.0.0-next.94096b2",
100
- "@orpc/shared": "0.0.0-next.94096b2",
101
- "@orpc/standard-server": "0.0.0-next.94096b2",
102
- "@orpc/contract": "0.0.0-next.94096b2",
103
- "@orpc/standard-server-aws-lambda": "0.0.0-next.94096b2",
104
- "@orpc/standard-server-node": "0.0.0-next.94096b2",
105
- "@orpc/standard-server-fetch": "0.0.0-next.94096b2",
106
- "@orpc/standard-server-peer": "0.0.0-next.94096b2"
109
+ "cookie": "^1.0.2",
110
+ "@orpc/client": "0.0.0-next.9540489",
111
+ "@orpc/interop": "0.0.0-next.9540489",
112
+ "@orpc/shared": "0.0.0-next.9540489",
113
+ "@orpc/standard-server": "0.0.0-next.9540489",
114
+ "@orpc/contract": "0.0.0-next.9540489",
115
+ "@orpc/standard-server-aws-lambda": "0.0.0-next.9540489",
116
+ "@orpc/standard-server-fetch": "0.0.0-next.9540489",
117
+ "@orpc/standard-server-node": "0.0.0-next.9540489",
118
+ "@orpc/standard-server-fastify": "0.0.0-next.9540489",
119
+ "@orpc/standard-server-peer": "0.0.0-next.9540489"
107
120
  },
108
121
  "devDependencies": {
122
+ "@tanstack/router-core": "^1.136.1",
109
123
  "@types/ws": "^8.18.1",
110
124
  "crossws": "^0.4.1",
111
- "next": "^15.4.1",
112
- "supertest": "^7.1.3",
113
- "ws": "^8.18.3"
125
+ "fastify": "^5.6.2",
126
+ "next": "^16.0.3",
127
+ "supertest": "^7.1.4",
128
+ "ws": "^8.18.3",
129
+ "zod": "^4.1.12"
114
130
  },
115
131
  "scripts": {
116
132
  "build": "unbuild",
@@ -1,20 +0,0 @@
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 { response } = await handler.handle(
14
- { ...request, body: () => Promise.resolve(request.body) },
15
- resolveFriendlyStandardHandleOptions(options)
16
- );
17
- await peer.response(id, response ?? { status: 404, headers: {}, body: "No procedure matched" });
18
- }
19
-
20
- export { handleStandardServerPeerMessage as h };