@orpc/server 0.0.0-next.4a31e17 → 0.0.0-next.4e27480

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/dist/{chunk-6A7XHEBH.js → chunk-GK2Z6B6W.js} +85 -44
  2. package/dist/{chunk-B2EZJB7X.js → chunk-SXUFCJBY.js} +18 -20
  3. package/dist/chunk-WUOGVGWG.js +1 -0
  4. package/dist/fetch.js +5 -22
  5. package/dist/hono.js +30 -0
  6. package/dist/index.js +689 -167
  7. package/dist/next.js +36 -0
  8. package/dist/node.js +69 -27
  9. package/dist/src/adapters/fetch/index.d.ts +0 -1
  10. package/dist/src/adapters/fetch/orpc-handler.d.ts +9 -9
  11. package/dist/src/adapters/fetch/orpc-payload-codec.d.ts +1 -1
  12. package/dist/src/adapters/fetch/types.d.ts +11 -6
  13. package/dist/src/adapters/hono/index.d.ts +3 -0
  14. package/dist/src/adapters/hono/middleware.d.ts +12 -0
  15. package/dist/src/adapters/next/index.d.ts +3 -0
  16. package/dist/src/adapters/next/serve.d.ts +19 -0
  17. package/dist/src/adapters/node/index.d.ts +1 -1
  18. package/dist/src/adapters/node/orpc-handler.d.ts +7 -7
  19. package/dist/src/adapters/node/request-listener.d.ts +28 -0
  20. package/dist/src/adapters/node/types.d.ts +10 -9
  21. package/dist/src/builder-with-errors-middlewares.d.ts +51 -0
  22. package/dist/src/builder-with-errors.d.ts +52 -0
  23. package/dist/src/builder-with-middlewares.d.ts +48 -0
  24. package/dist/src/builder.d.ts +36 -22
  25. package/dist/src/config.d.ts +6 -0
  26. package/dist/src/context.d.ts +11 -0
  27. package/dist/src/error.d.ts +10 -0
  28. package/dist/src/hidden.d.ts +2 -2
  29. package/dist/src/implementer-chainable.d.ts +7 -3
  30. package/dist/src/index.d.ts +5 -3
  31. package/dist/src/lazy-decorated.d.ts +3 -6
  32. package/dist/src/middleware-decorated.d.ts +7 -5
  33. package/dist/src/middleware.d.ts +21 -8
  34. package/dist/src/procedure-builder-with-input.d.ts +34 -0
  35. package/dist/src/procedure-builder-with-output.d.ts +33 -0
  36. package/dist/src/procedure-builder.d.ts +22 -17
  37. package/dist/src/procedure-client.d.ts +8 -20
  38. package/dist/src/procedure-decorated.d.ts +22 -10
  39. package/dist/src/procedure-implementer.d.ts +16 -12
  40. package/dist/src/procedure-utils.d.ts +17 -0
  41. package/dist/src/procedure.d.ts +35 -13
  42. package/dist/src/router-builder.d.ts +19 -15
  43. package/dist/src/router-client.d.ts +7 -6
  44. package/dist/src/router-implementer.d.ts +7 -6
  45. package/dist/src/router.d.ts +5 -5
  46. package/dist/src/types.d.ts +2 -0
  47. package/package.json +18 -8
  48. package/dist/src/adapters/fetch/composite-handler.d.ts +0 -8
  49. package/dist/src/adapters/node/composite-handler.d.ts +0 -9
@@ -32,6 +32,30 @@ function isProcedure(item) {
32
32
  return (typeof item === "object" || typeof item === "function") && item !== null && "~type" in item && item["~type"] === "Procedure" && "~orpc" in item && typeof item["~orpc"] === "object" && item["~orpc"] !== null && "contract" in item["~orpc"] && isContractProcedure(item["~orpc"].contract) && "handler" in item["~orpc"] && typeof item["~orpc"].handler === "function";
33
33
  }
34
34
 
35
+ // src/error.ts
36
+ import { ORPCError } from "@orpc/contract";
37
+ function createORPCErrorConstructorMap(errors) {
38
+ const constructors = {};
39
+ for (const code in errors) {
40
+ const config = errors[code];
41
+ if (!config) {
42
+ continue;
43
+ }
44
+ const constructor = (...[options]) => {
45
+ return new ORPCError({
46
+ code,
47
+ defined: true,
48
+ status: config.status,
49
+ message: options?.message ?? config.message,
50
+ data: options?.data,
51
+ cause: options?.cause
52
+ });
53
+ };
54
+ constructors[code] = constructor;
55
+ }
56
+ return constructors;
57
+ }
58
+
35
59
  // src/lazy.ts
