@veloxts/router 0.2.0 → 0.2.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.
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @veloxts/router - Procedure API with hybrid tRPC/REST routing
3
+ *
4
+ * Core routing abstraction that enables type-safe API endpoints with
5
+ * automatic tRPC and REST adapter generation from procedure definitions.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { procedure, defineProcedures } from '@veloxts/router';
10
+ * import { z } from '@veloxts/validation';
11
+ *
12
+ * const UserSchema = z.object({
13
+ * id: z.string().uuid(),
14
+ * name: z.string(),
15
+ * email: z.string().email(),
16
+ * });
17
+ *
18
+ * export const userProcedures = defineProcedures('users', {
19
+ * getUser: procedure()
20
+ * .input(z.object({ id: z.string().uuid() }))
21
+ * .output(UserSchema)
22
+ * .query(async ({ input, ctx }) => {
23
+ * // input is typed as { id: string }
24
+ * // ctx is typed as BaseContext
25
+ * // return type must match UserSchema
26
+ * return ctx.db.user.findUnique({ where: { id: input.id } });
27
+ * }),
28
+ *
29
+ * createUser: procedure()
30
+ * .input(z.object({ name: z.string(), email: z.string().email() }))
31
+ * .output(UserSchema)
32
+ * .mutation(async ({ input, ctx }) => {
33
+ * return ctx.db.user.create({ data: input });
34
+ * }),
35
+ * });
36
+ * ```
37
+ *
38
+ * @module @veloxts/router
39
+ */
40
+ export declare const ROUTER_VERSION: "0.1.0";
41
+ export type { CompiledProcedure, ContextExtensions, ContextFactory, ExtendedContext, HttpMethod, InferProcedureContext, InferProcedureInput, InferProcedureOutput, InferProcedureTypes, MiddlewareArgs, MiddlewareFunction, MiddlewareNext, MiddlewareResult, ProcedureCollection, ProcedureHandler, ProcedureHandlerArgs, ProcedureRecord, ProcedureType, RestRouteOverride, } from './types.js';
42
+ export { PROCEDURE_METHOD_MAP, } from './types.js';
43
+ export { defineProcedures, executeProcedure, isCompiledProcedure, isProcedureCollection, procedure, } from './procedure/builder.js';
44
+ export type { BuilderRuntimeState, InferProcedures, InferSchemaOutput, ProcedureBuilder, ProcedureBuilderState, ProcedureDefinitions, ValidSchema, } from './procedure/types.js';
45
+ export type { RestAdapterOptions, RestMapping, RestRoute } from './rest/index.js';
46
+ export { buildRestPath, createRoutesRegistrar, followsNamingConvention, generateRestRoutes, getRouteSummary, inferResourceName, parseNamingConvention, registerRestRoutes, } from './rest/index.js';
47
+ export type { AnyRouter, InferAppRouter, TRPCInstance, TRPCPluginOptions, } from './trpc/index.js';
48
+ export { buildTRPCRouter, createAppRouter, createTRPC, createTRPCContextFactory, registerTRPCPlugin, veloxErrorToTRPCError, } from './trpc/index.js';
49
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,eAAO,MAAM,cAAc,EAAG,OAAgB,CAAC;AAO/C,YAAY,EAEV,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EAEnB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAEhB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAEL,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAEL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,GACV,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAEV,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAS9B,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAMzB,YAAY,EAEV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,eAAe,EACf,eAAe,EACf,UAAU,EACV,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @veloxts/router - Procedure API with hybrid tRPC/REST routing
3
+ *
4
+ * Core routing abstraction that enables type-safe API endpoints with
5
+ * automatic tRPC and REST adapter generation from procedure definitions.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { procedure, defineProcedures } from '@veloxts/router';
10
+ * import { z } from '@veloxts/validation';
11
+ *
12
+ * const UserSchema = z.object({
13
+ * id: z.string().uuid(),
14
+ * name: z.string(),
15
+ * email: z.string().email(),
16
+ * });
17
+ *
18
+ * export const userProcedures = defineProcedures('users', {
19
+ * getUser: procedure()
20
+ * .input(z.object({ id: z.string().uuid() }))
21
+ * .output(UserSchema)
22
+ * .query(async ({ input, ctx }) => {
23
+ * // input is typed as { id: string }
24
+ * // ctx is typed as BaseContext
25
+ * // return type must match UserSchema
26
+ * return ctx.db.user.findUnique({ where: { id: input.id } });
27
+ * }),
28
+ *
29
+ * createUser: procedure()
30
+ * .input(z.object({ name: z.string(), email: z.string().email() }))
31
+ * .output(UserSchema)
32
+ * .mutation(async ({ input, ctx }) => {
33
+ * return ctx.db.user.create({ data: input });
34
+ * }),
35
+ * });
36
+ * ```
37
+ *
38
+ * @module @veloxts/router
39
+ */
40
+ // Version constant
41
+ export const ROUTER_VERSION = '0.1.0';
42
+ export {
43
+ // Constants
44
+ PROCEDURE_METHOD_MAP, } from './types.js';
45
+ // ============================================================================
46
+ // Procedure Builder
47
+ // ============================================================================
48
+ export {
49
+ // Builder functions
50
+ defineProcedures, executeProcedure, isCompiledProcedure, isProcedureCollection, procedure, } from './procedure/builder.js';
51
+ export { buildRestPath, createRoutesRegistrar, followsNamingConvention, generateRestRoutes, getRouteSummary, inferResourceName, parseNamingConvention, registerRestRoutes, } from './rest/index.js';
52
+ export {
53
+ // tRPC utilities
54
+ buildTRPCRouter, createAppRouter, createTRPC, createTRPCContextFactory, registerTRPCPlugin, veloxErrorToTRPCError, } from './trpc/index.js';
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,mBAAmB;AACnB,MAAM,CAAC,MAAM,cAAc,GAAG,OAAgB,CAAC;AA+B/C,OAAO;AACL,YAAY;AACZ,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E,OAAO;AACL,oBAAoB;AACpB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,GACV,MAAM,wBAAwB,CAAC;AAoBhC,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAazB,OAAO;AACL,iBAAiB;AACjB,eAAe,EACf,eAAe,EACf,UAAU,EACV,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Procedure builder implementation
3
+ *
4
+ * Implements the fluent builder pattern for defining type-safe procedures.
5
+ * Uses a functional approach where each method returns a new builder instance
6
+ * with accumulated state, enabling immutable building with proper type inference.
7
+ *
8
+ * @module procedure/builder
9
+ */
10
+ import type { BaseContext } from '@veloxts/core';
11
+ import type { CompiledProcedure, ProcedureCollection } from '../types.js';
12
+ import type { InferProcedures, ProcedureBuilder, ProcedureDefinitions } from './types.js';
13
+ /**
14
+ * Creates a new procedure builder instance
15
+ *
16
+ * This is the primary entry point for defining procedures. The builder uses
17
+ * TypeScript's generic inference to track types through the fluent chain.
18
+ *
19
+ * @returns New procedure builder with void input, unknown output, and BaseContext
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const getUser = procedure()
24
+ * .input(z.object({ id: z.string().uuid() }))
25
+ * .output(UserSchema)
26
+ * .query(async ({ input, ctx }) => {
27
+ * // input is { id: string }
28
+ * // ctx is BaseContext
29
+ * // return type must match UserSchema
30
+ * return ctx.db.user.findUnique({ where: { id: input.id } });
31
+ * });
32
+ * ```
33
+ */
34
+ export declare function procedure(): ProcedureBuilder<unknown, unknown, BaseContext>;
35
+ /**
36
+ * Defines a collection of procedures under a namespace
37
+ *
38
+ * Groups related procedures together for registration with routers.
39
+ * The namespace determines the base path for REST routes.
40
+ *
41
+ * @template TProcedures - The record of named procedures
42
+ * @param namespace - Resource namespace (e.g., 'users', 'posts')
43
+ * @param procedures - Object containing named procedures
44
+ * @returns Procedure collection with preserved types
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * export const userProcedures = defineProcedures('users', {
49
+ * getUser: procedure()
50
+ * .input(z.object({ id: z.string().uuid() }))
51
+ * .query(async ({ input, ctx }) => {
52
+ * return ctx.db.user.findUnique({ where: { id: input.id } });
53
+ * }),
54
+ *
55
+ * createUser: procedure()
56
+ * .input(CreateUserSchema)
57
+ * .mutation(async ({ input, ctx }) => {
58
+ * return ctx.db.user.create({ data: input });
59
+ * }),
60
+ * });
61
+ *
62
+ * // Types are fully preserved:
63
+ * // userProcedures.procedures.getUser.inputSchema -> { id: string }
64
+ * // userProcedures.procedures.createUser -> mutation type
65
+ * ```
66
+ */
67
+ export declare function defineProcedures<TProcedures extends ProcedureDefinitions>(namespace: string, procedures: TProcedures): ProcedureCollection<InferProcedures<TProcedures>>;
68
+ /**
69
+ * Executes a compiled procedure with the given input and context
70
+ *
71
+ * This function handles:
72
+ * 1. Input validation (if schema provided)
73
+ * 2. Middleware chain execution (using pre-compiled executor when available)
74
+ * 3. Handler execution
75
+ * 4. Output validation (if schema provided)
76
+ *
77
+ * PERFORMANCE: Uses pre-compiled middleware executor when available,
78
+ * eliminating the overhead of building the middleware chain on every request.
79
+ *
80
+ * @template TInput - The input type
81
+ * @template TOutput - The output type
82
+ * @template TContext - The context type
83
+ * @param procedure - The compiled procedure to execute
84
+ * @param rawInput - Raw input data to validate and pass to handler
85
+ * @param ctx - Request context
86
+ * @returns Promise resolving to the handler output
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const result = await executeProcedure(
91
+ * userProcedures.procedures.getUser,
92
+ * { id: '123' },
93
+ * context
94
+ * );
95
+ * ```
96
+ */
97
+ export declare function executeProcedure<TInput, TOutput, TContext extends BaseContext>(procedure: CompiledProcedure<TInput, TOutput, TContext>, rawInput: unknown, ctx: TContext): Promise<TOutput>;
98
+ /**
99
+ * Type guard to check if a value is a compiled procedure
100
+ */
101
+ export declare function isCompiledProcedure(value: unknown): value is CompiledProcedure;
102
+ /**
103
+ * Type guard to check if a value is a procedure collection
104
+ */
105
+ export declare function isProcedureCollection(value: unknown): value is ProcedureCollection;
106
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/procedure/builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EACV,iBAAiB,EAEjB,mBAAmB,EAGpB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAEV,eAAe,EAEf,gBAAgB,EAChB,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAMpB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,SAAS,IAAI,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,CAO3E;AA8LD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,SAAS,oBAAoB,EACvE,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,WAAW,GACtB,mBAAmB,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAKnD;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,SAAS,WAAW,EAClF,SAAS,EAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EACvD,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,QAAQ,GACZ,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAkDD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAY9E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAYlF"}
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Procedure builder implementation
3
+ *
4
+ * Implements the fluent builder pattern for defining type-safe procedures.
5
+ * Uses a functional approach where each method returns a new builder instance
6
+ * with accumulated state, enabling immutable building with proper type inference.
7
+ *
8
+ * @module procedure/builder
9
+ */
10
+ // ============================================================================
11
+ // Builder Factory
12
+ // ============================================================================
13
+ /**
14
+ * Creates a new procedure builder instance
15
+ *
16
+ * This is the primary entry point for defining procedures. The builder uses
17
+ * TypeScript's generic inference to track types through the fluent chain.
18
+ *
19
+ * @returns New procedure builder with void input, unknown output, and BaseContext
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const getUser = procedure()
24
+ * .input(z.object({ id: z.string().uuid() }))
25
+ * .output(UserSchema)
26
+ * .query(async ({ input, ctx }) => {
27
+ * // input is { id: string }
28
+ * // ctx is BaseContext
29
+ * // return type must match UserSchema
30
+ * return ctx.db.user.findUnique({ where: { id: input.id } });
31
+ * });
32
+ * ```
33
+ */
34
+ export function procedure() {
35
+ return createBuilder({
36
+ inputSchema: undefined,
37
+ outputSchema: undefined,
38
+ middlewares: [],
39
+ restOverride: undefined,
40
+ });
41
+ }
42
+ // ============================================================================
43
+ // Internal Builder Implementation
44
+ // ============================================================================
45
+ /**
46
+ * Creates a builder instance with the given runtime state
47
+ *
48
+ * This internal function constructs the builder object with all methods bound
49
+ * to the current state. Each method returns a new builder with updated state.
50
+ *
51
+ * @internal
52
+ */
53
+ function createBuilder(state) {
54
+ return {
55
+ /**
56
+ * Sets the input validation schema
57
+ */
58
+ input(schema) {
59
+ // Return new builder with updated input schema
60
+ // The type parameter extracts the schema's output type
61
+ return createBuilder({
62
+ ...state,
63
+ inputSchema: schema,
64
+ });
65
+ },
66
+ /**
67
+ * Sets the output validation schema
68
+ */
69
+ output(schema) {
70
+ // Return new builder with updated output schema
71
+ return createBuilder({
72
+ ...state,
73
+ outputSchema: schema,
74
+ });
75
+ },
76
+ /**
77
+ * Adds middleware to the chain
78
+ */
79
+ use(middleware) {
80
+ // Add middleware to the chain
81
+ // Cast is safe because we're building up the chain incrementally
82
+ const typedMiddleware = middleware;
83
+ return createBuilder({
84
+ ...state,
85
+ middlewares: [...state.middlewares, typedMiddleware],
86
+ });
87
+ },
88
+ /**
89
+ * Sets REST route override
90
+ */
91
+ rest(config) {
92
+ return createBuilder({
93
+ ...state,
94
+ restOverride: config,
95
+ });
96
+ },
97
+ /**
98
+ * Finalizes as a query procedure
99
+ */
100
+ query(handler) {
101
+ return compileProcedure('query', handler, state);
102
+ },
103
+ /**
104
+ * Finalizes as a mutation procedure
105
+ */
106
+ mutation(handler) {
107
+ return compileProcedure('mutation', handler, state);
108
+ },
109
+ };
110
+ }
111
+ /**
112
+ * Compiles a procedure from the builder state
113
+ *
114
+ * Creates the final CompiledProcedure object with all metadata and handlers.
115
+ * PERFORMANCE: Pre-compiles the middleware chain during procedure definition
116
+ * instead of building it on every request.
117
+ *
118
+ * @internal
119
+ */
120
+ function compileProcedure(type, handler, state) {
121
+ const typedMiddlewares = state.middlewares;
122
+ // Pre-compile the middleware chain executor if middlewares exist
123
+ // This avoids rebuilding the chain on every request
124
+ const precompiledExecutor = typedMiddlewares.length > 0
125
+ ? createPrecompiledMiddlewareExecutor(typedMiddlewares, handler)
126
+ : undefined;
127
+ // Create the final procedure object
128
+ const procedure = {
129
+ type,
130
+ handler,
131
+ inputSchema: state.inputSchema,
132
+ outputSchema: state.outputSchema,
133
+ middlewares: typedMiddlewares,
134
+ restOverride: state.restOverride,
135
+ // Store pre-compiled executor for performance
136
+ _precompiledExecutor: precompiledExecutor,
137
+ };
138
+ return procedure;
139
+ }
140
+ /**
141
+ * Creates a pre-compiled middleware chain executor
142
+ *
143
+ * PERFORMANCE: This function builds the middleware chain once during procedure
144
+ * compilation, creating a single reusable function that executes the entire chain.
145
+ * This eliminates the need to rebuild closures on every request.
146
+ *
147
+ * @internal
148
+ */
149
+ function createPrecompiledMiddlewareExecutor(middlewares, handler) {
150
+ // Pre-build the chain executor once
151
+ return async (input, ctx) => {
152
+ // Create mutable context copy for middleware extensions
153
+ const mutableCtx = ctx;
154
+ // Build the handler wrapper
155
+ const executeHandler = async () => {
156
+ const output = await handler({ input, ctx: mutableCtx });
157
+ return { output };
158
+ };
159
+ // Build chain from end to start (only done once per request, not per middleware)
160
+ let next = executeHandler;
161
+ for (let i = middlewares.length - 1; i >= 0; i--) {
162
+ const middleware = middlewares[i];
163
+ const currentNext = next;
164
+ next = async () => {
165
+ return middleware({
166
+ input,
167
+ ctx: mutableCtx,
168
+ next: async (opts) => {
169
+ if (opts?.ctx) {
170
+ Object.assign(mutableCtx, opts.ctx);
171
+ }
172
+ return currentNext();
173
+ },
174
+ });
175
+ };
176
+ }
177
+ const result = await next();
178
+ return result.output;
179
+ };
180
+ }
181
+ // ============================================================================
182
+ // Procedure Collection Factory
183
+ // ============================================================================
184
+ /**
185
+ * Defines a collection of procedures under a namespace
186
+ *
187
+ * Groups related procedures together for registration with routers.
188
+ * The namespace determines the base path for REST routes.
189
+ *
190
+ * @template TProcedures - The record of named procedures
191
+ * @param namespace - Resource namespace (e.g., 'users', 'posts')
192
+ * @param procedures - Object containing named procedures
193
+ * @returns Procedure collection with preserved types
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * export const userProcedures = defineProcedures('users', {
198
+ * getUser: procedure()
199
+ * .input(z.object({ id: z.string().uuid() }))
200
+ * .query(async ({ input, ctx }) => {
201
+ * return ctx.db.user.findUnique({ where: { id: input.id } });
202
+ * }),
203
+ *
204
+ * createUser: procedure()
205
+ * .input(CreateUserSchema)
206
+ * .mutation(async ({ input, ctx }) => {
207
+ * return ctx.db.user.create({ data: input });
208
+ * }),
209
+ * });
210
+ *
211
+ * // Types are fully preserved:
212
+ * // userProcedures.procedures.getUser.inputSchema -> { id: string }
213
+ * // userProcedures.procedures.createUser -> mutation type
214
+ * ```
215
+ */
216
+ export function defineProcedures(namespace, procedures) {
217
+ return {
218
+ namespace,
219
+ procedures: procedures,
220
+ };
221
+ }
222
+ // ============================================================================
223
+ // Procedure Execution
224
+ // ============================================================================
225
+ /**
226
+ * Executes a compiled procedure with the given input and context
227
+ *
228
+ * This function handles:
229
+ * 1. Input validation (if schema provided)
230
+ * 2. Middleware chain execution (using pre-compiled executor when available)
231
+ * 3. Handler execution
232
+ * 4. Output validation (if schema provided)
233
+ *
234
+ * PERFORMANCE: Uses pre-compiled middleware executor when available,
235
+ * eliminating the overhead of building the middleware chain on every request.
236
+ *
237
+ * @template TInput - The input type
238
+ * @template TOutput - The output type
239
+ * @template TContext - The context type
240
+ * @param procedure - The compiled procedure to execute
241
+ * @param rawInput - Raw input data to validate and pass to handler
242
+ * @param ctx - Request context
243
+ * @returns Promise resolving to the handler output
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * const result = await executeProcedure(
248
+ * userProcedures.procedures.getUser,
249
+ * { id: '123' },
250
+ * context
251
+ * );
252
+ * ```
253
+ */
254
+ export async function executeProcedure(procedure, rawInput, ctx) {
255
+ // Step 1: Validate input if schema provided
256
+ const input = procedure.inputSchema
257
+ ? procedure.inputSchema.parse(rawInput)
258
+ : rawInput;
259
+ // Step 2: Execute handler (with or without middleware)
260
+ let result;
261
+ if (procedure._precompiledExecutor) {
262
+ // PERFORMANCE: Use pre-compiled middleware chain executor
263
+ result = await procedure._precompiledExecutor(input, ctx);
264
+ }
265
+ else if (procedure.middlewares.length === 0) {
266
+ // No middleware - execute handler directly
267
+ result = await procedure.handler({ input, ctx });
268
+ }
269
+ else {
270
+ // Fallback: Build middleware chain dynamically (should not normally happen)
271
+ result = await executeMiddlewareChainFallback(procedure.middlewares, input, ctx, async () => procedure.handler({ input, ctx }));
272
+ }
273
+ // Step 3: Validate output if schema provided
274
+ if (procedure.outputSchema) {
275
+ return procedure.outputSchema.parse(result);
276
+ }
277
+ return result;
278
+ }
279
+ /**
280
+ * Fallback middleware chain executor for edge cases
281
+ *
282
+ * This function is only used when _precompiledExecutor is not available,
283
+ * which should be rare in normal operation.
284
+ *
285
+ * @internal
286
+ */
287
+ async function executeMiddlewareChainFallback(middlewares, input, ctx, handler) {
288
+ // Build the chain from the end (handler) back to the start
289
+ let next = async () => {
290
+ const output = await handler();
291
+ return { output };
292
+ };
293
+ // Wrap each middleware from last to first
294
+ for (let i = middlewares.length - 1; i >= 0; i--) {
295
+ const middleware = middlewares[i];
296
+ const currentNext = next;
297
+ next = async () => {
298
+ return middleware({
299
+ input,
300
+ ctx,
301
+ next: async (opts) => {
302
+ // Allow middleware to extend context
303
+ if (opts?.ctx) {
304
+ Object.assign(ctx, opts.ctx);
305
+ }
306
+ return currentNext();
307
+ },
308
+ });
309
+ };
310
+ }
311
+ const result = await next();
312
+ return result.output;
313
+ }
314
+ // ============================================================================
315
+ // Type Utilities
316
+ // ============================================================================
317
+ /**
318
+ * Type guard to check if a value is a compiled procedure
319
+ */
320
+ export function isCompiledProcedure(value) {
321
+ if (typeof value !== 'object' || value === null) {
322
+ return false;
323
+ }
324
+ const obj = value;
325
+ return ((obj.type === 'query' || obj.type === 'mutation') &&
326
+ typeof obj.handler === 'function' &&
327
+ Array.isArray(obj.middlewares));
328
+ }
329
+ /**
330
+ * Type guard to check if a value is a procedure collection
331
+ */
332
+ export function isProcedureCollection(value) {
333
+ if (typeof value !== 'object' || value === null) {
334
+ return false;
335
+ }
336
+ const obj = value;
337
+ return (typeof obj.namespace === 'string' &&
338
+ typeof obj.procedures === 'object' &&
339
+ obj.procedures !== null);
340
+ }
341
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/procedure/builder.ts"],"names":[],"mappings":"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"}