@orpc/server 0.13.0 → 0.14.0

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.
@@ -45,9 +45,8 @@ function decorateMiddleware(middleware) {
45
45
  }
46
46
 
47
47
  // src/procedure-caller.ts
48
- import { trim, value } from "@orpc/shared";
48
+ import { executeWithHooks, trim, value } from "@orpc/shared";
49
49
  import { ORPCError } from "@orpc/shared/error";
50
- import { OpenAPIDeserializer } from "@orpc/transformer";
51
50
 
52
51
  // src/procedure.ts
53
52
  import {
@@ -109,96 +108,101 @@ function isProcedure(item) {
109
108
 
110
109
  // src/procedure-caller.ts
111
110
  function createProcedureCaller(options) {
112
- const loadProcedure = async () => {
113
- let procedure;
114
- if (isLazy(options.procedure)) {
115
- procedure = (await loadLazy(options.procedure)).default;
116
- } else {
117
- procedure = options.procedure;
118
- }
119
- if (!isProcedure(procedure)) {
120
- throw new ORPCError({
121
- code: "NOT_FOUND",
122
- message: "Not found",
123
- cause: new Error(trim(`
124
- This error should be caught by the typescript compiler.
125
- But if you still see this error, it means that you trying to call a lazy router (expected to be a lazy procedure).
126
- `))
127
- });
128
- }
129
- return procedure;
130
- };
131
111
  const caller = async (input) => {
132
112
  const path = options.path ?? [];
133
- const procedure = await loadProcedure();
134
- const input_ = (() => {
135
- if (!(input instanceof FormData)) {
136
- return input;
137
- }
138
- const transformer = new OpenAPIDeserializer({
139
- schema: procedure.zz$p.contract.zz$cp.InputSchema
140
- });
141
- return transformer.deserializeAsFormData(input);
142
- })();
143
- const validInput = (() => {
144
- const schema = procedure.zz$p.contract.zz$cp.InputSchema;
145
- if (!schema) {
146
- return input_;
147
- }
148
- try {
149
- return schema.parse(input_);
150
- } catch (e) {
151
- throw new ORPCError({
152
- message: "Validation input failed",
153
- code: "BAD_REQUEST",
154
- cause: e
155
- });
156
- }
157
- })();
158
- const middlewares = procedure.zz$p.middlewares ?? [];
159
- let currentMidIndex = 0;
160
- let currentContext = await value(options.context);
161
- const next = async (nextOptions) => {
162
- const mid = middlewares[currentMidIndex];
163
- currentMidIndex += 1;
164
- currentContext = mergeContext(currentContext, nextOptions.context);
165
- if (mid) {
166
- return await mid(validInput, currentContext, {
167
- path,
168
- procedure,
169
- next,
170
- output: (output2) => ({ output: output2, context: void 0 })
171
- });
172
- } else {
173
- return {
174
- output: await await procedure.zz$p.func(validInput, currentContext, {
113
+ const procedure = await loadProcedure(options.procedure);
114
+ const context = await value(options.context);
115
+ const execute = async () => {
116
+ const validInput = (() => {
117
+ const schema = procedure.zz$p.contract.zz$cp.InputSchema;
118
+ if (!schema) {
119
+ return input;
120
+ }
121
+ try {
122
+ return schema.parse(input);
123
+ } catch (e) {
124
+ throw new ORPCError({
125
+ message: "Validation input failed",
126
+ code: "BAD_REQUEST",
127
+ cause: e
128
+ });
129
+ }
130
+ })();
131
+ const middlewares = procedure.zz$p.middlewares ?? [];
132
+ let currentMidIndex = 0;
133
+ let currentContext = context;
134
+ const next = async (nextOptions) => {
135
+ const mid = middlewares[currentMidIndex];
136
+ currentMidIndex += 1;
137
+ currentContext = mergeContext(currentContext, nextOptions.context);
138
+ if (mid) {
139
+ return await mid(validInput, currentContext, {
175
140
  path,
176
- procedure
177
- }),
178
- context: currentContext
179
- };
180
- }
141
+ procedure,
142
+ next,
143
+ output: (output3) => ({ output: output3, context: void 0 })
144
+ });
145
+ } else {
146
+ return {
147
+ output: await await procedure.zz$p.func(validInput, currentContext, {
148
+ path,
149
+ procedure
150
+ }),
151
+ context: currentContext
152
+ };
153
+ }
154
+ };
155
+ const output2 = (await next({})).output;
156
+ const validOutput = await (async () => {
157
+ const schema = procedure.zz$p.contract.zz$cp.OutputSchema;
158
+ if (!schema) {
159
+ return output2;
160
+ }
161
+ const result = await schema.safeParseAsync(output2);
162
+ if (result.error) {
163
+ throw new ORPCError({
164
+ message: "Validation output failed",
165
+ code: "INTERNAL_SERVER_ERROR",
166
+ cause: result.error
167
+ });
168
+ }
169
+ return result.data;
170
+ })();
171
+ return validOutput;
181
172
  };
182
- const output = (await next({})).output;
183
- const validOutput = await (async () => {
184
- const schema = procedure.zz$p.contract.zz$cp.OutputSchema;
185
- if (!schema) {
186
- return output;
187
- }
188
- const result = await schema.safeParseAsync(output);
189
- if (result.error) {
190
- throw new ORPCError({
191
- message: "Validation output failed",
192
- code: "INTERNAL_SERVER_ERROR",
193
- cause: result.error
194
- });
195
- }
196
- return result.data;
197
- })();
198
- return validOutput;
173
+ const output = await executeWithHooks({
174
+ hooks: options,
175
+ input,
176
+ context,
177
+ meta: {
178
+ path,
179
+ procedure
180
+ },
181
+ execute
182
+ });
183
+ return output;
199
184
  };
200
185
  return caller;
201
186
  }
187
+ async function loadProcedure(procedure) {
188
+ let loadedProcedure;
189
+ if (isLazy(procedure)) {
190
+ loadedProcedure = (await loadLazy(procedure)).default;
191
+ } else {
192
+ loadedProcedure = procedure;
193
+ }
194
+ if (!isProcedure(loadedProcedure)) {
195
+ throw new ORPCError({
196
+ code: "NOT_FOUND",
197
+ message: "Not found",
198
+ cause: new Error(trim(`
199
+ This error should be caught by the typescript compiler.
200
+ But if you still see this error, it means that you trying to call a lazy router (expected to be a lazy procedure).
201
+ `))
202
+ });
203
+ }
204
+ return loadedProcedure;
205
+ }
202
206
 
203
207
  // src/lazy.ts
204
208
  var LAZY_LOADER_SYMBOL = Symbol("ORPC_LAZY_LOADER");
@@ -260,8 +264,9 @@ export {
260
264
  createFlattenLazy,
261
265
  decorateLazy,
262
266
  createProcedureCaller,
267
+ loadProcedure,
263
268
  Procedure,
264
269
  decorateProcedure,
265
270
  isProcedure
266
271
  };
267
- //# sourceMappingURL=chunk-FL4ZAGNE.js.map
272
+ //# sourceMappingURL=chunk-MZXEMHFS.js.map
package/dist/fetch.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  createProcedureCaller,
3
3
  isLazy,
4
4
  isProcedure
5
- } from "./chunk-FL4ZAGNE.js";
5
+ } from "./chunk-MZXEMHFS.js";
6
6
 
7
7
  // src/fetch/handle.ts
8
8
  import { ORPCError } from "@orpc/shared/error";
@@ -24,7 +24,7 @@ async function handleFetchRequest(options) {
24
24
 
25
25
  // src/fetch/handler.ts
26
26
  import { ORPC_HEADER, ORPC_HEADER_VALUE } from "@orpc/contract";
27
- import { trim, value } from "@orpc/shared";
27
+ import { executeWithHooks, trim, value } from "@orpc/shared";
28
28
  import { ORPCError as ORPCError2 } from "@orpc/shared/error";
29
29
  import { ORPCDeserializer, ORPCSerializer } from "@orpc/transformer";
30
30
  var serializer = new ORPCSerializer();
@@ -56,10 +56,13 @@ function createORPCHandler() {
56
56
  });
57
57
  };
