@orpc/server 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. package/dist/chunk-26DTFWOI.js +200 -0
  2. package/dist/chunk-26DTFWOI.js.map +1 -0
  3. package/dist/fetch.js +87 -91
  4. package/dist/fetch.js.map +1 -1
  5. package/dist/index.js +6 -9
  6. package/dist/index.js.map +1 -1
  7. package/dist/src/adapters/fetch.d.ts +9 -3
  8. package/dist/src/adapters/fetch.d.ts.map +1 -1
  9. package/dist/src/builder.d.ts +4 -4
  10. package/dist/src/builder.d.ts.map +1 -1
  11. package/dist/src/index.d.ts +2 -2
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/middleware.d.ts +17 -7
  14. package/dist/src/middleware.d.ts.map +1 -1
  15. package/dist/src/procedure-builder.d.ts +4 -4
  16. package/dist/src/procedure-builder.d.ts.map +1 -1
  17. package/dist/src/procedure-caller.d.ts +0 -5
  18. package/dist/src/procedure-caller.d.ts.map +1 -1
  19. package/dist/src/procedure-implementer.d.ts +4 -5
  20. package/dist/src/procedure-implementer.d.ts.map +1 -1
  21. package/dist/src/procedure.d.ts +8 -9
  22. package/dist/src/procedure.d.ts.map +1 -1
  23. package/dist/src/router-builder.d.ts +2 -2
  24. package/dist/src/router-builder.d.ts.map +1 -1
  25. package/dist/src/router-caller.d.ts +1 -6
  26. package/dist/src/router-caller.d.ts.map +1 -1
  27. package/dist/src/router-implementer.d.ts +2 -2
  28. package/dist/src/router-implementer.d.ts.map +1 -1
  29. package/dist/src/router.d.ts +1 -1
  30. package/dist/src/router.d.ts.map +1 -1
  31. package/dist/src/types.d.ts +1 -10
  32. package/dist/src/types.d.ts.map +1 -1
  33. package/dist/src/utils.d.ts +1 -2
  34. package/dist/src/utils.d.ts.map +1 -1
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +5 -5
  37. package/src/adapters/fetch.test.ts +32 -17
  38. package/src/adapters/fetch.ts +134 -123
  39. package/src/builder.test.ts +48 -39
  40. package/src/builder.ts +32 -30
  41. package/src/index.ts +2 -2
  42. package/src/middleware.test.ts +54 -73
  43. package/src/middleware.ts +39 -22
  44. package/src/procedure-builder.test.ts +26 -22
  45. package/src/procedure-builder.ts +15 -15
  46. package/src/procedure-caller.test.ts +25 -70
  47. package/src/procedure-caller.ts +69 -88
  48. package/src/procedure-implementer.test.ts +27 -22
  49. package/src/procedure-implementer.ts +16 -17
  50. package/src/procedure.test.ts +17 -12
  51. package/src/procedure.ts +46 -45
  52. package/src/router-builder.test.ts +4 -4
  53. package/src/router-builder.ts +12 -10
  54. package/src/router-caller.test.ts +6 -6
  55. package/src/router-caller.ts +5 -16
  56. package/src/router-implementer.test.ts +12 -12
  57. package/src/router-implementer.ts +9 -6
  58. package/src/router.test.ts +4 -4
  59. package/src/router.ts +12 -10
  60. package/src/types.test.ts +1 -1
  61. package/src/types.ts +1 -15
  62. package/src/utils.test.ts +2 -229
  63. package/src/utils.ts +5 -84
  64. package/dist/chunk-ACLC6USM.js +0 -262
  65. package/dist/chunk-ACLC6USM.js.map +0 -1
