@orpc/server 0.1.0 → 0.1.2

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 (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 {