36
60
  var LAZY_LOADER_SYMBOL = Symbol("ORPC_LAZY_LOADER");
37
61
  function lazy(loader) {
@@ -59,36 +83,44 @@ function flatLazy(lazied) {
59
83
  return lazy(flattenLoader);
60
84
  }
61
85
 
86
+ // src/middleware.ts
87
+ function middlewareOutputFn(output) {
88
+ return { output, context: void 0 };
89
+ }
90
+
62
91
  // src/procedure-client.ts
63
- import { executeWithHooks, value } from "@orpc/shared";
64
- import { ORPCError } from "@orpc/shared/error";
65
- function createProcedureClient(options) {
92
+ import { ORPCError as ORPCError2, validateORPCError, ValidationError } from "@orpc/contract";
93
+ import { executeWithHooks, toError, value } from "@orpc/shared";
94
+ function createProcedureClient(lazyableProcedure, ...[options]) {
66
95
  return async (...[input, callerOptions]) => {
67
- const path = options.path ?? [];
68
- const { default: procedure } = await unlazy(options.procedure);
69
- const context = await value(options.context);
70
- const meta = {
96
+ const path = options?.path ?? [];
97
+ const { default: procedure } = await unlazy(lazyableProcedure);
98
+ const context = await value(options?.context, callerOptions?.context);
99
+ const errors = createORPCErrorConstructorMap(procedure["~orpc"].contract["~orpc"].errorMap);
100
+ const executeOptions = {
101
+ input,
102
+ context,
103
+ errors,
71
104
  path,
72
105
  procedure,
73
106
  signal: callerOptions?.signal
74
107
  };
75
- const executeWithValidation = async () => {
76
- const validInput = await validateInput(procedure, input);
77
- const output = await executeMiddlewareChain(
78
- procedure,
79
- validInput,
108
+ try {
109
+ const output = await executeWithHooks({
110
+ hooks: options,
111
+ input,
80
112
  context,
81
- meta
82
- );
83
- return validateOutput(procedure, output);
84
- };
85
- return executeWithHooks({
86
- hooks: options,
87
- input,
88
- context,
89
- meta,
90
- execute: executeWithValidation
91
- });
113
+ meta: executeOptions,
114
+ execute: () => executeProcedureInternal(procedure, executeOptions)
115
+ });
116
+ return output;
117
+ } catch (e) {
118
+ if (!(e instanceof ORPCError2)) {
119
+ throw toError(e);
120
+ }
121
+ const validated = await validateORPCError(procedure["~orpc"].contract["~orpc"].errorMap, e);
122
+ throw validated;
123
+ }
92
124
  };
93
125
  }
94
126
  async function validateInput(procedure, input) {
@@ -97,10 +129,13 @@ async function validateInput(procedure, input) {
97
129
  return input;
98
130
  const result = await schema["~standard"].validate(input);
99
131
  if (result.issues) {
100
- throw new ORPCError({
132
+ throw new ORPCError2({
101
133
  message: "Input validation failed",
102
134
  code: "BAD_REQUEST",
103
- issues: result.issues
135
+ data: {
136
+ issues: result.issues
137
+ },
138
+ cause: new ValidationError({ message: "Input validation failed", issues: result.issues })
104
139
  });
105
140
  }
106
141
  return result.value;
@@ -111,33 +146,37 @@ async function validateOutput(procedure, output) {
111
146
  return output;
112
147
  const result = await schema["~standard"].validate(output);
113
148
  if (result.issues) {
114
- throw new ORPCError({
149
+ throw new ORPCError2({
115
150
  message: "Output validation failed",
116
151
  code: "INTERNAL_SERVER_ERROR",
117
- issues: result.issues
152
+ cause: new ValidationError({ message: "Output validation failed", issues: result.issues })
118
153
  });
119
154
  }
120
155
  return result.value;
121
156
  }
122
- async function executeMiddlewareChain(procedure, input, context, meta) {
123
- const middlewares = procedure["~orpc"].middlewares ?? [];
124
- let currentMidIndex = 0;
125
- let currentContext = context;
157
+ async function executeProcedureInternal(procedure, options) {
158
+ const middlewares = procedure["~orpc"].middlewares;
159
+ const inputValidationIndex = Math.min(Math.max(0, procedure["~orpc"].inputValidationIndex), middlewares.length);
160
+ const outputValidationIndex = Math.min(Math.max(0, procedure["~orpc"].outputValidationIndex), middlewares.length);
161
+ let currentIndex = 0;
162
+ let currentContext = options.context;
163
+ let currentInput = options.input;
126
164
  const next = async (nextOptions) => {
127
- const mid = middlewares[currentMidIndex];
128
- currentMidIndex += 1;
165
+ const index = currentIndex;
166
+ currentIndex += 1;
129
167
  currentContext = mergeContext(currentContext, nextOptions.context);
130
- if (mid) {
131
- return await mid(input, currentContext, {
132
- ...meta,
133
- next,
134
- output: (output) => ({ output, context: void 0 })
135
- });
168
+ if (index === inputValidationIndex) {
169
+ currentInput = await validateInput(procedure, currentInput);
170
+ }
171
+ const mid = middlewares[index];
172
+ const result = mid ? await mid({ ...options, context: currentContext, next }, currentInput, middlewareOutputFn) : { output: await procedure["~orpc"].handler({ ...options, context: currentContext, input: currentInput }), context: currentContext };
173
+ if (index === outputValidationIndex) {
174
+ const validatedOutput = await validateOutput(procedure, result.output);
175
+ return {
176
+ ...result,
177
+ output: validatedOutput
178
+ };
136
179
  }
137
- const result = {
138
- output: await procedure["~orpc"].handler(input, currentContext, meta),
139
- context: currentContext
140
- };
141
180
  return result;
142
181
  };
143
182
  return (await next({})).output;
@@ -178,12 +217,14 @@ export {
178
217
  mergeContext,
179
218
  Procedure,
180
219
  isProcedure,
220
+ createORPCErrorConstructorMap,
181
221
  LAZY_LOADER_SYMBOL,
182
222
  lazy,
183
223
  isLazy,
184
224
  unlazy,
185
225
  flatLazy,
226
+ middlewareOutputFn,
186
227
  createProcedureClient,
187
228
  getRouterChild
188
229
  };
189
- //# sourceMappingURL=chunk-6A7XHEBH.js.map
230
+ //# sourceMappingURL=chunk-GK2Z6B6W.js.map
@@ -4,7 +4,7 @@ import {
4
4
  getRouterChild,
5
5
  isProcedure,
6
6
  unlazy
7
- } from "./chunk-6A7XHEBH.js";
7
+ } from "./chunk-GK2Z6B6W.js";
8
8
 
9
9
  // src/adapters/fetch/super-json.ts
10
10
  var super_json_exports = {};
@@ -130,8 +130,8 @@ function deserialize({
130
130
  }
131
131
 
132
132
  // src/adapters/fetch/orpc-payload-codec.ts
133
+ import { ORPCError } from "@orpc/contract";
133
134
  import { findDeepMatches, set } from "@orpc/shared";
134
- import { ORPCError } from "@orpc/shared/error";
135
135
  var ORPCPayloadCodec = class {
136
136
  /**
137
137
  * If method is GET, the payload will be encoded as query string.
@@ -236,49 +236,46 @@ var ORPCProcedureMatcher = class {
236
236
  };
237
237
 
238
238
  // src/adapters/fetch/orpc-handler.ts
239
- import { executeWithHooks, ORPC_HANDLER_HEADER, ORPC_HANDLER_VALUE, trim as trim2 } from "@orpc/shared";
240
- import { ORPCError as ORPCError2 } from "@orpc/shared/error";
241
- var ORPCHandler = class {
239
+ import { ORPCError as ORPCError2 } from "@orpc/contract";
240
+ import { executeWithHooks, trim as trim2 } from "@orpc/shared";
241
+ var RPCHandler = class {
242
242
  constructor(router, options) {
243
- this.router = router;
244
243
  this.options = options;
245
244
  this.procedureMatcher = options?.procedureMatcher ?? new ORPCProcedureMatcher(router);
246
245
  this.payloadCodec = options?.payloadCodec ?? new ORPCPayloadCodec();
247
246
  }
248
247
  procedureMatcher;
249
248
  payloadCodec;
250
- condition(request) {
251
- return Boolean(request.headers.get(ORPC_HANDLER_HEADER)?.includes(ORPC_HANDLER_VALUE));
252
- }
253
- async fetch(request, ...[options]) {
249
+ async handle(request, ...[options]) {
254
250
  const context = options?.context;
255
251
  const execute = async () => {
256
252
  const url = new URL(request.url);
257
253
  const pathname = `/${trim2(url.pathname.replace(options?.prefix ?? "", ""), "/")}`;
258
254
  const match = await this.procedureMatcher.match(pathname);
259
255
  if (!match) {
260
- throw new ORPCError2({ code: "NOT_FOUND", message: "Not found" });
256
+ return { matched: false, response: void 0 };
261
257
  }
262
258
  const input = await this.payloadCodec.decode(request);
263
- const client = createProcedureClient({
259
+ const client = createProcedureClient(match.procedure, {
264
260
  context,
265
- procedure: match.procedure,
266
261
  path: match.path
267
262
  });
268
- const output = await client(input, { signal: options?.signal });
263
+ const output = await client(input, { signal: request.signal });
269
264
  const { body, headers } = this.payloadCodec.encode(output);
270
- return new Response(body, { headers });
265
+ const response = new Response(body, { headers });
266
+ return { matched: true, response };
271
267
  };
272
268
  try {
273
- return await executeWithHooks({
269
+ const result = await executeWithHooks({
274
270
  context,
275
271
  execute,
276
272
  input: request,
277
273
  hooks: this.options,
278
274
  meta: {
279
- signal: options?.signal
275
+ signal: request.signal
280
276
  }
281
277
  });
278
+ return result;
282
279
  } catch (e) {
283
280
  const error = e instanceof ORPCError2 ? e : new ORPCError2({
284
281
  code: "INTERNAL_SERVER_ERROR",
@@ -286,10 +283,11 @@ var ORPCHandler = class {
286
283
  cause: e
287
284
  });
288
285
  const { body, headers } = this.payloadCodec.encode(error.toJSON());
289
- return new Response(body, {
286
+ const response = new Response(body, {
290
287
  headers,
291
288
  status: error.status
292
289
  });
290
+ return { matched: true, response };
293
291
  }
294
292
  }
295
293
  };
@@ -298,6 +296,6 @@ export {
298
296
  super_json_exports,
299
297
  ORPCPayloadCodec,
300
298
  ORPCProcedureMatcher,
301
- ORPCHandler
299
+ RPCHandler
302
300
  };
303
- //# sourceMappingURL=chunk-B2EZJB7X.js.map
301
+ //# sourceMappingURL=chunk-SXUFCJBY.js.map
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-WUOGVGWG.js.map
package/dist/fetch.js CHANGED
@@ -1,32 +1,15 @@
1
+ import "./chunk-WUOGVGWG.js";
1
2
  import {
2
- ORPCHandler,
3
3
  ORPCPayloadCodec,
4
4
  ORPCProcedureMatcher,
5
+ RPCHandler,
5
6
  super_json_exports
6
- } from "./chunk-B2EZJB7X.js";
7
- import "./chunk-6A7XHEBH.js";
8
-
9
- // src/adapters/fetch/composite-handler.ts
10
- var CompositeHandler = class {
11
- constructor(handlers) {
12
- this.handlers = handlers;
13
- }
14
- async fetch(request, ...opt) {
15
- for (const handler of this.handlers) {
16
- if (handler.condition(request)) {
17
- return handler.fetch(request, ...opt);
18
- }
19
- }
20
- return new Response("None of the handlers can handle the request.", {
21
- status: 404
22
- });
23
- }
24
- };
7
+ } from "./chunk-SXUFCJBY.js";
8
+ import "./chunk-GK2Z6B6W.js";
25
9
  export {
26
- CompositeHandler,
27
- ORPCHandler,
28
10
  ORPCPayloadCodec,
29
11
  ORPCProcedureMatcher,
12
+ RPCHandler,
30
13
  super_json_exports as SuperJSON
31
14
  };
32
15
  //# sourceMappingURL=fetch.js.map
package/dist/hono.js ADDED
@@ -0,0 +1,30 @@
1
+ import "./chunk-WUOGVGWG.js";
2
+ import {
3
+ ORPCPayloadCodec,
4
+ ORPCProcedureMatcher,
5
+ RPCHandler,
6
+ super_json_exports
7
+ } from "./chunk-SXUFCJBY.js";
8
+ import "./chunk-GK2Z6B6W.js";
9
+
10
+ // src/adapters/hono/middleware.ts
11
+ import { value } from "@orpc/shared";
12
+ function createMiddleware(handler, ...[options]) {
13
+ return async (c, next) => {
14
+ const context = await value(options?.context, c);
15
+ const { matched, response } = await handler.handle(c.req.raw, { ...options, context });
16
+ if (matched) {
17
+ c.res = response;
18
+ return;
19
+ }
20
+ await next();
21
+ };
22
+ }
23
+ export {
24
+ ORPCPayloadCodec,
25
+ ORPCProcedureMatcher,
26
+ RPCHandler,
27
+ super_json_exports as SuperJSON,
28
+ createMiddleware
29
+ };
30
+ //# sourceMappingURL=hono.js.map