@@ -0,0 +1,200 @@
1
+ // src/utils.ts
2
+ function mergeContext(a, b) {
3
+ if (!a)
4
+ return b;
5
+ if (!b)
6
+ return a;
7
+ return {
8
+ ...a,
9
+ ...b
10
+ };
11
+ }
12
+
13
+ // src/middleware.ts
14
+ var decoratedMiddlewareSymbol = Symbol("\u{1F512}decoratedMiddleware");
15
+ function decorateMiddleware(middleware) {
16
+ if (Reflect.get(middleware, decoratedMiddlewareSymbol)) {
17
+ return middleware;
18
+ }
19
+ const concat = (concatMiddleware, mapInput2) => {
20
+ const concatMiddleware_ = mapInput2 ? decorateMiddleware(concatMiddleware).mapInput(mapInput2) : concatMiddleware;
21
+ return decorateMiddleware(async (input, context, meta, ...rest) => {
22
+ const input_ = input;
23
+ const context_ = context;
24
+ const meta_ = meta;
25
+ const next = async (options) => {
26
+ return concatMiddleware_(input_, mergeContext(context_, options.context), meta_, ...rest);
27
+ };
28
+ const m1 = await middleware(input_, context_, {
29
+ ...meta_,
30
+ next
31
+ }, ...rest);
32
+ return m1;
33
+ });
34
+ };
35
+ const mapInput = (map) => {
36
+ return decorateMiddleware(
37
+ (input, ...rest) => middleware(map(input), ...rest)
38
+ );
39
+ };
40
+ return Object.assign(middleware, {
41
+ [decoratedMiddlewareSymbol]: true,
42
+ concat,
43
+ mapInput
44
+ });
45
+ }
46
+
47
+ // src/procedure-caller.ts
48
+ import { ORPCError } from "@orpc/shared/error";
49
+ function createProcedureCaller(options) {
50
+ const internal = options.internal ?? true;
51
+ const path = options.path ?? [];
52
+ const procedure = options.procedure;
53
+ const validate = options.validate ?? true;
54
+ const caller = async (input) => {
55
+ const validInput = (() => {
56
+ if (!validate)
57
+ return input;
58
+ const schema = procedure.zz$p.contract.zz$cp.InputSchema;
59
+ if (!schema)
60
+ return input;
61
+ try {
62
+ return schema.parse(input);
63
+ } catch (e) {
64
+ throw new ORPCError({
65
+ message: "Validation input failed",
66
+ code: "BAD_REQUEST",
67
+ cause: e
68
+ });
69
+ }
70
+ })();
71
+ const middlewares = procedure.zz$p.middlewares ?? [];
72
+ let currentMidIndex = 0;
73
+ let currentContext = options.context;
74
+ const next = async (nextOptions) => {
75
+ const mid = middlewares[currentMidIndex];
76
+ currentMidIndex += 1;
77
+ currentContext = mergeContext(currentContext, nextOptions.context);
78
+ if (mid) {
79
+ return await mid(validInput, currentContext, {
80
+ path,
81
+ procedure,
82
+ internal,
83
+ next,
84
+ output: (output2) => ({ output: output2, context: void 0 })
85
+ });
86
+ } else {
87
+ return {
88
+ output: await await procedure.zz$p.handler(validInput, currentContext, {
89
+ path,
90
+ procedure,
91
+ internal
92
+ }),
93
+ context: currentContext
94
+ };
95
+ }
96
+ };
97
+ const output = (await next({})).output;
98
+ const validOutput = await (async () => {
99
+ if (!validate)
100
+ return output;
101
+ const schema = procedure.zz$p.contract.zz$cp.OutputSchema;
102
+ if (!schema)
103
+ return output;
104
+ const result = await schema.safeParseAsync(output);
105
+ if (result.error) {
106
+ throw new ORPCError({
107
+ message: "Validation output failed",
108
+ code: "INTERNAL_SERVER_ERROR",
109
+ cause: result.error
110
+ });
111
+ }
112
+ return result.data;
113
+ })();
114
+ return validOutput;
115
+ };
116
+ return caller;
117
+ }
118
+
119
+ // src/procedure.ts
120
+ import {
121
+ DecoratedContractProcedure,
122
+ isContractProcedure
123
+ } from "@orpc/contract";
124
+ import { OpenAPIDeserializer } from "@orpc/transformer";
125
+ var Procedure = class {
126
+ constructor(zz$p) {
127
+ this.zz$p = zz$p;
128
+ }
129
+ };
130
+ var DECORATED_PROCEDURE_SYMBOL = Symbol("DECORATED_PROCEDURE");
131
+ function decorateProcedure(procedure) {
132
+ if (DECORATED_PROCEDURE_SYMBOL in procedure) {
133
+ return procedure;
134
+ }
135
+ const serverAction = async (input) => {
136
+ const input_ = (() => {
137
+ if (!(input instanceof FormData))
138
+ return input;
139
+ const transformer = new OpenAPIDeserializer({
140
+ schema: procedure.zz$p.contract.zz$cp.InputSchema
141
+ });
142
+ return transformer.deserializeAsFormData(input);
143
+ })();
144
+ const procedureCaller = createProcedureCaller({
145
+ procedure,
146
+ context: void 0,
147
+ internal: false,
148
+ validate: true
149
+ });
150
+ return await procedureCaller(input_);
151
+ };
152
+ return Object.assign(serverAction, {
153
+ [DECORATED_PROCEDURE_SYMBOL]: true,
154
+ zz$p: procedure.zz$p,
155
+ prefix(prefix) {
156
+ return decorateProcedure({
157
+ zz$p: {
158
+ ...procedure.zz$p,
159
+ contract: DecoratedContractProcedure.decorate(
160
+ procedure.zz$p.contract
161
+ ).prefix(prefix)
162
+ }
163
+ });
164
+ },
165
+ route(opts) {
166
+ return decorateProcedure({
167
+ zz$p: {
168
+ ...procedure.zz$p,
169
+ contract: DecoratedContractProcedure.decorate(
170
+ procedure.zz$p.contract
171
+ ).route(opts)
172
+ }
173
+ });
174
+ },
175
+ use(middleware, mapInput) {
176
+ const middleware_ = mapInput ? decorateMiddleware(middleware).mapInput(mapInput) : middleware;
177
+ return decorateProcedure({
178
+ zz$p: {
179
+ ...procedure.zz$p,
180
+ middlewares: [middleware_, ...procedure.zz$p.middlewares ?? []]
181
+ }
182
+ });
183
+ }
184
+ });
185
+ }
186
+ function isProcedure(item) {
187
+ if (item instanceof Procedure)
188
+ return true;
189
+ return (typeof item === "object" || typeof item === "function") && item !== null && "zz$p" in item && typeof item.zz$p === "object" && item.zz$p !== null && "contract" in item.zz$p && isContractProcedure(item.zz$p.contract) && "handler" in item.zz$p && typeof item.zz$p.handler === "function";
190
+ }
191
+
192
+ export {
193
+ mergeContext,
194
+ decorateMiddleware,
195
+ createProcedureCaller,
196
+ Procedure,
197
+ decorateProcedure,
198
+ isProcedure
199
+ };
200
+ //# sourceMappingURL=chunk-26DTFWOI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/middleware.ts","../src/procedure-caller.ts","../src/procedure.ts"],"sourcesContent":["import type { Context, MergeContext } from './types'\n\nexport function mergeContext<A extends Context, B extends Context>(\n a: A,\n b: B,\n): MergeContext<A, B> {\n if (!a)\n return b as any\n if (!b)\n return a as any\n\n return {\n ...a,\n ...b,\n } as any\n}\n","import type { Promisable } from '@orpc/shared'\nimport type { Context, MergeContext, Meta } from './types'\nimport { mergeContext } from './utils'\n\nexport type MiddlewareResult<TExtraContext extends Context, TOutput> = Promisable<{\n output: TOutput\n context: TExtraContext\n}>\n\nexport interface MiddlewareMeta<\n TOutput,\n> extends Meta {\n next: <UExtraContext extends Context = undefined>(\n options: UExtraContext extends undefined ? { context?: UExtraContext } : { context: UExtraContext }\n ) => MiddlewareResult<UExtraContext, TOutput>\n output: <UOutput>(output: UOutput) => MiddlewareResult<undefined, UOutput>\n}\n\nexport interface Middleware<\n TContext extends Context,\n TExtraContext extends Context,\n TInput,\n TOutput,\n> {\n (\n input: TInput,\n context: TContext,\n meta: MiddlewareMeta<TOutput>,\n ): Promisable<\n MiddlewareResult<TExtraContext, TOutput>\n >\n}\n\nexport interface MapInputMiddleware<TInput, TMappedInput> {\n (input: TInput): TMappedInput\n}\n\nexport interface DecoratedMiddleware<\n TContext extends Context,\n TExtraContext extends Context,\n TInput,\n TOutput,\n> extends Middleware<TContext, TExtraContext, TInput, TOutput> {\n concat: (<\n UExtraContext extends Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>> | undefined = undefined,\n UInput = TInput,\n >(\n middleware: Middleware<\n MergeContext<TContext, TExtraContext>,\n UExtraContext,\n UInput & TInput,\n TOutput\n >,\n ) => DecoratedMiddleware<\n TContext,\n MergeContext<TExtraContext, UExtraContext>,\n TInput & UInput,\n TOutput\n >) & (<\n UExtraContext extends Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>> | undefined = undefined,\n UInput = TInput,\n UMappedInput = unknown,\n >(\n middleware: Middleware<\n MergeContext<TContext, TExtraContext>,\n UExtraContext,\n UMappedInput,\n TOutput\n >,\n mapInput: MapInputMiddleware<UInput, UMappedInput>,\n ) => DecoratedMiddleware<\n TContext,\n MergeContext<TExtraContext, UExtraContext>,\n TInput & UInput,\n TOutput\n >)\n\n mapInput: <UInput = unknown>(\n map: MapInputMiddleware<UInput, TInput>,\n ) => DecoratedMiddleware<TContext, TExtraContext, UInput, TOutput>\n}\n\nconst decoratedMiddlewareSymbol = Symbol('🔒decoratedMiddleware')\n\nexport function decorateMiddleware<\n TContext extends Context,\n TExtraContext extends Context,\n TInput,\n TOutput,\n>(\n middleware: Middleware<TContext, TExtraContext, TInput, TOutput>,\n): DecoratedMiddleware<TContext, TExtraContext, TInput, TOutput> {\n if (Reflect.get(middleware, decoratedMiddlewareSymbol)) {\n return middleware as any\n }\n\n const concat = (\n concatMiddleware: Middleware<any, any, any, any>,\n mapInput?: MapInputMiddleware<any, any>,\n ): Middleware<any, any, any, any> => {\n const concatMiddleware_ = mapInput\n ? decorateMiddleware(concatMiddleware).mapInput(mapInput)\n : concatMiddleware\n\n return decorateMiddleware(async (input, context, meta, ...rest) => {\n const input_ = input as any\n const context_ = context as any\n const meta_ = meta as any\n\n const next: MiddlewareMeta<any>['next'] = async (options) => {\n return concatMiddleware_(input_, mergeContext(context_, options.context), meta_, ...rest)\n }\n\n const m1 = await middleware(input_, context_, {\n ...meta_,\n next,\n }, ...rest)\n\n return m1\n })\n }\n\n const mapInput = <UInput = unknown>(\n map: MapInputMiddleware<UInput, TInput>,\n ): DecoratedMiddleware<TContext, TExtraContext, UInput, TOutput> => {\n return decorateMiddleware((input, ...rest) =>\n middleware(map(input), ...rest),\n )\n }\n\n return Object.assign(middleware, {\n [decoratedMiddlewareSymbol]: true,\n concat: concat as any,\n mapInput,\n })\n}\n","import type { SchemaInput, SchemaOutput } from '@orpc/contract'\nimport type { MiddlewareMeta } from './middleware'\nimport type { Procedure } from './procedure'\nimport type { Context } from './types'\nimport { ORPCError } from '@orpc/shared/error'\nimport { mergeContext } from './utils'\n\nexport interface CreateProcedureCallerOptions<\n TProcedure extends Procedure<any, any, any, any, any>,\n TValidate extends boolean,\n> {\n procedure: TProcedure\n\n /**\n * The context used when calling the procedure.\n */\n context: TProcedure extends Procedure<infer UContext, any, any, any, any>\n ? UContext\n : never\n\n /**\n * This is helpful for logging and analytics.\n */\n path?: string[]\n\n /**\n * This flag helpful when you want bypass some logics not necessary to internal server calls.\n *\n * @default true\n */\n internal?: boolean\n\n /**\n * Indicate whether validate input and output.\n *\n * @default true\n */\n validate?: TValidate\n}\n\nexport type ProcedureCaller<\n TProcedure extends Procedure<any, any, any, any, any>,\n TValidate extends boolean,\n> = TProcedure extends Procedure<\n any,\n any,\n infer UInputSchema,\n infer UOutputSchema,\n infer UHandlerOutput\n>\n ? (\n input: TValidate extends true\n ? SchemaInput<UInputSchema>\n : SchemaOutput<UInputSchema>,\n ) => Promise<\n TValidate extends true\n ? SchemaOutput<UOutputSchema, UHandlerOutput>\n : SchemaInput<UOutputSchema, UHandlerOutput>\n >\n : never\n\nexport function createProcedureCaller<\n TProcedure extends Procedure<any, any, any, any, any>,\n TValidate extends boolean = true,\n>(\n options: CreateProcedureCallerOptions<TProcedure, TValidate>,\n): ProcedureCaller<TProcedure, TValidate> {\n const internal = options.internal ?? true\n const path = options.path ?? []\n const procedure = options.procedure\n const validate = options.validate ?? true\n\n const caller = async (input: unknown): Promise<unknown> => {\n const validInput = (() => {\n if (!validate)\n return input\n const schema = procedure.zz$p.contract.zz$cp.InputSchema\n if (!schema)\n return input\n\n try {\n return schema.parse(input)\n }\n catch (e) {\n throw new ORPCError({\n message: 'Validation input failed',\n code: 'BAD_REQUEST',\n cause: e,\n })\n }\n })()\n\n const middlewares = procedure.zz$p.middlewares ?? []\n let currentMidIndex = 0\n let currentContext: Context = options.context\n\n const next: MiddlewareMeta<unknown>['next'] = async (nextOptions) => {\n const mid = middlewares[currentMidIndex]\n currentMidIndex += 1\n currentContext = mergeContext(currentContext, nextOptions.context)\n\n if (mid) {\n return await mid(validInput, currentContext, {\n path,\n procedure,\n internal,\n next,\n output: output => ({ output, context: undefined }),\n })\n }\n else {\n return {\n output: await await procedure.zz$p.handler(validInput, currentContext, {\n path,\n procedure,\n internal,\n }),\n context: currentContext,\n }\n }\n }\n\n const output = (await next({})).output\n\n const validOutput = await (async () => {\n if (!validate)\n return output\n const schema = procedure.zz$p.contract.zz$cp.OutputSchema\n if (!schema)\n return output\n const result = await schema.safeParseAsync(output)\n if (result.error) {\n throw new ORPCError({\n message: 'Validation output failed',\n code: 'INTERNAL_SERVER_ERROR',\n cause: result.error,\n })\n }\n return result.data\n })()\n\n return validOutput\n }\n\n return caller as ProcedureCaller<TProcedure, TValidate>\n}\n","import type { Promisable } from '@orpc/shared'\nimport type { Context, MergeContext, Meta } from './types'\nimport {\n type ContractProcedure,\n DecoratedContractProcedure,\n type HTTPPath,\n isContractProcedure,\n type RouteOptions,\n type Schema,\n type SchemaInput,\n type SchemaOutput,\n} from '@orpc/contract'\nimport { OpenAPIDeserializer } from '@orpc/transformer'\nimport {\n decorateMiddleware,\n type MapInputMiddleware,\n type Middleware,\n} from './middleware'\nimport { createProcedureCaller } from './procedure-caller'\n\nexport class Procedure<\n TContext extends Context,\n TExtraContext extends Context,\n TInputSchema extends Schema,\n TOutputSchema extends Schema,\n THandlerOutput extends SchemaOutput<TOutputSchema>,\n> {\n constructor(\n public zz$p: {\n middlewares?: Middleware<any, any, any, any>[]\n contract: ContractProcedure<TInputSchema, TOutputSchema>\n handler: ProcedureHandler<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >\n },\n ) {}\n}\n\nexport type DecoratedProcedure<\n TContext extends Context,\n TExtraContext extends Context,\n TInputSchema extends Schema,\n TOutputSchema extends Schema,\n THandlerOutput extends SchemaOutput<TOutputSchema>,\n> = Procedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n> & {\n prefix: (\n prefix: HTTPPath,\n ) => DecoratedProcedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >\n\n route: (\n opts: RouteOptions,\n ) => DecoratedProcedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >\n\n use: (<\n UExtraContext extends\n | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>\n | undefined = undefined,\n >(\n middleware: Middleware<\n MergeContext<TContext, TExtraContext>,\n UExtraContext,\n SchemaOutput<TInputSchema>,\n SchemaInput<TOutputSchema, THandlerOutput>\n >,\n ) => DecoratedProcedure<\n TContext,\n MergeContext<TExtraContext, UExtraContext>,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >) & (<\n UExtraContext extends\n | Partial<MergeContext<Context, MergeContext<TContext, TExtraContext>>>\n | undefined = undefined,\n UMappedInput = unknown,\n >(\n middleware: Middleware<\n MergeContext<TContext, TExtraContext>,\n UExtraContext,\n UMappedInput,\n SchemaInput<TOutputSchema, THandlerOutput>\n >,\n mapInput: MapInputMiddleware<\n SchemaOutput<TInputSchema, THandlerOutput>,\n UMappedInput\n >,\n ) => DecoratedProcedure<\n TContext,\n MergeContext<TExtraContext, UExtraContext>,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >)\n} & (undefined extends TContext\n ? (\n input: SchemaInput<TInputSchema> | FormData,\n ) => Promise<SchemaOutput<TOutputSchema, THandlerOutput>>\n : unknown)\n\nexport interface ProcedureHandler<\n TContext extends Context,\n TExtraContext extends Context,\n TInputSchema extends Schema,\n TOutputSchema extends Schema,\n TOutput extends SchemaOutput<TOutputSchema>,\n> {\n (\n input: SchemaOutput<TInputSchema>,\n context: MergeContext<TContext, TExtraContext>,\n meta: Meta,\n ): Promisable<SchemaInput<TOutputSchema, TOutput>>\n}\n\nconst DECORATED_PROCEDURE_SYMBOL = Symbol('DECORATED_PROCEDURE')\n\nexport function decorateProcedure<\n TContext extends Context,\n TExtraContext extends Context,\n TInputSchema extends Schema,\n TOutputSchema extends Schema,\n THandlerOutput extends SchemaOutput<TOutputSchema>,\n>(\n procedure: Procedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n >,\n): DecoratedProcedure<\n TContext,\n TExtraContext,\n TInputSchema,\n TOutputSchema,\n THandlerOutput\n > {\n if (DECORATED_PROCEDURE_SYMBOL in procedure) {\n return procedure as any\n }\n\n const serverAction = async (input: unknown): Promise<SchemaOutput<TOutputSchema, THandlerOutput>> => {\n const input_ = (() => {\n if (!(input instanceof FormData))\n return input\n\n const transformer = new OpenAPIDeserializer({\n schema: procedure.zz$p.contract.zz$cp.InputSchema,\n })\n\n return transformer.deserializeAsFormData(input)\n })()\n\n const procedureCaller = createProcedureCaller({\n procedure,\n context: undefined as any,\n internal: false,\n validate: true,\n })\n\n return await procedureCaller(input_ as any)\n }\n\n return Object.assign(serverAction, {\n [DECORATED_PROCEDURE_SYMBOL]: true,\n zz$p: procedure.zz$p,\n\n prefix(prefix: HTTPPath) {\n return decorateProcedure({\n zz$p: {\n ...procedure.zz$p,\n contract: DecoratedContractProcedure.decorate(\n procedure.zz$p.contract,\n ).prefix(prefix),\n },\n })\n },\n\n route(opts: RouteOptions) {\n return decorateProcedure({\n zz$p: {\n ...procedure.zz$p,\n contract: DecoratedContractProcedure.decorate(\n procedure.zz$p.contract,\n ).route(opts),\n },\n })\n },\n\n use(\n middleware: Middleware<any, any, any, any>,\n mapInput?: MapInputMiddleware<any, any>,\n ) {\n const middleware_ = mapInput\n ? decorateMiddleware(middleware).mapInput(mapInput)\n : middleware\n\n return decorateProcedure({\n zz$p: {\n ...procedure.zz$p,\n middlewares: [middleware_, ...(procedure.zz$p.middlewares ?? [])],\n },\n })\n },\n }) as any\n}\n\nexport type WELL_DEFINED_PROCEDURE = Procedure<\n Context,\n Context,\n Schema,\n Schema,\n unknown\n>\n\nexport function isProcedure(item: unknown): item is WELL_DEFINED_PROCEDURE {\n if (item instanceof Procedure)\n return true\n\n return (\n (typeof item === 'object' || typeof item === 'function')\n && item !== null\n && 'zz$p' in item\n && typeof item.zz$p === 'object'\n && item.zz$p !== null\n && 'contract' in item.zz$p\n && isContractProcedure(item.zz$p.contract)\n && 'handler' in item.zz$p\n && typeof item.zz$p.handler === 'function'\n )\n}\n"],"mappings":"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","names":["mapInput","output"]}
package/dist/fetch.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import {
2
2
  createProcedureCaller,
3
- hook,
4
3
  isProcedure
5
- } from "./chunk-ACLC6USM.js";
4
+ } from "./chunk-26DTFWOI.js";
6
5
 