58
58
  try {
59
- return await options.hooks?.(
59
+ return await executeWithHooks({
60
+ hooks: options,
60
61
  context,
61
- { next: handler, response: (response) => response }
62
- ) ?? await handler();
62
+ execute: handler,
63
+ input: options.request,
64
+ meta: void 0
65
+ });
63
66
  } catch (e) {
64
67
  const error = e instanceof ORPCError2 ? e : new ORPCError2({
65
68
  code: "INTERNAL_SERVER_ERROR",
package/dist/index.js CHANGED
@@ -10,8 +10,9 @@ import {
10
10
  isLazy,
11
11
  isProcedure,
12
12
  loadLazy,
13
+ loadProcedure,
13
14
  mergeContext
14
- } from "./chunk-FL4ZAGNE.js";
15
+ } from "./chunk-MZXEMHFS.js";
15
16
 
16
17
  // src/builder.ts
17
18
  import {
@@ -409,28 +410,25 @@ function toContractRouter(router) {
409
410
 
410
411
  // src/router-caller.ts
411
412
  function createRouterCaller(options) {
412
- return createRouterCallerInternal({
413
- current: options.router,
414
- context: options.context,
415
- path: options.basePath ?? []
416
- });
413
+ return createRouterCallerInternal(options);
417
414
  }
418
415
  function createRouterCallerInternal(options) {
419
- const procedureCaller = isLazy(options.current) || isProcedure(options.current) ? createProcedureCaller({
420
- procedure: options.current,
416
+ const procedureCaller = isLazy(options.router) || isProcedure(options.router) ? createProcedureCaller({
417
+ ...options,
418
+ procedure: options.router,
421
419
  context: options.context,
422
- path: options.path
420
+ path: options.basePath
423
421
  }) : {};
424
422
  const recursive = new Proxy(procedureCaller, {
425
423
  get(target, key) {
426
424
  if (typeof key !== "string") {
427
425
  return Reflect.get(target, key);
428
426
  }
429
- const next = options.current[key];
427
+ const next = options.router[key];
430
428
  return createRouterCallerInternal({
431
- current: next,
432
- context: options.context,
433
- path: [...options.path, key]
429
+ ...options,
430
+ router: next,
431
+ basePath: [...options.basePath ?? [], key]
434
432
  });
435
433
  }
436
434
  });
@@ -461,6 +459,7 @@ export {
461
459
  isLazy,
462
460
  isProcedure,
463
461
  loadLazy,
462
+ loadProcedure,
464
463
  mergeContext,
465
464
  os,
466
465
  toContractRouter
@@ -1,9 +1,5 @@
1
- import type { PartialOnUndefinedDeep, Promisable, Value } from '@orpc/shared';
1
+ import type { Hooks, PartialOnUndefinedDeep, Value } from '@orpc/shared';
2
2
  import type { Router } from '../router';
3
- export interface FetchHandlerHooks {
4
- next: () => Promise<Response>;
5
- response: (response: Response) => Response;
6
- }
7
3
  export type FetchHandlerOptions<TRouter extends Router<any>> = {
8
4
  /**
9
5
  * The `router` used for handling the request and routing,
@@ -21,15 +17,11 @@ export type FetchHandlerOptions<TRouter extends Router<any>> = {
21
17
  * @example /api
22
18
  */
23
19
  prefix?: string;
24
- /**
25
- * Hooks for executing logics on lifecycle events.
26
- */
27
- hooks?: (context: TRouter extends Router<infer UContext> ? UContext : never, hooks: FetchHandlerHooks) => Promisable<Response>;
28
20
  } & PartialOnUndefinedDeep<{
29
21
  /**
30
22
  * The context used to handle the request.
31
23
  */
32
24
  context: Value<TRouter extends Router<infer UContext> ? UContext : never>;
33
- }>;
25
+ }> & Hooks<Request, Response, TRouter extends Router<infer UContext> ? UContext : never, undefined>;
34
26
  export type FetchHandler = <TRouter extends Router<any>>(options: FetchHandlerOptions<TRouter>) => Promise<Response | undefined>;
35
27
  //# sourceMappingURL=types.d.ts.map
@@ -1,20 +1,25 @@
1
1
  import type { SchemaInput, SchemaOutput } from '@orpc/contract';
2
+ import type { Hooks, PartialOnUndefinedDeep, Value } from '@orpc/shared';
2
3
  import type { Lazy } from './lazy';
3
- import { type Value } from '@orpc/shared';
4
- import { type ANY_LAZY_PROCEDURE, type ANY_PROCEDURE, type Procedure } from './procedure';
5
- export interface CreateProcedureCallerOptions<TProcedure extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE> {
6
- procedure: TProcedure;
7
- /**
8
- * The context used when calling the procedure.
9
- */
10
- context: Value<TProcedure extends Procedure<infer UContext, any, any, any, any> | Lazy<Procedure<infer UContext, any, any, any, any>> ? UContext : never>;
4
+ import type { ANY_LAZY_PROCEDURE, ANY_PROCEDURE, Procedure } from './procedure';
5
+ export type CreateProcedureCallerOptions<T extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE> = T extends Procedure<infer UContext, any, any, infer UOutputSchema, infer UFuncOutput> | Lazy<Procedure<infer UContext, any, any, infer UOutputSchema, infer UFuncOutput>> ? {
6
+ procedure: T;
11
7
  /**
12
8
  * This is helpful for logging and analytics.
13
9
  *
14
10
  * @internal
15
11
  */
16
12
  path?: string[];
17
- }
18
- export type ProcedureCaller<TProcedure extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE> = TProcedure extends Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput> | Lazy<Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput>> ? (...input: [input: SchemaInput<UInputSchema> | FormData] | (undefined extends SchemaInput<UInputSchema> ? [] : never)) => Promise<SchemaOutput<UOutputSchema, UFuncOutput>> : never;
13
+ } & PartialOnUndefinedDeep<{
14
+ /**
15
+ * The context used when calling the procedure.
16
+ */
17
+ context: Value<UContext>;
18
+ }> & Hooks<unknown, SchemaOutput<UOutputSchema, UFuncOutput>, UContext, {
19
+ path: string[];
20
+ procedure: ANY_PROCEDURE;
21
+ }> : never;
22
+ export type ProcedureCaller<TProcedure extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE> = TProcedure extends Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput> | Lazy<Procedure<any, any, infer UInputSchema, infer UOutputSchema, infer UFuncOutput>> ? (...input: [input: SchemaInput<UInputSchema>] | (undefined extends SchemaInput<UInputSchema> ? [] : never)) => Promise<SchemaOutput<UOutputSchema, UFuncOutput>> : never;
19
23
  export declare function createProcedureCaller<TProcedure extends ANY_PROCEDURE | ANY_LAZY_PROCEDURE>(options: CreateProcedureCallerOptions<TProcedure>): ProcedureCaller<TProcedure>;
24
+ export declare function loadProcedure(procedure: ANY_PROCEDURE | ANY_LAZY_PROCEDURE): Promise<ANY_PROCEDURE>;
20
25
  //# sourceMappingURL=procedure-caller.d.ts.map
@@ -1,8 +1,11 @@
1
- import type { Value } from '@orpc/shared';
1
+ import type { Hooks, Value } from '@orpc/shared';
2
2
  import type { ANY_LAZY_PROCEDURE, ANY_PROCEDURE } from './procedure';
3
3
  import type { Router } from './router';
4
4
  import { type ProcedureCaller } from './procedure-caller';
5
- export interface CreateRouterCallerOptions<TRouter extends Router<any>> {
5
+ export interface CreateRouterCallerOptions<TRouter extends Router<any>> extends Hooks<unknown, unknown, TRouter extends Router<infer UContext> ? UContext : never, {
6
+ path: string[];
7
+ procedure: ANY_PROCEDURE;
8
+ }> {
6
9
  router: TRouter;
7
10
  /**
8
11
  * The context used when calling the procedure.
@@ -13,9 +13,9 @@ export type RouterWithContract<TContext extends Context, TContract extends Contr
13
13
  };
14
14
  export declare function toContractRouter(router: ContractRouter | Router<any>): ContractRouter;
15
15
  export type InferRouterInputs<T extends Router<any>> = {
16
- [K in keyof T]: T[K] extends Procedure<any, any, infer UInputSchema, any, any> ? SchemaInput<UInputSchema> : T[K] extends Router<any> ? InferRouterInputs<T[K]> : never;
16
+ [K in keyof T]: T[K] extends Procedure<any, any, infer UInputSchema, any, any> | Lazy<Procedure<any, any, infer UInputSchema, any, any>> ? SchemaInput<UInputSchema> : T[K] extends Router<any> ? InferRouterInputs<T[K]> : never;
17
17
  };
18
18
  export type InferRouterOutputs<T extends Router<any>> = {
19
- [K in keyof T]: T[K] extends Procedure<any, any, any, infer UOutputSchema, infer UFuncOutput> ? SchemaOutput<UOutputSchema, UFuncOutput> : T[K] extends Router<any> ? InferRouterOutputs<T[K]> : never;
19
+ [K in keyof T]: T[K] extends Procedure<any, any, any, infer UOutputSchema, infer UFuncOutput> | Lazy<Procedure<any, any, any, infer UOutputSchema, infer UFuncOutput>> ? SchemaOutput<UOutputSchema, UFuncOutput> : T[K] extends Router<any> ? InferRouterOutputs<T[K]> : never;
20
20
  };
21
21
  //# sourceMappingURL=router.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/server",
3
3
  "type": "module",
4
- "version": "0.13.0",
4
+ "version": "0.14.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -35,15 +35,15 @@
35
35
  ],
36
36
  "peerDependencies": {
37
37
  "zod": ">=3.23.0",
38
- "@orpc/zod": "0.13.0"
38
+ "@orpc/zod": "0.14.0"
39
39
  },
40
40
  "dependencies": {
41
- "@orpc/transformer": "0.13.0",
42
- "@orpc/contract": "0.13.0",
43
- "@orpc/shared": "0.13.0"
41
+ "@orpc/shared": "0.14.0",
42
+ "@orpc/transformer": "0.14.0",
43
+ "@orpc/contract": "0.14.0"
44
44
  },
45
45
  "devDependencies": {
46
- "@orpc/openapi": "0.13.0"
46
+ "@orpc/openapi": "0.14.0"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsup --clean --sourcemap --entry.index=src/index.ts --entry.fetch=src/fetch/index.ts --format=esm --onSuccess='tsc -b --noCheck'",