@veloxts/router 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 VeloxTS Framework Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,647 @@
1
+ # @veloxts/router
2
+
3
+ Procedure-based routing with hybrid tRPC and REST adapters for the VeloxTS framework.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @veloxts/router @veloxts/validation
9
+ # or
10
+ pnpm add @veloxts/router @veloxts/validation
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { procedure, defineProcedures } from '@veloxts/router';
17
+ import { z } from '@veloxts/validation';
18
+
19
+ // Define procedures
20
+ export const userProcedures = defineProcedures('users', {
21
+ // GET /users/:id
22
+ getUser: procedure()
23
+ .input(z.object({ id: z.string().uuid() }))
24
+ .output(UserSchema)
25
+ .query(async ({ input, ctx }) => {
26
+ return ctx.db.user.findUnique({ where: { id: input.id } });
27
+ }),
28
+
29
+ // POST /users
30
+ createUser: procedure()
31
+ .input(CreateUserSchema)
32
+ .output(UserSchema)
33
+ .mutation(async ({ input, ctx }) => {
34
+ return ctx.db.user.create({ data: input });
35
+ }),
36
+ });
37
+ ```
38
+
39
+ ## Core Concepts
40
+
41
+ ### Procedures
42
+
43
+ A **procedure** is the fundamental abstraction in VeloxTS. It defines:
44
+
45
+ 1. **Input schema** - What data the endpoint expects (validated with Zod)
46
+ 2. **Output schema** - What data the endpoint returns (validated with Zod)
47
+ 3. **Handler** - The business logic (query for reads, mutation for writes)
48
+ 4. **Middleware** - Optional request processing (auth, logging, etc.)
49
+
50
+ Procedures are type-safe from backend to frontend with zero code generation.
51
+
52
+ ### Procedure Builder API
53
+
54
+ The fluent builder pattern enables composable, type-safe endpoint definitions:
55
+
56
+ ```typescript
57
+ procedure()
58
+ .input(schema) // Define input validation
59
+ .output(schema) // Define output validation
60
+ .use(middleware) // Add middleware (optional)
61
+ .rest(config) // Override REST mapping (optional)
62
+ .query(handler) // Define read handler (GET)
63
+ // OR
64
+ .mutation(handler) // Define write handler (POST/PUT/DELETE)
65
+ ```
66
+
67
+ ## Defining Procedures
68
+
69
+ ### Query Procedures (Read Operations)
70
+
71
+ Use `.query()` for operations that read data:
72
+
73
+ ```typescript
74
+ const userProcedures = defineProcedures('users', {
75
+ // Get single user
76
+ getUser: procedure()
77
+ .input(z.object({ id: z.string().uuid() }))
78
+ .output(UserSchema)
79
+ .query(async ({ input, ctx }) => {
80
+ const user = await ctx.db.user.findUnique({
81
+ where: { id: input.id },
82
+ });
83
+
84
+ if (!user) {
85
+ throw new NotFoundError('User', input.id);
86
+ }
87
+
88
+ return user;
89
+ }),
90
+
91
+ // List users with pagination
92
+ listUsers: procedure()
93
+ .input(paginationInputSchema.optional())
94
+ .output(z.object({
95
+ data: z.array(UserSchema),
96
+ meta: z.object({
97
+ page: z.number(),
98
+ limit: z.number(),
99
+ total: z.number(),
100
+ }),
101
+ }))
102
+ .query(async ({ input, ctx }) => {
103
+ const page = input?.page ?? 1;
104
+ const limit = input?.limit ?? 10;
105
+ const skip = (page - 1) * limit;
106
+
107
+ const [data, total] = await Promise.all([
108
+ ctx.db.user.findMany({ skip, take: limit }),
109
+ ctx.db.user.count(),
110
+ ]);
111
+
112
+ return { data, meta: { page, limit, total } };
113
+ }),
114
+ });
115
+ ```
116
+
117
+ ### Mutation Procedures (Write Operations)
118
+
119
+ Use `.mutation()` for operations that modify data:
120
+
121
+ ```typescript
122
+ const userProcedures = defineProcedures('users', {
123
+ // Create user
124
+ createUser: procedure()
125
+ .input(z.object({
126
+ name: z.string().min(1),
127
+ email: z.string().email(),
128
+ }))
129
+ .output(UserSchema)
130
+ .mutation(async ({ input, ctx }) => {
131
+ return ctx.db.user.create({ data: input });
132
+ }),
133
+
134
+ // Update user (v1.1+ - PUT endpoint)
135
+ updateUser: procedure()
136
+ .input(z.object({
137
+ id: z.string().uuid(),
138
+ name: z.string().min(1).optional(),
139
+ email: z.string().email().optional(),
140
+ }))
141
+ .output(UserSchema)
142
+ .mutation(async ({ input, ctx }) => {
143
+ const { id, ...data } = input;
144
+ return ctx.db.user.update({
145
+ where: { id },
146
+ data,
147
+ });
148
+ }),
149
+ });
150
+ ```
151
+
152
+ ## REST Endpoint Generation
153
+
154
+ VeloxTS automatically generates REST endpoints from procedure names using **naming conventions**:
155
+
156
+ ### MVP (v0.1.0) - GET and POST
157
+
158
+ | Procedure Name | HTTP Method | REST Path | Notes |
159
+ |---------------|-------------|-----------|-------|
160
+ | `getUser` | GET | `/users/:id` | Single resource |
161
+ | `listUsers` | GET | `/users` | Collection |
162
+ | `createUser` | POST | `/users` | Create resource |
163
+
164
+ ### v1.1+ - Full REST Support
165
+
166
+ | Procedure Name | HTTP Method | REST Path |
167
+ |---------------|-------------|-----------|
168
+ | `updateUser` | PUT | `/users/:id` |
169
+ | `patchUser` | PATCH | `/users/:id` |
170
+ | `deleteUser` | DELETE | `/users/:id` |
171
+
172
+ ### Custom REST Paths
173
+
174
+ Override naming conventions when needed:
175
+
176
+ ```typescript
177
+ const userProcedures = defineProcedures('users', {
178
+ // Custom path for search endpoint
179
+ searchUsers: procedure()
180
+ .rest({ method: 'GET', path: '/users/search' })
181
+ .input(z.object({ q: z.string() }))
182
+ .output(z.array(UserSchema))
183
+ .query(async ({ input, ctx }) => {
184
+ return ctx.db.user.findMany({
185
+ where: {
186
+ OR: [
187
+ { name: { contains: input.q } },
188
+ { email: { contains: input.q } },
189
+ ],
190
+ },
191
+ });
192
+ }),
193
+
194
+ // Custom path for password reset
195
+ resetPassword: procedure()
196
+ .rest({ method: 'POST', path: '/auth/password-reset' })
197
+ .input(z.object({ email: z.string().email() }))
198
+ .output(z.object({ success: z.boolean() }))
199
+ .mutation(async ({ input, ctx }) => {
200
+ // Send password reset email
201
+ return { success: true };
202
+ }),
203
+ });
204
+ ```
205
+
206
+ ## Registering Routes
207
+
208
+ ### REST Adapter
209
+
210
+ Register REST routes with your VeloxTS app:
211
+
212
+ ```typescript
213
+ import { createVeloxApp } from '@veloxts/core';
214
+ import { registerRestRoutes } from '@veloxts/router';
215
+ import { userProcedures } from './procedures/users';
216
+
217
+ const app = await createVeloxApp({ port: 3000 });
218
+
219
+ // Register REST routes
220
+ await registerRestRoutes(app.server, {
221
+ prefix: '/api',
222
+ procedures: {
223
+ users: userProcedures,
224
+ },
225
+ });
226
+
227
+ await app.start();
228
+ ```
229
+
230
+ This generates the following endpoints:
231
+
232
+ ```
233
+ GET /api/users/:id (getUser)
234
+ GET /api/users (listUsers)
235
+ POST /api/users (createUser)
236
+ GET /api/users/search (searchUsers)
237
+ ```
238
+
239
+ ### tRPC Adapter
240
+
241
+ For type-safe internal API calls from your frontend:
242
+
243
+ ```typescript
244
+ import { createAppRouter, registerTRPCPlugin } from '@veloxts/router';
245
+ import { userProcedures, postProcedures } from './procedures';
246
+
247
+ // Create tRPC router
248
+ const appRouter = createAppRouter({
249
+ users: userProcedures,
250
+ posts: postProcedures,
251
+ });
252
+
253
+ // Register tRPC plugin
254
+ await registerTRPCPlugin(app.server, {
255
+ router: appRouter,
256
+ prefix: '/trpc',
257
+ });
258
+
259
+ // Export type for frontend
260
+ export type AppRouter = typeof appRouter;
261
+ ```
262
+
263
+ Frontend usage:
264
+
265
+ ```typescript
266
+ import { createClient } from '@veloxts/client';
267
+ import type { AppRouter } from '../server';
268
+
269
+ const api = createClient<AppRouter>({ baseUrl: '/api' });
270
+
271
+ // Fully typed calls
272
+ const user = await api.users.getUser({ id: '123' });
273
+ // ^? User (inferred from UserSchema)
274
+ ```
275
+
276
+ ## Middleware
277
+
278
+ Add cross-cutting concerns with middleware:
279
+
280
+ ```typescript
281
+ const loggerMiddleware: MiddlewareFunction = async ({ ctx, next }) => {
282
+ const start = Date.now();
283
+ console.log(`[${ctx.request.method}] ${ctx.request.url}`);
284
+
285
+ const result = await next();
286
+
287
+ const duration = Date.now() - start;
288
+ console.log(`[${ctx.request.method}] ${ctx.request.url} - ${duration}ms`);
289
+
290
+ return result;
291
+ };
292
+
293
+ const userProcedures = defineProcedures('users', {
294
+ getUser: procedure()
295
+ .use(loggerMiddleware)
296
+ .input(z.object({ id: z.string().uuid() }))
297
+ .output(UserSchema)
298
+ .query(async ({ input, ctx }) => {
299
+ return ctx.db.user.findUnique({ where: { id: input.id } });
300
+ }),
301
+ });
302
+ ```
303
+
304
+ ## Type Inference
305
+
306
+ VeloxTS automatically infers types throughout the procedure chain:
307
+
308
+ ```typescript
309
+ const userProcedures = defineProcedures('users', {
310
+ getUser: procedure()
311
+ .input(z.object({ id: z.string().uuid() }))
312
+ .output(UserSchema)
313
+ .query(async ({ input, ctx }) => {
314
+ // input is typed as { id: string }
315
+ // ^? { id: string }
316
+
317
+ // ctx is typed as BaseContext (with extensions)
318
+ // ^? BaseContext & { db: PrismaClient }
319
+
320
+ // Return type must match UserSchema
321
+ return ctx.db.user.findUnique({ where: { id: input.id } });
322
+ // ^? User | null
323
+ }),
324
+ });
325
+
326
+ // Frontend infers the complete type
327
+ const user = await api.users.getUser({ id: '123' });
328
+ // ^? User | null
329
+ ```
330
+
331
+ ### Type Helpers
332
+
333
+ Extract types from procedures:
334
+
335
+ ```typescript
336
+ import type {
337
+ InferProcedureInput,
338
+ InferProcedureOutput,
339
+ InferProcedures,
340
+ } from '@veloxts/router';
341
+
342
+ // Infer input type
343
+ type GetUserInput = InferProcedureInput<typeof userProcedures.getUser>;
344
+ // { id: string }
345
+
346
+ // Infer output type
347
+ type GetUserOutput = InferProcedureOutput<typeof userProcedures.getUser>;
348
+ // User | null
349
+
350
+ // Infer all procedures
351
+ type UserProcedures = InferProcedures<typeof userProcedures>;
352
+ ```
353
+
354
+ ## Context System
355
+
356
+ Procedures receive a context object with request-scoped state:
357
+
358
+ ### Base Context
359
+
360
+ ```typescript
361
+ interface BaseContext {
362
+ request: FastifyRequest;
363
+ reply: FastifyReply;
364
+ }
365
+ ```
366
+
367
+ ### Extending Context
368
+
369
+ Plugins can extend context via declaration merging:
370
+
371
+ ```typescript
372
+ import type { PrismaClient } from '@prisma/client';
373
+
374
+ declare module '@veloxts/core' {
375
+ interface BaseContext {
376
+ db: PrismaClient; // Added by @veloxts/orm
377
+ user?: User; // Added by @veloxts/auth (v1.1+)
378
+ }
379
+ }
380
+
381
+ // Now all procedures have ctx.db and ctx.user
382
+ const userProcedures = defineProcedures('users', {
383
+ getProfile: procedure()
384
+ .output(UserSchema)
385
+ .query(async ({ ctx }) => {
386
+ // ctx.db is available (typed as PrismaClient)
387
+ // ctx.user is available (typed as User | undefined)
388
+ if (!ctx.user) {
389
+ throw new UnauthorizedError('Must be logged in');
390
+ }
391
+
392
+ return ctx.db.user.findUnique({
393
+ where: { id: ctx.user.id },
394
+ });
395
+ }),
396
+ });
397
+ ```
398
+
399
+ ## Practical Examples
400
+
401
+ ### Complete CRUD API
402
+
403
+ ```typescript
404
+ import { defineProcedures, procedure } from '@veloxts/router';
405
+ import { z, paginationInputSchema } from '@veloxts/validation';
406
+ import { NotFoundError } from '@veloxts/core';
407
+
408
+ const UserSchema = z.object({
409
+ id: z.string().uuid(),
410
+ name: z.string(),
411
+ email: z.string().email(),
412
+ createdAt: z.string().datetime(),
413
+ updatedAt: z.string().datetime(),
414
+ });
415
+
416
+ const CreateUserInput = z.object({
417
+ name: z.string().min(1).max(100),
418
+ email: z.string().email(),
419
+ });
420
+
421
+ export const userProcedures = defineProcedures('users', {
422
+ // GET /users/:id
423
+ getUser: procedure()
424
+ .input(z.object({ id: z.string().uuid() }))
425
+ .output(UserSchema.nullable())
426
+ .query(async ({ input, ctx }) => {
427
+ return ctx.db.user.findUnique({ where: { id: input.id } });
428
+ }),
429
+
430
+ // GET /users
431
+ listUsers: procedure()
432
+ .input(paginationInputSchema.optional())
433
+ .output(z.object({
434
+ data: z.array(UserSchema),
435
+ meta: z.object({
436
+ page: z.number(),
437
+ limit: z.number(),
438
+ total: z.number(),
439
+ }),
440
+ }))
441
+ .query(async ({ input, ctx }) => {
442
+ const page = input?.page ?? 1;
443
+ const limit = input?.limit ?? 10;
444
+ const skip = (page - 1) * limit;
445
+
446
+ const [data, total] = await Promise.all([
447
+ ctx.db.user.findMany({ skip, take: limit }),
448
+ ctx.db.user.count(),
449
+ ]);
450
+
451
+ return { data, meta: { page, limit, total } };
452
+ }),
453
+
454
+ // POST /users
455
+ createUser: procedure()
456
+ .input(CreateUserInput)
457
+ .output(UserSchema)
458
+ .mutation(async ({ input, ctx }) => {
459
+ return ctx.db.user.create({ data: input });
460
+ }),
461
+
462
+ // PUT /users/:id (v1.1+)
463
+ // DELETE /users/:id (v1.1+)
464
+ });
465
+ ```
466
+
467
+ ### Search with Custom Path
468
+
469
+ ```typescript
470
+ const postProcedures = defineProcedures('posts', {
471
+ // GET /posts/search?q=keyword&published=true
472
+ searchPosts: procedure()
473
+ .rest({ method: 'GET', path: '/posts/search' })
474
+ .input(z.object({
475
+ q: z.string().min(1),
476
+ published: z.boolean().optional(),
477
+ }))
478
+ .output(z.array(PostSchema))
479
+ .query(async ({ input, ctx }) => {
480
+ return ctx.db.post.findMany({
481
+ where: {
482
+ AND: [
483
+ {
484
+ OR: [
485
+ { title: { contains: input.q } },
486
+ { content: { contains: input.q } },
487
+ ],
488
+ },
489
+ input.published !== undefined
490
+ ? { published: input.published }
491
+ : {},
492
+ ],
493
+ },
494
+ });
495
+ }),
496
+ });
497
+ ```
498
+
499
+ ### Authentication Middleware
500
+
501
+ ```typescript
502
+ const authMiddleware: MiddlewareFunction = async ({ ctx, next }) => {
503
+ const token = ctx.request.headers.authorization?.replace('Bearer ', '');
504
+
505
+ if (!token) {
506
+ throw new UnauthorizedError('Missing authentication token');
507
+ }
508
+
509
+ // Verify token and attach user to context
510
+ const user = await verifyToken(token);
511
+ (ctx as ExtendedContext).user = user;
512
+
513
+ return next();
514
+ };
515
+
516
+ const protectedProcedures = defineProcedures('protected', {
517
+ getProfile: procedure()
518
+ .use(authMiddleware)
519
+ .output(UserSchema)
520
+ .query(async ({ ctx }) => {
521
+ // ctx.user is guaranteed to exist after authMiddleware
522
+ const user = (ctx as ExtendedContext).user;
523
+ return ctx.db.user.findUnique({ where: { id: user.id } });
524
+ }),
525
+ });
526
+ ```
527
+
528
+ ## Error Handling
529
+
530
+ Procedures integrate with VeloxTS error classes:
531
+
532
+ ```typescript
533
+ import {
534
+ VeloxError,
535
+ NotFoundError,
536
+ ValidationError,
537
+ UnauthorizedError,
538
+ } from '@veloxts/core';
539
+
540
+ const userProcedures = defineProcedures('users', {
541
+ getUser: procedure()
542
+ .input(z.object({ id: z.string().uuid() }))
543
+ .output(UserSchema)
544
+ .query(async ({ input, ctx }) => {
545
+ const user = await ctx.db.user.findUnique({
546
+ where: { id: input.id },
547
+ });
548
+
549
+ if (!user) {
550
+ // Returns 404 with structured error
551
+ throw new NotFoundError('User', input.id);
552
+ }
553
+
554
+ return user;
555
+ }),
556
+
557
+ deleteUser: procedure()
558
+ .input(z.object({ id: z.string().uuid() }))
559
+ .output(z.object({ success: z.boolean() }))
560
+ .mutation(async ({ input, ctx }) => {
561
+ try {
562
+ await ctx.db.user.delete({ where: { id: input.id } });
563
+ return { success: true };
564
+ } catch (error) {
565
+ // Handle Prisma errors
566
+ if (error.code === 'P2025') {
567
+ throw new NotFoundError('User', input.id);
568
+ }
569
+ throw new VeloxError('Failed to delete user', 500);
570
+ }
571
+ }),
572
+ });
573
+ ```
574
+
575
+ ## Configuration
576
+
577
+ ### Route Summary
578
+
579
+ Get a summary of generated routes:
580
+
581
+ ```typescript
582
+ import { getRouteSummary } from '@veloxts/router';
583
+
584
+ const summary = getRouteSummary({
585
+ users: userProcedures,
586
+ posts: postProcedures,
587
+ });
588
+
589
+ console.log(summary);
590
+ // [
591
+ // { method: 'GET', path: '/users/:id', procedure: 'users.getUser' },
592
+ // { method: 'GET', path: '/users', procedure: 'users.listUsers' },
593
+ // { method: 'POST', path: '/users', procedure: 'users.createUser' },
594
+ // { method: 'GET', path: '/posts/:id', procedure: 'posts.getPost' },
595
+ // ...
596
+ // ]
597
+ ```
598
+
599
+ ### Route Prefix
600
+
601
+ Apply a common prefix to all routes:
602
+
603
+ ```typescript
604
+ await registerRestRoutes(app.server, {
605
+ prefix: '/api/v1', // All routes start with /api/v1
606
+ procedures: {
607
+ users: userProcedures,
608
+ },
609
+ });
610
+
611
+ // Generates: GET /api/v1/users/:id
612
+ ```
613
+
614
+ ## MVP Limitations
615
+
616
+ The current v0.1.0 release supports:
617
+
618
+ **Included:**
619
+ - Query procedures (GET)
620
+ - Mutation procedures (POST)
621
+ - Input/output validation with Zod
622
+ - Naming convention-based REST mapping
623
+ - Custom REST path overrides
624
+ - tRPC adapter for type-safe internal calls
625
+ - Middleware support
626
+
627
+ **Deferred to v1.1+:**
628
+ - Full REST verbs (PUT, PATCH, DELETE)
629
+ - Nested resource routing
630
+ - OpenAPI/Swagger documentation generation
631
+ - Rate limiting middleware
632
+ - Request/response transformation hooks
633
+
634
+ ## Related Packages
635
+
636
+ - [@veloxts/core](/packages/core) - Core framework with context and errors
637
+ - [@veloxts/validation](/packages/validation) - Zod schemas for input/output
638
+ - [@veloxts/orm](/packages/orm) - Database integration (provides ctx.db)
639
+ - [@veloxts/client](/packages/client) - Type-safe frontend API client
640
+
641
+ ## TypeScript Support
642
+
643
+ All exports are fully typed with comprehensive JSDoc documentation. The package includes type definitions and declaration maps for excellent IDE support.
644
+
645
+ ## License
646
+
647
+ MIT
@@ -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