astro-routify 1.2.2 → 1.5.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/README.md +367 -28
- package/dist/core/RouteTrie.d.ts +4 -3
- package/dist/core/RouteTrie.js +132 -35
- package/dist/core/RouterBuilder.d.ts +96 -13
- package/dist/core/RouterBuilder.js +243 -21
- package/dist/core/decorators.d.ts +29 -0
- package/dist/core/decorators.js +49 -0
- package/dist/core/defineGroup.d.ts +33 -17
- package/dist/core/defineGroup.js +66 -23
- package/dist/core/defineHandler.d.ts +31 -13
- package/dist/core/defineHandler.js +1 -23
- package/dist/core/defineRoute.d.ts +32 -3
- package/dist/core/defineRoute.js +36 -9
- package/dist/core/defineRouter.d.ts +11 -1
- package/dist/core/defineRouter.js +79 -16
- package/dist/core/internal/createJsonStreamRoute.d.ts +1 -1
- package/dist/core/internal/createJsonStreamRoute.js +12 -4
- package/dist/core/middlewares.d.ts +47 -0
- package/dist/core/middlewares.js +110 -0
- package/dist/core/openapi.d.ts +17 -0
- package/dist/core/openapi.js +84 -0
- package/dist/core/registry.d.ts +15 -0
- package/dist/core/registry.js +26 -0
- package/dist/core/responseHelpers.d.ts +22 -5
- package/dist/core/responseHelpers.js +121 -20
- package/dist/core/stream.d.ts +3 -3
- package/dist/core/stream.js +16 -9
- package/dist/core/streamJsonArray.d.ts +1 -1
- package/dist/core/streamJsonArray.js +1 -1
- package/dist/index.d.ts +338 -57
- package/dist/index.js +5 -1
- package/package.json +5 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as astro from 'astro';
|
|
2
1
|
import { APIContext, APIRoute } from 'astro';
|
|
3
2
|
import { HeadersInit, BodyInit } from 'undici';
|
|
4
3
|
|
|
@@ -16,6 +15,10 @@ declare const ALLOWED_HTTP_METHODS: Set<string>;
|
|
|
16
15
|
*/
|
|
17
16
|
declare function normalizeMethod(method: string): HttpMethod;
|
|
18
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Supported types that can be returned from a route handler.
|
|
20
|
+
*/
|
|
21
|
+
type HandlerResult = Response | ResultResponse | string | number | boolean | object | ArrayBuffer | Uint8Array | ReadableStream<Uint8Array> | Blob | FormData | URLSearchParams | null | undefined;
|
|
19
22
|
/**
|
|
20
23
|
* A standardized shape for internal route result objects.
|
|
21
24
|
* These are later converted into native `Response` instances.
|
|
@@ -74,14 +77,20 @@ declare const methodNotAllowed: <T = string>(body?: T, headers?: HeadersInit) =>
|
|
|
74
77
|
* 429 Too Many Requests
|
|
75
78
|
*/
|
|
76
79
|
declare const tooManyRequests: <T = string>(body?: T, headers?: HeadersInit) => ResultResponse<T>;
|
|
80
|
+
/**
|
|
81
|
+
* Returns a response with JSON body and specified status.
|
|
82
|
+
*/
|
|
83
|
+
declare const json: (body: any, status?: number, headers?: HeadersInit) => ResultResponse<any>;
|
|
77
84
|
/**
|
|
78
85
|
* 500 Internal Server Error
|
|
86
|
+
*
|
|
87
|
+
* In production, you might want to avoid leaking error details.
|
|
79
88
|
*/
|
|
80
89
|
declare const internalError: (err: unknown, headers?: HeadersInit) => ResultResponse<string>;
|
|
81
90
|
/**
|
|
82
91
|
* Sends a binary or stream-based file response with optional content-disposition.
|
|
83
92
|
*
|
|
84
|
-
* @param content - The file
|
|
93
|
+
* @param content - The file state (Blob, ArrayBuffer, or stream)
|
|
85
94
|
* @param contentType - MIME type of the file
|
|
86
95
|
* @param fileName - Optional download filename
|
|
87
96
|
* @param headers - Optional extra headers
|
|
@@ -89,23 +98,55 @@ declare const internalError: (err: unknown, headers?: HeadersInit) => ResultResp
|
|
|
89
98
|
*/
|
|
90
99
|
declare const fileResponse: (content: Blob | ArrayBuffer | ReadableStream<Uint8Array>, contentType: string, fileName?: string, headers?: HeadersInit) => ResultResponse<BodyInit>;
|
|
91
100
|
/**
|
|
92
|
-
*
|
|
101
|
+
* Type guard to detect ReadableStreams, used for streamed/binary responses.
|
|
102
|
+
*
|
|
103
|
+
* @param value - Any value to test
|
|
104
|
+
* @returns True if it looks like a ReadableStream
|
|
105
|
+
*/
|
|
106
|
+
declare function isReadableStream(value: unknown): value is ReadableStream<Uint8Array>;
|
|
107
|
+
/**
|
|
108
|
+
* Converts an internal `ResultResponse` or any `HandlerResult` into a native `Response` object
|
|
93
109
|
* for use inside Astro API routes.
|
|
94
110
|
*
|
|
95
|
-
* Automatically applies
|
|
111
|
+
* Automatically applies appropriate Content-Type headers.
|
|
96
112
|
*
|
|
97
|
-
* @param result - A ResultResponse returned from route handler
|
|
113
|
+
* @param result - A ResultResponse or other supported type returned from route handler
|
|
98
114
|
* @returns A native Response
|
|
99
115
|
*/
|
|
100
|
-
declare function toAstroResponse(result:
|
|
116
|
+
declare function toAstroResponse(result: HandlerResult): Response;
|
|
101
117
|
|
|
102
118
|
/**
|
|
103
|
-
*
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
119
|
+
* Enhanced Astro context for Routify.
|
|
120
|
+
*/
|
|
121
|
+
interface RoutifyContext<State = Record<string, any>> extends APIContext {
|
|
122
|
+
/**
|
|
123
|
+
* Parsed query parameters from the URL.
|
|
124
|
+
* Note: If multiple parameters have the same key, only the last one is included.
|
|
125
|
+
* Use `searchParams` for full multi-value support.
|
|
126
|
+
*/
|
|
127
|
+
query: Record<string, string | string[]>;
|
|
128
|
+
/**
|
|
129
|
+
* Full URLSearchParams object for the incoming request.
|
|
130
|
+
*/
|
|
131
|
+
searchParams: URLSearchParams;
|
|
132
|
+
/**
|
|
133
|
+
* Shared state container for middlewares and handlers (e.g., validation results).
|
|
134
|
+
* This is where middlewares can store information for subsequent handlers.
|
|
135
|
+
*/
|
|
136
|
+
state: State;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Convenience type alias for RoutifyContext.
|
|
107
140
|
*/
|
|
108
|
-
type
|
|
141
|
+
type Context<State = Record<string, any>> = RoutifyContext<State>;
|
|
142
|
+
/**
|
|
143
|
+
* A middleware function that can modify the context or short-circuit the response.
|
|
144
|
+
*/
|
|
145
|
+
type Middleware<State = any> = (ctx: RoutifyContext<State>, next: () => Promise<Response>) => Promise<Response> | Response;
|
|
146
|
+
/**
|
|
147
|
+
* A flexible route handler that can return various types.
|
|
148
|
+
*/
|
|
149
|
+
type Handler<State = any> = (ctx: RoutifyContext<State>) => Promise<HandlerResult> | HandlerResult;
|
|
109
150
|
/**
|
|
110
151
|
* Wraps a `Handler` function into an `APIRoute` that:
|
|
111
152
|
* - logs requests and responses,
|
|
@@ -117,13 +158,6 @@ type Handler = (ctx: APIContext) => Promise<ResultResponse | Response> | ResultR
|
|
|
117
158
|
* @returns An Astro-compatible `APIRoute` function
|
|
118
159
|
*/
|
|
119
160
|
declare function defineHandler(handler: Handler): APIRoute;
|
|
120
|
-
/**
|
|
121
|
-
* Type guard to detect ReadableStreams, used for streamed/binary responses.
|
|
122
|
-
*
|
|
123
|
-
* @param value - Any value to test
|
|
124
|
-
* @returns True if it looks like a ReadableStream
|
|
125
|
-
*/
|
|
126
|
-
declare function isReadableStream(value: unknown): value is ReadableStream<Uint8Array>;
|
|
127
161
|
|
|
128
162
|
/**
|
|
129
163
|
* Represents a single route definition.
|
|
@@ -141,6 +175,19 @@ interface Route {
|
|
|
141
175
|
* The function that handles the request when matched.
|
|
142
176
|
*/
|
|
143
177
|
handler: Handler;
|
|
178
|
+
/**
|
|
179
|
+
* Optional array of middlewares to run before the handler.
|
|
180
|
+
*/
|
|
181
|
+
middlewares?: Middleware[];
|
|
182
|
+
/**
|
|
183
|
+
* Optional metadata for the route (e.g. for OpenAPI generation).
|
|
184
|
+
*/
|
|
185
|
+
metadata?: Record<string, any>;
|
|
186
|
+
/**
|
|
187
|
+
* Internal marker to identify the object type during module discovery.
|
|
188
|
+
* @internal
|
|
189
|
+
*/
|
|
190
|
+
_routifyType?: 'route';
|
|
144
191
|
}
|
|
145
192
|
/**
|
|
146
193
|
* Defines a route using a `Route` object.
|
|
@@ -149,9 +196,10 @@ interface Route {
|
|
|
149
196
|
* defineRoute({ method: 'GET', path: '/users', handler });
|
|
150
197
|
*
|
|
151
198
|
* @param route - A fully constructed route object
|
|
199
|
+
* @param autoRegister - If true, registers the route to the global registry
|
|
152
200
|
* @returns The validated Route object
|
|
153
201
|
*/
|
|
154
|
-
declare function defineRoute(route: Route): Route;
|
|
202
|
+
declare function defineRoute(route: Route, autoRegister?: boolean): Route;
|
|
155
203
|
/**
|
|
156
204
|
* Defines a route by specifying its method, path, and handler explicitly.
|
|
157
205
|
*
|
|
@@ -161,9 +209,24 @@ declare function defineRoute(route: Route): Route;
|
|
|
161
209
|
* @param method - HTTP method to match
|
|
162
210
|
* @param path - Route path (must start with `/`)
|
|
163
211
|
* @param handler - Function to handle the matched request
|
|
212
|
+
* @param autoRegister - If true, registers the route to the global registry
|
|
164
213
|
* @returns The validated Route object
|
|
165
214
|
*/
|
|
166
|
-
declare function defineRoute(method: HttpMethod, path: string, handler: Handler): Route;
|
|
215
|
+
declare function defineRoute(method: HttpMethod, path: string, handler: Handler, autoRegister?: boolean): Route;
|
|
216
|
+
/**
|
|
217
|
+
* Ensures the route is properly formed and uses a valid method + path format.
|
|
218
|
+
*
|
|
219
|
+
* @param route - Route to validate
|
|
220
|
+
* @throws If method is unsupported or path doesn't start with `/`
|
|
221
|
+
*/
|
|
222
|
+
declare function validateRoute({ method, path }: Route): void;
|
|
223
|
+
/**
|
|
224
|
+
* Checks if an object implements the `Route` interface.
|
|
225
|
+
*
|
|
226
|
+
* @param obj - The object to check
|
|
227
|
+
* @returns True if the object is a valid Route
|
|
228
|
+
*/
|
|
229
|
+
declare function isRoute(obj: any): obj is Route;
|
|
167
230
|
|
|
168
231
|
/**
|
|
169
232
|
* Optional configuration for the router instance.
|
|
@@ -178,6 +241,15 @@ interface RouterOptions {
|
|
|
178
241
|
* Custom handler to return when no route is matched (404).
|
|
179
242
|
*/
|
|
180
243
|
onNotFound?: () => ReturnType<typeof notFound>;
|
|
244
|
+
/**
|
|
245
|
+
* If true, enables debug logging for route matching.
|
|
246
|
+
* Useful during development to trace which route is being matched.
|
|
247
|
+
*/
|
|
248
|
+
debug?: boolean;
|
|
249
|
+
/**
|
|
250
|
+
* Custom error handler for the router.
|
|
251
|
+
*/
|
|
252
|
+
onError?: (error: unknown, ctx: RoutifyContext) => HandlerResult | Response;
|
|
181
253
|
}
|
|
182
254
|
/**
|
|
183
255
|
* Defines a router that dynamically matches registered routes based on method and path.
|
|
@@ -215,8 +287,10 @@ declare function defineRouter(routes: Route[], options?: RouterOptions): APIRout
|
|
|
215
287
|
* .addPost('/', createUser);
|
|
216
288
|
*/
|
|
217
289
|
declare class RouteGroup {
|
|
290
|
+
readonly _routifyType = "group";
|
|
218
291
|
private basePath;
|
|
219
292
|
private routes;
|
|
293
|
+
private middlewares;
|
|
220
294
|
/**
|
|
221
295
|
* Creates a new route group with the specified base path.
|
|
222
296
|
* Trailing slashes are automatically removed.
|
|
@@ -228,49 +302,61 @@ declare class RouteGroup {
|
|
|
228
302
|
* Returns the normalized base path used by the group.
|
|
229
303
|
*/
|
|
230
304
|
getBasePath(): string;
|
|
305
|
+
/**
|
|
306
|
+
* Adds a middleware to all routes in this group.
|
|
307
|
+
*
|
|
308
|
+
* @param middleware - The middleware function to add
|
|
309
|
+
* @returns The current group instance
|
|
310
|
+
*/
|
|
311
|
+
use(middleware: Middleware): this;
|
|
231
312
|
/**
|
|
232
313
|
* Registers a GET route under the group's base path.
|
|
233
314
|
*
|
|
234
315
|
* @param path - Path relative to the base path (e.g. "/:id")
|
|
235
|
-
* @param
|
|
316
|
+
* @param handlers - Middleware(s) followed by a handler function
|
|
236
317
|
*/
|
|
237
|
-
addGet(path: string,
|
|
318
|
+
addGet(path: string, ...handlers: any[]): this;
|
|
238
319
|
/**
|
|
239
320
|
* Registers a POST route under the group's base path.
|
|
240
321
|
*
|
|
241
322
|
* @param path - Path relative to the base path
|
|
242
|
-
* @param
|
|
323
|
+
* @param handlers - Middleware(s) followed by a handler function
|
|
243
324
|
*/
|
|
244
|
-
addPost(path: string,
|
|
325
|
+
addPost(path: string, ...handlers: any[]): this;
|
|
245
326
|
/**
|
|
246
327
|
* Registers a PUT route under the group's base path.
|
|
247
328
|
*
|
|
248
329
|
* @param path - Path relative to the base path
|
|
249
|
-
* @param
|
|
330
|
+
* @param handlers - Middleware(s) followed by a handler function
|
|
250
331
|
*/
|
|
251
|
-
addPut(path: string,
|
|
332
|
+
addPut(path: string, ...handlers: any[]): this;
|
|
252
333
|
/**
|
|
253
334
|
* Registers a DELETE route under the group's base path.
|
|
254
335
|
*
|
|
255
336
|
* @param path - Path relative to the base path
|
|
256
|
-
* @param
|
|
337
|
+
* @param handlers - Middleware(s) followed by a handler function
|
|
257
338
|
*/
|
|
258
|
-
addDelete(path: string,
|
|
339
|
+
addDelete(path: string, ...handlers: any[]): this;
|
|
259
340
|
/**
|
|
260
341
|
* Registers a PATCH route under the group's base path.
|
|
261
342
|
*
|
|
262
343
|
* @param path - Path relative to the base path
|
|
263
|
-
* @param
|
|
344
|
+
* @param handlers - Middleware(s) followed by a handler function
|
|
264
345
|
*/
|
|
265
|
-
addPatch(path: string,
|
|
346
|
+
addPatch(path: string, ...handlers: any[]): this;
|
|
266
347
|
/**
|
|
267
|
-
*
|
|
348
|
+
* Registers a route under the group's base path.
|
|
268
349
|
*
|
|
269
350
|
* @param method - HTTP verb
|
|
270
|
-
* @param
|
|
271
|
-
* @param
|
|
351
|
+
* @param path - Path relative to the base path
|
|
352
|
+
* @param args - Middleware(s) and handler
|
|
353
|
+
* @returns The current group instance
|
|
272
354
|
*/
|
|
273
|
-
|
|
355
|
+
add(method: HttpMethod, path: string, ...args: any[]): this;
|
|
356
|
+
/**
|
|
357
|
+
* Registers the group and all its current routes to the global registry.
|
|
358
|
+
*/
|
|
359
|
+
register(): this;
|
|
274
360
|
/**
|
|
275
361
|
* Returns all the registered routes in the group.
|
|
276
362
|
*/
|
|
@@ -281,23 +367,25 @@ declare class RouteGroup {
|
|
|
281
367
|
*
|
|
282
368
|
* @param basePath - The base path prefix for all routes
|
|
283
369
|
* @param configure - Optional callback to configure the group inline
|
|
370
|
+
* @param autoRegister - If true, registers the group to the global registry
|
|
284
371
|
*
|
|
285
372
|
* @example
|
|
286
373
|
* const users = defineGroup('/users', (group) => {
|
|
287
374
|
* group.addGet('/:id', handler);
|
|
288
|
-
* });
|
|
375
|
+
* }, true);
|
|
289
376
|
*/
|
|
290
|
-
declare function defineGroup(basePath: string, configure?: (group: RouteGroup) => void): RouteGroup;
|
|
377
|
+
declare function defineGroup(basePath: string, configure?: (group: RouteGroup) => void, autoRegister?: boolean): RouteGroup;
|
|
291
378
|
|
|
292
379
|
interface RouteMatch {
|
|
293
|
-
|
|
380
|
+
route: Route | null;
|
|
294
381
|
allowed?: HttpMethod[];
|
|
295
382
|
params: Record<string, string | undefined>;
|
|
296
383
|
}
|
|
297
384
|
declare class RouteTrie {
|
|
298
385
|
private readonly root;
|
|
299
|
-
insert(
|
|
386
|
+
insert(route: Route): void;
|
|
300
387
|
find(path: string, method: HttpMethod): RouteMatch;
|
|
388
|
+
private matchNode;
|
|
301
389
|
private segmentize;
|
|
302
390
|
}
|
|
303
391
|
|
|
@@ -326,12 +414,72 @@ declare class RouteTrie {
|
|
|
326
414
|
*
|
|
327
415
|
* export const GET = router.build();
|
|
328
416
|
* ```
|
|
417
|
+
*
|
|
418
|
+
* @example Auto-discovering routes via Vite glob:
|
|
419
|
+
* ```ts
|
|
420
|
+
* const router = new RouterBuilder()
|
|
421
|
+
* .addModules(import.meta.glob('./**\/*.routes.ts', { eager: true }));
|
|
422
|
+
*
|
|
423
|
+
* export const ALL = router.build();
|
|
424
|
+
* ```
|
|
329
425
|
*/
|
|
330
426
|
declare class RouterBuilder {
|
|
331
427
|
private _options;
|
|
332
428
|
private _routes;
|
|
429
|
+
private _groups;
|
|
430
|
+
private _middlewares;
|
|
431
|
+
private _shouldLog;
|
|
333
432
|
private static _registerWarned;
|
|
433
|
+
/**
|
|
434
|
+
* A global RouterBuilder instance for easy, centralized route registration.
|
|
435
|
+
*/
|
|
436
|
+
static readonly global: RouterBuilder;
|
|
334
437
|
constructor(options?: RouterOptions);
|
|
438
|
+
/**
|
|
439
|
+
* Adds a global middleware to all routes registered in this builder.
|
|
440
|
+
*
|
|
441
|
+
* @param middleware - The middleware function.
|
|
442
|
+
* @returns The current builder instance.
|
|
443
|
+
*/
|
|
444
|
+
use(middleware: Middleware): this;
|
|
445
|
+
/**
|
|
446
|
+
* Creates and adds a new route group to the builder.
|
|
447
|
+
*
|
|
448
|
+
* @param basePath - The base path for the group.
|
|
449
|
+
* @param configure - Optional callback to configure the group.
|
|
450
|
+
* @returns The created RouteGroup instance.
|
|
451
|
+
*/
|
|
452
|
+
group(basePath: string, configure?: (group: RouteGroup) => void): RouteGroup;
|
|
453
|
+
/**
|
|
454
|
+
* Adds all routes and groups that have been auto-registered via `defineRoute(..., true)`
|
|
455
|
+
* or `defineGroup(..., true)`.
|
|
456
|
+
*
|
|
457
|
+
* @returns The current builder instance.
|
|
458
|
+
*/
|
|
459
|
+
addRegistered(): this;
|
|
460
|
+
/**
|
|
461
|
+
* Bulk registers routes and groups from a module collection.
|
|
462
|
+
* Ideal for use with Vite's `import.meta.glob` (with `{ eager: true }`).
|
|
463
|
+
*
|
|
464
|
+
* It will search for both default and named exports that are either `Route` or `RouteGroup`.
|
|
465
|
+
*
|
|
466
|
+
* @param modules A record of modules (e.g. from `import.meta.glob`).
|
|
467
|
+
* @returns The current builder instance.
|
|
468
|
+
*/
|
|
469
|
+
addModules(modules: Record<string, any>): this;
|
|
470
|
+
/**
|
|
471
|
+
* Prints all registered routes to the console.
|
|
472
|
+
* Useful for debugging during development.
|
|
473
|
+
*
|
|
474
|
+
* @returns The current builder instance.
|
|
475
|
+
*/
|
|
476
|
+
logRoutes(): this;
|
|
477
|
+
/**
|
|
478
|
+
* Disables the automatic logging of routes that happens in development mode.
|
|
479
|
+
*
|
|
480
|
+
* @returns The current builder instance.
|
|
481
|
+
*/
|
|
482
|
+
disableLogging(): this;
|
|
335
483
|
/**
|
|
336
484
|
* @deprecated Prefer `addGroup()` or `addRoute()` for structured routing.
|
|
337
485
|
*
|
|
@@ -370,39 +518,39 @@ declare class RouterBuilder {
|
|
|
370
518
|
/**
|
|
371
519
|
* Adds a GET route.
|
|
372
520
|
* @param path Route path (e.g., `/items/:id`)
|
|
373
|
-
* @param
|
|
521
|
+
* @param handlers Middleware(s) followed by a request handler function.
|
|
374
522
|
*/
|
|
375
|
-
addGet(path: string,
|
|
523
|
+
addGet(path: string, ...handlers: any[]): this;
|
|
376
524
|
/**
|
|
377
525
|
* Adds a POST route.
|
|
378
526
|
* @param path Route path.
|
|
379
|
-
* @param
|
|
527
|
+
* @param handlers Middleware(s) followed by a request handler function.
|
|
380
528
|
*/
|
|
381
|
-
addPost(path: string,
|
|
529
|
+
addPost(path: string, ...handlers: any[]): this;
|
|
382
530
|
/**
|
|
383
531
|
* Adds a PUT route.
|
|
384
532
|
* @param path Route path.
|
|
385
|
-
* @param
|
|
533
|
+
* @param handlers Middleware(s) followed by a request handler function.
|
|
386
534
|
*/
|
|
387
|
-
addPut(path: string,
|
|
535
|
+
addPut(path: string, ...handlers: any[]): this;
|
|
388
536
|
/**
|
|
389
537
|
* Adds a DELETE route.
|
|
390
538
|
* @param path Route path.
|
|
391
|
-
* @param
|
|
539
|
+
* @param handlers Middleware(s) followed by a request handler function.
|
|
392
540
|
*/
|
|
393
|
-
addDelete(path: string,
|
|
541
|
+
addDelete(path: string, ...handlers: any[]): this;
|
|
394
542
|
/**
|
|
395
543
|
* Adds a PATCH route.
|
|
396
544
|
* @param path Route path.
|
|
397
|
-
* @param
|
|
545
|
+
* @param handlers Middleware(s) followed by a request handler function.
|
|
398
546
|
*/
|
|
399
|
-
addPatch(path: string,
|
|
547
|
+
addPatch(path: string, ...handlers: any[]): this;
|
|
400
548
|
/**
|
|
401
549
|
* Internal helper to add a route with any HTTP method.
|
|
402
550
|
*
|
|
403
551
|
* @param method The HTTP method.
|
|
404
552
|
* @param subPath Path segment (can be relative or absolute).
|
|
405
|
-
* @param
|
|
553
|
+
* @param args Middleware(s) and handler.
|
|
406
554
|
* @returns The current builder instance (for chaining).
|
|
407
555
|
*/
|
|
408
556
|
private add;
|
|
@@ -414,11 +562,79 @@ declare class RouterBuilder {
|
|
|
414
562
|
*
|
|
415
563
|
* @returns A fully resolved Astro route handler.
|
|
416
564
|
*/
|
|
417
|
-
build():
|
|
565
|
+
build(): APIRoute;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* A convenience helper to create a router.
|
|
569
|
+
*
|
|
570
|
+
* If modules are provided (e.g. from Vite's `import.meta.glob`), they will be registered.
|
|
571
|
+
* If no modules are provided, it will automatically include all routes that were
|
|
572
|
+
* registered via the auto-registration flags (`defineRoute(..., true)`).
|
|
573
|
+
*
|
|
574
|
+
* @example Auto-discovery via glob:
|
|
575
|
+
* ```ts
|
|
576
|
+
* export const ALL = createRouter(import.meta.glob('./**\/*.ts', { eager: true }));
|
|
577
|
+
* ```
|
|
578
|
+
*
|
|
579
|
+
* @example Auto-registration via global registry:
|
|
580
|
+
* ```ts
|
|
581
|
+
* export const ALL = createRouter();
|
|
582
|
+
* ```
|
|
583
|
+
*
|
|
584
|
+
* @param modulesOrOptions Either modules to register or router options.
|
|
585
|
+
* @param options Router options (if first arg is modules).
|
|
586
|
+
* @returns An Astro-compatible route handler.
|
|
587
|
+
*/
|
|
588
|
+
declare function createRouter(modulesOrOptions?: Record<string, any> | RouterOptions, options?: RouterOptions): APIRoute;
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* A global registry for routes and groups to support "agnostic" auto-registration.
|
|
592
|
+
* This allows routes to be defined anywhere in the project and automatically
|
|
593
|
+
* picked up by the router.
|
|
594
|
+
*/
|
|
595
|
+
declare class InternalRegistry {
|
|
596
|
+
private static instance;
|
|
597
|
+
private items;
|
|
598
|
+
private constructor();
|
|
599
|
+
static getInstance(): InternalRegistry;
|
|
600
|
+
register(item: any): void;
|
|
601
|
+
getItems(): any[];
|
|
602
|
+
clear(): void;
|
|
418
603
|
}
|
|
604
|
+
declare const globalRegistry: InternalRegistry;
|
|
419
605
|
|
|
420
606
|
/**
|
|
421
|
-
*
|
|
607
|
+
* @Get decorator - auto-registers a GET route.
|
|
608
|
+
*/
|
|
609
|
+
declare const Get: (path: string) => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
|
|
610
|
+
/**
|
|
611
|
+
* @Post decorator - auto-registers a POST route.
|
|
612
|
+
*/
|
|
613
|
+
declare const Post: (path: string) => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
|
|
614
|
+
/**
|
|
615
|
+
* @Put decorator - auto-registers a PUT route.
|
|
616
|
+
*/
|
|
617
|
+
declare const Put: (path: string) => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
|
|
618
|
+
/**
|
|
619
|
+
* @Delete decorator - auto-registers a DELETE route.
|
|
620
|
+
*/
|
|
621
|
+
declare const Delete: (path: string) => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
|
|
622
|
+
/**
|
|
623
|
+
* @Patch decorator - auto-registers a PATCH route.
|
|
624
|
+
*/
|
|
625
|
+
declare const Patch: (path: string) => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
|
|
626
|
+
/**
|
|
627
|
+
* @RouteGroup decorator - can be used on classes to auto-register a group.
|
|
628
|
+
* Note: This requires the class to have a static method or property that returns the routes,
|
|
629
|
+
* or it can be used in conjunction with method decorators.
|
|
630
|
+
*
|
|
631
|
+
* For now, we'll implement a simple version that can be used on a class
|
|
632
|
+
* if the class is intended to be a group.
|
|
633
|
+
*/
|
|
634
|
+
declare function Group(basePath: string): (constructor: Function) => void;
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* A writer for streaming raw state to the response body.
|
|
422
638
|
*
|
|
423
639
|
* This is used inside the `stream()` route handler to emit bytes
|
|
424
640
|
* or strings directly to the client with backpressure awareness.
|
|
@@ -462,7 +678,7 @@ interface StreamOptions {
|
|
|
462
678
|
keepAlive?: boolean;
|
|
463
679
|
}
|
|
464
680
|
/**
|
|
465
|
-
* Defines a generic streaming route that can write raw chunks of
|
|
681
|
+
* Defines a generic streaming route that can write raw chunks of state
|
|
466
682
|
* to the response in real time using a `ReadableStream`.
|
|
467
683
|
*
|
|
468
684
|
* Suitable for Server-Sent Events (SSE), long-polling, streamed HTML,
|
|
@@ -471,7 +687,7 @@ interface StreamOptions {
|
|
|
471
687
|
* @example
|
|
472
688
|
* stream('/clock', async ({ response }) => {
|
|
473
689
|
* const timer = setInterval(() => {
|
|
474
|
-
* response.write(`
|
|
690
|
+
* response.write(`state: ${new Date().toISOString()}\n\n`);
|
|
475
691
|
* }, 1000);
|
|
476
692
|
*
|
|
477
693
|
* setTimeout(() => {
|
|
@@ -491,7 +707,7 @@ declare function stream(path: string, handler: (ctx: APIContext & {
|
|
|
491
707
|
|
|
492
708
|
type JsonValue = any;
|
|
493
709
|
/**
|
|
494
|
-
* A writer interface for streaming JSON
|
|
710
|
+
* A writer interface for streaming JSON state to the response body.
|
|
495
711
|
* Supports both NDJSON and array formats.
|
|
496
712
|
*/
|
|
497
713
|
interface JsonStreamWriter {
|
|
@@ -555,7 +771,7 @@ declare function streamJsonND(path: string, handler: (ctx: APIContext & {
|
|
|
555
771
|
* Defines a JSON streaming route that emits a valid JSON array.
|
|
556
772
|
*
|
|
557
773
|
* This helper returns a valid `application/json` response containing
|
|
558
|
-
* a streamable array of JSON values. Useful for large
|
|
774
|
+
* a streamable array of JSON values. Useful for large state exports
|
|
559
775
|
* or APIs where the full array can be streamed as it's generated.
|
|
560
776
|
*
|
|
561
777
|
* Unlike `streamJsonND()`, this wraps all values in `[` and `]`
|
|
@@ -579,5 +795,70 @@ declare function streamJsonArray(path: string, handler: (ctx: APIContext & {
|
|
|
579
795
|
method?: HttpMethod;
|
|
580
796
|
}): Route;
|
|
581
797
|
|
|
582
|
-
|
|
583
|
-
|
|
798
|
+
/**
|
|
799
|
+
* CORS options.
|
|
800
|
+
*/
|
|
801
|
+
interface CorsOptions {
|
|
802
|
+
origin?: string | string[] | ((origin: string) => boolean | string);
|
|
803
|
+
methods?: string[];
|
|
804
|
+
allowedHeaders?: string[];
|
|
805
|
+
exposedHeaders?: string[];
|
|
806
|
+
credentials?: boolean;
|
|
807
|
+
maxAge?: number;
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Middleware to enable Cross-Origin Resource Sharing (CORS).
|
|
811
|
+
*/
|
|
812
|
+
declare function cors(options?: CorsOptions): Middleware;
|
|
813
|
+
/**
|
|
814
|
+
* Middleware to add common security headers (Helmet-like).
|
|
815
|
+
*/
|
|
816
|
+
declare function securityHeaders(): Middleware;
|
|
817
|
+
/**
|
|
818
|
+
* Interface for schemas compatible with Zod, Valibot, etc.
|
|
819
|
+
*/
|
|
820
|
+
interface Validatable {
|
|
821
|
+
safeParse: (data: any) => {
|
|
822
|
+
success: true;
|
|
823
|
+
data: any;
|
|
824
|
+
} | {
|
|
825
|
+
success: false;
|
|
826
|
+
error: any;
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Validation schema for request components.
|
|
831
|
+
*/
|
|
832
|
+
interface ValidationSchema {
|
|
833
|
+
body?: Validatable;
|
|
834
|
+
query?: Validatable;
|
|
835
|
+
params?: Validatable;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Middleware for request validation.
|
|
839
|
+
* Supports any schema library with a `safeParse` method (like Zod).
|
|
840
|
+
*
|
|
841
|
+
* Validated state is stored in `ctx.state.body`, `ctx.state.query`, etc.
|
|
842
|
+
*/
|
|
843
|
+
declare function validate(schema: ValidationSchema): Middleware;
|
|
844
|
+
|
|
845
|
+
/**
|
|
846
|
+
* Basic options for OpenAPI generation.
|
|
847
|
+
*/
|
|
848
|
+
interface OpenAPIOptions {
|
|
849
|
+
title: string;
|
|
850
|
+
version: string;
|
|
851
|
+
description?: string;
|
|
852
|
+
basePath?: string;
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Generates an OpenAPI 3.0.0 specification from a list of Routify routes.
|
|
856
|
+
*
|
|
857
|
+
* @param router - The router handler function (returned by builder.build() or createRouter())
|
|
858
|
+
* @param options - Basic info for the OpenAPI spec
|
|
859
|
+
* @returns A JSON object representing the OpenAPI specification
|
|
860
|
+
*/
|
|
861
|
+
declare function generateOpenAPI(router: any, options: OpenAPIOptions): any;
|
|
862
|
+
|
|
863
|
+
export { ALLOWED_HTTP_METHODS, Delete, Get, Group, HttpMethod, Patch, Post, Put, RouteGroup, RouteTrie, RouterBuilder, badRequest, cors, createRouter, created, defineGroup, defineHandler, defineRoute, defineRouter, fileResponse, forbidden, generateOpenAPI, globalRegistry, internalError, isReadableStream, isRoute, json, methodNotAllowed, noContent, normalizeMethod, notFound, notModified, ok, securityHeaders, stream, streamJsonArray, streamJsonND, toAstroResponse, tooManyRequests, unauthorized, validate, validateRoute };
|
|
864
|
+
export type { Context, CorsOptions, Handler, HandlerResult, JsonStreamWriter, Middleware, OpenAPIOptions, ResultResponse, Route, RouterOptions, RoutifyContext, StreamOptions, StreamWriter, Validatable, ValidationSchema };
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,11 @@ export * from './core/defineGroup';
|
|
|
5
5
|
export * from './core/RouteTrie';
|
|
6
6
|
export * from './core/HttpMethod';
|
|
7
7
|
export * from './core/responseHelpers';
|
|
8
|
-
export
|
|
8
|
+
export { RouterBuilder, createRouter } from './core/RouterBuilder';
|
|
9
|
+
export { globalRegistry } from './core/registry';
|
|
10
|
+
export * from './core/decorators';
|
|
9
11
|
export * from './core/stream';
|
|
10
12
|
export * from './core/streamJsonND';
|
|
11
13
|
export * from './core/streamJsonArray';
|
|
14
|
+
export * from './core/middlewares';
|
|
15
|
+
export * from './core/openapi';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-routify",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "A high-performance API router for Astro using a Trie-based matcher.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
"ndjson",
|
|
29
29
|
"json-stream",
|
|
30
30
|
"response-helpers",
|
|
31
|
-
"astro-api"
|
|
31
|
+
"astro-api",
|
|
32
|
+
"withastro",
|
|
33
|
+
"utils"
|
|
32
34
|
],
|
|
33
35
|
"author": "Alex Mora",
|
|
34
36
|
"license": "MIT",
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
"rollup": "^4.46.2",
|
|
41
43
|
"rollup-plugin-dts": "^6.2.1",
|
|
42
44
|
"typescript": "^5.3.3",
|
|
43
|
-
"undici": "^7.
|
|
45
|
+
"undici": "^7.20.0",
|
|
44
46
|
"vitest": "^3.2.4"
|
|
45
47
|
},
|
|
46
48
|
"engines": {
|