7
6
  // src/adapters/fetch.ts
8
7
  import {
@@ -18,10 +17,10 @@ import {
18
17
  } from "@orpc/shared";
19
18
  import { ORPCError } from "@orpc/shared/error";
20
19
  import {
21
- ORPCDeserializer,
22
- ORPCSerializer,
23
20
  OpenAPIDeserializer,
24
21
  OpenAPISerializer,
22
+ ORPCDeserializer,
23
+ ORPCSerializer,
25
24
  zodCoerce
26
25
  } from "@orpc/transformer";
27
26
 
@@ -551,103 +550,100 @@ function createFetchHandler(options) {
551
550
  const isORPCTransformer = requestOptions.request.headers.get(ORPC_HEADER) === ORPC_HEADER_VALUE;
552
551
  const accept = requestOptions.request.headers.get("Accept") || void 0;
553
552
  const serializer = isORPCTransformer ? new ORPCSerializer() : new OpenAPISerializer({ accept });
554
- try {
555
- return await hook(async (hooks) => {
556
- const url = new URL(requestOptions.request.url);
557
- const pathname = `/${trim(url.pathname.replace(requestOptions.prefix ?? "", ""), "/")}`;
558
- let path;
559
- let procedure;
560
- let params;
561
- if (isORPCTransformer) {
553
+ const handler = async () => {
554
+ const url = new URL(requestOptions.request.url);
555
+ const pathname = `/${trim(url.pathname.replace(requestOptions.prefix ?? "", ""), "/")}`;
556
+ let path;
557
+ let procedure;
558
+ let params;
559
+ if (isORPCTransformer) {
560
+ path = trim(pathname, "/").split("/").map(decodeURIComponent);
561
+ const val = get(options.router, path);
562
+ if (isProcedure(val)) {
563
+ procedure = val;
564
+ }
565
+ } else {
566
+ const customMethod = requestOptions.request.method === "POST" ? url.searchParams.get("method")?.toUpperCase() : void 0;
567
+ const method = customMethod || requestOptions.request.method;
568
+ const [matches, params_] = routing.match(method, pathname);
569
+ const [match] = matches.sort((a, b) => {
570
+ return Object.keys(a[1]).length - Object.keys(b[1]).length;
571
+ });
572
+ if (match) {
573
+ path = match[0][0];
574
+ procedure = match[0][1];
575
+ if (params_) {
576
+ params = mapValues(
577
+ match[1],
578
+ (v) => params_[v]
579
+ );
580
+ } else {
581
+ params = match[1];
582
+ }
583
+ }
584
+ if (!path || !procedure) {
562
585
  path = trim(pathname, "/").split("/").map(decodeURIComponent);
563
586
  const val = get(options.router, path);
564
587
  if (isProcedure(val)) {
565
588
  procedure = val;
566
589
  }
567
- } else {
568
- const customMethod = requestOptions.request.method === "POST" ? url.searchParams.get("method")?.toUpperCase() : void 0;
569
- const method = customMethod || requestOptions.request.method;
570
- const [matches, params_] = routing.match(method, pathname);
571
- const [match] = matches.sort((a, b) => {
572
- return Object.keys(a[1]).length - Object.keys(b[1]).length;
590
+ }
591
+ }
592
+ if (!path || !procedure) {
593
+ throw new ORPCError({ code: "NOT_FOUND", message: "Not found" });
594
+ }
595
+ const deserializer = isORPCTransformer ? new ORPCDeserializer() : new OpenAPIDeserializer({
596
+ schema: procedure.zz$p.contract.zz$cp.InputSchema
597
+ });
598
+ const input_ = await (async () => {
599
+ try {
600
+ return await deserializer.deserialize(requestOptions.request);
601
+ } catch (e) {
602
+ throw new ORPCError({
603
+ code: "BAD_REQUEST",
604
+ message: "Cannot parse request. Please check the request body and Content-Type header.",
605
+ cause: e
573
606
  });
574
- if (match) {
575
- path = match[0][0];
576
- procedure = match[0][1];
577
- if (params_) {
578
- params = mapValues(
579
- match[1],
580
- (v) => params_[v]
581
- );
582
- } else {
583
- params = match[1];
584
- }
585
- }
586
- if (!path || !procedure) {
587
- path = trim(pathname, "/").split("/").map(decodeURIComponent);
588
- const val = get(options.router, path);
589
- if (isProcedure(val)) {
590
- procedure = val;
591
- }
592
- }
593
607
  }
594
- if (!path || !procedure) {
595
- throw new ORPCError({ code: "NOT_FOUND", message: "Not found" });
608
+ })();
609
+ const input = (() => {
610
+ if (!params || Object.keys(params).length === 0) {
611
+ return input_;
596
612
  }
597
- const meta = {
598
- ...hooks,
599
- procedure,
600
- path,
601
- internal: false
602
- };
603
- await options.hooks?.(requestOptions.context, meta);
604
- const deserializer = isORPCTransformer ? new ORPCDeserializer() : new OpenAPIDeserializer({
605
- schema: procedure.zz$p.contract.zz$cp.InputSchema
606
- });
607
- const input_ = await (async () => {
608
- try {
609
- return await deserializer.deserialize(requestOptions.request);
610
- } catch (e) {
611
- throw new ORPCError({
612
- code: "BAD_REQUEST",
613
- message: "Cannot parse request. Please check the request body and Content-Type header.",
614
- cause: e
615
- });
616
- }
617
- })();
618
- const input = (() => {
619
- if (!params || Object.keys(params).length === 0) {
620
- return input_;
621
- }
622
- const coercedParams = procedure.zz$p.contract.zz$cp.InputSchema ? zodCoerce(
623
- procedure.zz$p.contract.zz$cp.InputSchema,
624
- { ...params },
625
- {
626
- bracketNotation: true
627
- }
628
- ) : params;
629
- if (!isPlainObject(input_)) {
630
- return coercedParams;
613
+ const coercedParams = procedure.zz$p.contract.zz$cp.InputSchema ? zodCoerce(
614
+ procedure.zz$p.contract.zz$cp.InputSchema,
615
+ { ...params },
616
+ {
617
+ bracketNotation: true
631
618
  }
632
- return {
633
- ...coercedParams,
634
- ...input_
635
- };
636
- })();
637
- const caller = createProcedureCaller({
638
- context: requestOptions.context,
639
- internal: false,
640
- validate: true,
641
- procedure,
642
- path
643
- });
644
- const output = await caller(input);
645
- const { body, headers } = serializer.serialize(output);
646
- return new Response(body, {
647
- status: 200,
648
- headers
649
- });
619
+ ) : params;
620
+ if (!isPlainObject(input_)) {
621
+ return coercedParams;
622
+ }
623
+ return {
624
+ ...coercedParams,
625
+ ...input_
626
+ };
627
+ })();
628
+ const caller = createProcedureCaller({
629
+ context: requestOptions.context,
630
+ internal: false,
631
+ validate: true,
632
+ procedure,
633
+ path
634
+ });
635
+ const output = await caller(input);
636
+ const { body, headers } = serializer.serialize(output);
637
+ return new Response(body, {
638
+ status: 200,
639
+ headers
650
640
  });
641
+ };
642
+ try {
643
+ return await options.hooks?.(requestOptions.context, {
644
+ next: handler,
645
+ response: (response) => response
646
+ }) ?? await handler();
651
647
  } catch (e) {
652
648
  const error = toORPCError(e);
653
649
  try {