@mxweb/core 1.0.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/dist/application.d.ts +402 -0
  4. package/dist/application.js +1 -0
  5. package/dist/application.mjs +1 -0
  6. package/dist/common.d.ts +323 -0
  7. package/dist/common.js +1 -0
  8. package/dist/common.mjs +1 -0
  9. package/dist/config.d.ts +258 -0
  10. package/dist/config.js +1 -0
  11. package/dist/config.mjs +1 -0
  12. package/dist/context.d.ts +48 -0
  13. package/dist/context.js +1 -0
  14. package/dist/context.mjs +1 -0
  15. package/dist/controller.d.ts +238 -0
  16. package/dist/controller.js +1 -0
  17. package/dist/controller.mjs +1 -0
  18. package/dist/decorator.d.ts +349 -0
  19. package/dist/decorator.js +1 -0
  20. package/dist/decorator.mjs +1 -0
  21. package/dist/error.d.ts +301 -0
  22. package/dist/error.js +1 -0
  23. package/dist/error.mjs +1 -0
  24. package/dist/execute.d.ts +469 -0
  25. package/dist/execute.js +1 -0
  26. package/dist/execute.mjs +1 -0
  27. package/dist/feature.d.ts +239 -0
  28. package/dist/feature.js +1 -0
  29. package/dist/feature.mjs +1 -0
  30. package/dist/hooks.d.ts +251 -0
  31. package/dist/hooks.js +1 -0
  32. package/dist/hooks.mjs +1 -0
  33. package/dist/index.d.ts +14 -0
  34. package/dist/index.js +1 -0
  35. package/dist/index.mjs +1 -0
  36. package/dist/logger.d.ts +360 -0
  37. package/dist/logger.js +1 -0
  38. package/dist/logger.mjs +1 -0
  39. package/dist/response.d.ts +665 -0
  40. package/dist/response.js +1 -0
  41. package/dist/response.mjs +1 -0
  42. package/dist/route.d.ts +298 -0
  43. package/dist/route.js +1 -0
  44. package/dist/route.mjs +1 -0
  45. package/dist/router.d.ts +205 -0
  46. package/dist/router.js +1 -0
  47. package/dist/router.mjs +1 -0
  48. package/dist/service.d.ts +261 -0
  49. package/dist/service.js +1 -0
  50. package/dist/service.mjs +1 -0
  51. package/package.json +168 -0
@@ -0,0 +1,298 @@
1
+ /**
2
+ * @fileoverview Route definition for mapping HTTP methods and paths to handlers.
3
+ *
4
+ * This module provides the `Route` class which represents a single route definition
5
+ * in the application. Routes are created using static factory methods and can include:
6
+ * - HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)
7
+ * - Path pattern with dynamic segments (e.g., "/users/:id")
8
+ * - Handler (controller method name or function)
9
+ * - Decorators (guards, filters, interceptors, pipes)
10
+ * - Middlewares
11
+ *
12
+ * @module route
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { Route, applyDecorators, UseGuards } from "@mxweb/core";
17
+ *
18
+ * // Simple routes
19
+ * Route.get("/users", "findAll")
20
+ * Route.post("/users", "create")
21
+ * Route.get("/users/:id", "findOne")
22
+ *
23
+ * // Route with decorators
24
+ * Route.delete(
25
+ * "/users/:id",
26
+ * "remove",
27
+ * applyDecorators(UseGuards(AuthGuard, AdminGuard))
28
+ * )
29
+ *
30
+ * // Route with inline handler
31
+ * Route.get("/health", async (ctx) => {
32
+ * return ctx.response.success({ status: "ok" });
33
+ * })
34
+ * ```
35
+ */
36
+ import { RouteMethod } from "./common";
37
+ import { DecoratorResult } from "./decorator";
38
+ import { Reflect, RouteHandler, RouteMiddleware } from "./execute";
39
+ /**
40
+ * Represents a single route definition in the application.
41
+ *
42
+ * A Route encapsulates all information needed to match and handle an HTTP request:
43
+ * - The HTTP method (GET, POST, etc.)
44
+ * - The URL path pattern
45
+ * - The handler (controller method name or function)
46
+ * - Route-level guards, filters, interceptors, and pipes
47
+ * - Custom middlewares
48
+ *
49
+ * Routes are created using static factory methods (`get`, `post`, etc.)
50
+ * and are typically grouped together in a Router.
51
+ *
52
+ * @remarks
53
+ * The constructor is private - always use static factory methods to create routes.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * // Creating routes for a product feature
58
+ * const routes = [
59
+ * Route.get("/", "findAll"),
60
+ * Route.get("/:id", "findOne"),
61
+ * Route.post("/", "create", applyDecorators(UseGuards(AuthGuard))),
62
+ * Route.put("/:id", "update", applyDecorators(UseGuards(AuthGuard))),
63
+ * Route.delete("/:id", "remove", applyDecorators(UseGuards(AuthGuard, AdminGuard))),
64
+ * ];
65
+ * ```
66
+ */
67
+ export declare class Route {
68
+ private readonly method;
69
+ private readonly path;
70
+ private readonly action;
71
+ private readonly reflect;
72
+ private readonly middlewares;
73
+ /**
74
+ * Private constructor to enforce factory method usage.
75
+ *
76
+ * @param method - The HTTP method for this route
77
+ * @param path - The URL path pattern (can include dynamic segments like :id)
78
+ * @param action - Controller method name or inline handler function
79
+ * @param reflect - Reflect instance containing guards, filters, interceptors, pipes
80
+ * @param middlewares - Array of middleware functions for this route
81
+ */
82
+ private constructor();
83
+ /**
84
+ * Gets the HTTP method for this route.
85
+ *
86
+ * @returns The RouteMethod enum value
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * const route = Route.get("/users", "findAll");
91
+ * console.log(route.getMethod()); // RouteMethod.GET
92
+ * ```
93
+ */
94
+ getMethod(): RouteMethod;
95
+ /**
96
+ * Gets the URL path pattern for this route.
97
+ *
98
+ * @returns The path string (e.g., "/users/:id")
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const route = Route.get("/users/:id", "findOne");
103
+ * console.log(route.getPath()); // "/users/:id"
104
+ * ```
105
+ */
106
+ getPath(): string;
107
+ /**
108
+ * Gets the action (handler) for this route.
109
+ *
110
+ * @returns The controller method name (string) or handler function
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * const route = Route.get("/users", "findAll");
115
+ * console.log(route.getAction()); // "findAll"
116
+ * ```
117
+ */
118
+ getAction(): string | RouteHandler;
119
+ /**
120
+ * Gets the Reflect instance containing route-level decorators.
121
+ *
122
+ * @returns The Reflect instance with guards, filters, interceptors, pipes, and metadata
123
+ */
124
+ getReflect(): Reflect;
125
+ /**
126
+ * Gets the middleware functions for this route.
127
+ *
128
+ * @returns Array of middleware functions
129
+ */
130
+ getMiddlewares(): RouteMiddleware[];
131
+ /**
132
+ * Normalizes decorator/middleware arguments into a consistent format.
133
+ *
134
+ * This method handles the flexible API where the third parameter can be either
135
+ * a DecoratorResult (from applyDecorators) or a middleware function.
136
+ *
137
+ * @param decoratorsOrMiddleware - Either a DecoratorResult or a middleware function
138
+ * @param middlewares - Additional middleware functions
139
+ * @returns Tuple of [Reflect instance, middlewares array]
140
+ * @internal
141
+ */
142
+ private static normalize;
143
+ /**
144
+ * Creates a route with the specified HTTP method.
145
+ *
146
+ * This is the base factory method used by all HTTP method shortcuts.
147
+ *
148
+ * @param method - The HTTP method
149
+ * @param path - The URL path pattern
150
+ * @param action - Controller method name or handler function
151
+ * @param decoratorsOrMiddleware - Optional decorators or first middleware
152
+ * @param middlewares - Additional middlewares
153
+ * @returns A new Route instance
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * Route.route(RouteMethod.GET, "/custom", "handler")
158
+ * ```
159
+ */
160
+ static route(method: RouteMethod, path: string, action: string | RouteHandler, decoratorsOrMiddleware?: DecoratorResult | RouteMiddleware, middlewares?: RouteMiddleware[]): Route;
161
+ /**
162
+ * Creates a GET route.
163
+ *
164
+ * Used for retrieving resources without side effects.
165
+ *
166
+ * @param path - The URL path pattern
167
+ * @param handle - Controller method name or handler function
168
+ * @param decoratorsOrMiddleware - Optional decorators or first middleware
169
+ * @param middlewares - Additional middlewares
170
+ * @returns A new Route instance for GET requests
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * // Simple GET route
175
+ * Route.get("/users", "findAll")
176
+ *
177
+ * // GET with path parameter
178
+ * Route.get("/users/:id", "findOne")
179
+ *
180
+ * // GET with guards
181
+ * Route.get("/profile", "getProfile", applyDecorators(UseGuards(AuthGuard)))
182
+ *
183
+ * // GET with inline handler
184
+ * Route.get("/ping", async () => ({ pong: true }))
185
+ * ```
186
+ */
187
+ static get(path: string, handle: string | RouteHandler, decoratorsOrMiddleware?: DecoratorResult | RouteMiddleware, ...middlewares: RouteMiddleware[]): Route;
188
+ /**
189
+ * Creates a POST route.
190
+ *
191
+ * Used for creating new resources.
192
+ *
193
+ * @param path - The URL path pattern
194
+ * @param handle - Controller method name or handler function
195
+ * @param decoratorsOrMiddleware - Optional decorators or first middleware
196
+ * @param middlewares - Additional middlewares
197
+ * @returns A new Route instance for POST requests
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * // Create resource
202
+ * Route.post("/users", "create")
203
+ *
204
+ * // With validation pipe
205
+ * Route.post("/users", "create", applyDecorators(UsePipes(ValidationPipe)))
206
+ * ```
207
+ */
208
+ static post(path: string, handle: string | RouteHandler, decoratorsOrMiddleware?: DecoratorResult | RouteMiddleware, ...middlewares: RouteMiddleware[]): Route;
209
+ /**
210
+ * Creates a PUT route.
211
+ *
212
+ * Used for replacing an entire resource.
213
+ *
214
+ * @param path - The URL path pattern
215
+ * @param handle - Controller method name or handler function
216
+ * @param decoratorsOrMiddleware - Optional decorators or first middleware
217
+ * @param middlewares - Additional middlewares
218
+ * @returns A new Route instance for PUT requests
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * // Replace entire resource
223
+ * Route.put("/users/:id", "replace")
224
+ * ```
225
+ */
226
+ static put(path: string, handle: string | RouteHandler, decoratorsOrMiddleware?: DecoratorResult | RouteMiddleware, ...middlewares: RouteMiddleware[]): Route;
227
+ /**
228
+ * Creates a PATCH route.
229
+ *
230
+ * Used for partial updates to a resource.
231
+ *
232
+ * @param path - The URL path pattern
233
+ * @param handle - Controller method name or handler function
234
+ * @param decoratorsOrMiddleware - Optional decorators or first middleware
235
+ * @param middlewares - Additional middlewares
236
+ * @returns A new Route instance for PATCH requests
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * // Partial update
241
+ * Route.patch("/users/:id", "update")
242
+ * ```
243
+ */
244
+ static patch(path: string, handle: string | RouteHandler, decoratorsOrMiddleware?: DecoratorResult | RouteMiddleware, ...middlewares: RouteMiddleware[]): Route;
245
+ /**
246
+ * Creates a DELETE route.
247
+ *
248
+ * Used for removing resources.
249
+ *
250
+ * @param path - The URL path pattern
251
+ * @param handle - Controller method name or handler function
252
+ * @param decoratorsOrMiddleware - Optional decorators or first middleware
253
+ * @param middlewares - Additional middlewares
254
+ * @returns A new Route instance for DELETE requests
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * // Delete resource (usually requires auth)
259
+ * Route.delete("/users/:id", "remove", applyDecorators(UseGuards(AuthGuard)))
260
+ * ```
261
+ */
262
+ static delete(path: string, handle: string | RouteHandler, decoratorsOrMiddleware?: DecoratorResult | RouteMiddleware, ...middlewares: RouteMiddleware[]): Route;
263
+ /**
264
+ * Creates a HEAD route.
265
+ *
266
+ * Used for retrieving headers without body (like GET but without response body).
267
+ *
268
+ * @param path - The URL path pattern
269
+ * @param handle - Controller method name or handler function
270
+ * @param decoratorsOrMiddleware - Optional decorators or first middleware
271
+ * @param middlewares - Additional middlewares
272
+ * @returns A new Route instance for HEAD requests
273
+ *
274
+ * @example
275
+ * ```ts
276
+ * Route.head("/users/:id", "checkExists")
277
+ * ```
278
+ */
279
+ static head(path: string, handle: string | RouteHandler, decoratorsOrMiddleware?: DecoratorResult | RouteMiddleware, ...middlewares: RouteMiddleware[]): Route;
280
+ /**
281
+ * Creates an OPTIONS route.
282
+ *
283
+ * Used for describing available communication options for a resource.
284
+ * Typically handled automatically by CORS middleware.
285
+ *
286
+ * @param path - The URL path pattern
287
+ * @param handle - Controller method name or handler function
288
+ * @param decoratorsOrMiddleware - Optional decorators or first middleware
289
+ * @param middlewares - Additional middlewares
290
+ * @returns A new Route instance for OPTIONS requests
291
+ *
292
+ * @example
293
+ * ```ts
294
+ * Route.options("/users", "corsOptions")
295
+ * ```
296
+ */
297
+ static options(path: string, handle: string | RouteHandler, decoratorsOrMiddleware?: DecoratorResult | RouteMiddleware, ...middlewares: RouteMiddleware[]): Route;
298
+ }
package/dist/route.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var t=require("./common.js"),e=require("./execute.js");class r{constructor(t,e,r,s,i=[]){this.method=t,this.path=e,this.action=r,this.reflect=s,this.middlewares=i}getMethod(){return this.method}getPath(){return this.path}getAction(){return this.action}getReflect(){return this.reflect}getMiddlewares(){return this.middlewares}static normalize(t,r){let s={guards:new Set,filters:new Set,interceptors:new Set,pipes:new Set,metadata:new Map};"function"==typeof t?r.unshift(t):t&&(s=t);return[new e.Reflect(s.metadata,s.guards,s.filters,s.interceptors,s.pipes),r]}static route(t,e,s,i,o=[]){return new r(t,e,s,...this.normalize(i,o))}static get(e,r,s,...i){return this.route(t.RouteMethod.GET,e,r,s,i)}static post(e,r,s,...i){return this.route(t.RouteMethod.POST,e,r,s,i)}static put(e,r,s,...i){return this.route(t.RouteMethod.PUT,e,r,s,i)}static patch(e,r,s,...i){return this.route(t.RouteMethod.PATCH,e,r,s,i)}static delete(e,r,s,...i){return this.route(t.RouteMethod.DELETE,e,r,s,i)}static head(e,r,s,...i){return this.route(t.RouteMethod.HEAD,e,r,s,i)}static options(e,r,s,...i){return this.route(t.RouteMethod.OPTIONS,e,r,s,i)}}exports.Route=r;
package/dist/route.mjs ADDED
@@ -0,0 +1 @@
1
+ import{RouteMethod as t}from"./common.mjs";import{Reflect as e}from"./execute.mjs";class r{constructor(t,e,r,i,s=[]){this.method=t,this.path=e,this.action=r,this.reflect=i,this.middlewares=s}getMethod(){return this.method}getPath(){return this.path}getAction(){return this.action}getReflect(){return this.reflect}getMiddlewares(){return this.middlewares}static normalize(t,r){let i={guards:new Set,filters:new Set,interceptors:new Set,pipes:new Set,metadata:new Map};"function"==typeof t?r.unshift(t):t&&(i=t);return[new e(i.metadata,i.guards,i.filters,i.interceptors,i.pipes),r]}static route(t,e,i,s,n=[]){return new r(t,e,i,...this.normalize(s,n))}static get(e,r,i,...s){return this.route(t.GET,e,r,i,s)}static post(e,r,i,...s){return this.route(t.POST,e,r,i,s)}static put(e,r,i,...s){return this.route(t.PUT,e,r,i,s)}static patch(e,r,i,...s){return this.route(t.PATCH,e,r,i,s)}static delete(e,r,i,...s){return this.route(t.DELETE,e,r,i,s)}static head(e,r,i,...s){return this.route(t.HEAD,e,r,i,s)}static options(e,r,i,...s){return this.route(t.OPTIONS,e,r,i,s)}}export{r as Route};
@@ -0,0 +1,205 @@
1
+ /**
2
+ * @fileoverview Router for registering routes and matching incoming requests.
3
+ *
4
+ * This module provides the `Router` class which manages a collection of routes
5
+ * and matches incoming requests to the appropriate route handler. Features:
6
+ * - Path parameter extraction (e.g., `/users/:id` → `{ id: "123" }`)
7
+ * - Optional parameters (e.g., `/posts/:id?`)
8
+ * - Wildcard patterns (e.g., `/files/*` captures remaining path segments)
9
+ * - HTTP method matching
10
+ *
11
+ * @module router
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { Router, Route } from "@mxweb/core";
16
+ *
17
+ * // Create a router with routes
18
+ * const router = Router.register(
19
+ * Route.get("/", "index"),
20
+ * Route.get("/:id", "findOne"),
21
+ * Route.post("/", "create"),
22
+ * Route.put("/:id", "update"),
23
+ * Route.delete("/:id", "remove"),
24
+ * );
25
+ *
26
+ * // Match a request
27
+ * const matched = router.match(RouteMethod.GET, "/123");
28
+ * // matched = { route: ..., params: { id: "123" }, wildcards: [] }
29
+ * ```
30
+ */
31
+ import { RouteMethod } from "./common";
32
+ import { Route } from "./route";
33
+ /**
34
+ * Result of a successful route match.
35
+ *
36
+ * Contains the matched route, extracted path parameters, and any
37
+ * wildcard segments captured from the URL.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * // For pattern "/users/:id" and path "/users/123"
42
+ * const matched: RouteMatched = {
43
+ * route: Route.get("/users/:id", "findOne"),
44
+ * params: { id: "123" },
45
+ * wildcards: []
46
+ * };
47
+ *
48
+ * // For pattern "/files/*" and path "/files/images/photo.jpg"
49
+ * const matched: RouteMatched = {
50
+ * route: Route.get("/files/*", "serveFile"),
51
+ * params: {},
52
+ * wildcards: ["images", "photo.jpg"]
53
+ * };
54
+ * ```
55
+ */
56
+ export interface RouteMatched {
57
+ /** The matched Route instance */
58
+ route: Route;
59
+ /** Extracted path parameters (e.g., { id: "123" }) */
60
+ params: Record<string, string>;
61
+ /** Wildcard segments captured after a `*` pattern */
62
+ wildcards: string[];
63
+ }
64
+ /**
65
+ * Internal structure for registered routes.
66
+ *
67
+ * @internal
68
+ */
69
+ export interface RouteRegister {
70
+ /** The HTTP method for this route */
71
+ method: RouteMethod;
72
+ /** The Route instance */
73
+ route: Route;
74
+ }
75
+ /**
76
+ * Router for managing and matching HTTP routes.
77
+ *
78
+ * The Router class provides route registration and URL matching capabilities.
79
+ * It supports:
80
+ * - **Path parameters**: `/users/:id` extracts `id` from the URL
81
+ * - **Optional parameters**: `/posts/:id?` makes `id` optional
82
+ * - **Wildcards**: `/files/*` captures all remaining segments
83
+ * - **Literal segments**: `/api/v1/users` matches exactly
84
+ *
85
+ * @remarks
86
+ * The constructor is private - use `Router.register()` to create instances.
87
+ * Each Feature typically has one Router that groups related routes.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * // Product feature router
92
+ * export const productRouter = Router.register(
93
+ * Route.get("/", "findAll"),
94
+ * Route.get("/:id", "findOne"),
95
+ * Route.post("/", "create", applyDecorators(UseGuards(AuthGuard))),
96
+ * Route.patch("/:id", "update", applyDecorators(UseGuards(AuthGuard))),
97
+ * Route.delete("/:id", "remove", applyDecorators(UseGuards(AuthGuard, AdminGuard))),
98
+ * );
99
+ *
100
+ * // Feature with router
101
+ * export const productFeature = Feature.create({
102
+ * path: "/products",
103
+ * controller: ProductController,
104
+ * router: productRouter,
105
+ * });
106
+ * ```
107
+ */
108
+ export declare class Router {
109
+ private readonly registered;
110
+ /**
111
+ * Private constructor to enforce factory method usage.
112
+ *
113
+ * @param registered - Set of registered routes
114
+ */
115
+ private constructor();
116
+ /**
117
+ * Creates a new Router with the specified routes.
118
+ *
119
+ * This is the primary way to create a Router instance. Routes are
120
+ * registered in order and will be matched in that order.
121
+ *
122
+ * @param routes - One or more Route instances to register
123
+ * @returns A new Router instance
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * const router = Router.register(
128
+ * Route.get("/", "index"),
129
+ * Route.get("/search", "search"),
130
+ * Route.get("/:id", "findOne"),
131
+ * Route.post("/", "create"),
132
+ * );
133
+ * ```
134
+ */
135
+ static register(...routes: Route[]): Router;
136
+ /**
137
+ * Matches an incoming request to a registered route.
138
+ *
139
+ * Iterates through registered routes in order and returns the first
140
+ * match. If no route matches, returns `null`.
141
+ *
142
+ * @param method - The HTTP method of the request
143
+ * @param path - The URL path to match (e.g., "/users/123")
144
+ * @returns RouteMatched object if found, null otherwise
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * const router = Router.register(
149
+ * Route.get("/:id", "findOne"),
150
+ * );
151
+ *
152
+ * const matched = router.match(RouteMethod.GET, "/456");
153
+ * if (matched) {
154
+ * console.log(matched.params.id); // "456"
155
+ * console.log(matched.route.getAction()); // "findOne"
156
+ * }
157
+ * ```
158
+ */
159
+ match(method: RouteMethod, path: string): {
160
+ route: Route;
161
+ params: Record<string, string>;
162
+ wildcards: string[];
163
+ } | null;
164
+ /**
165
+ * Matches a URL path against a route pattern.
166
+ *
167
+ * This static method performs the actual pattern matching logic.
168
+ * It supports:
169
+ * - **Literal segments**: Must match exactly
170
+ * - **Path parameters**: `:param` captures a single segment
171
+ * - **Optional parameters**: `:param?` matches zero or one segment
172
+ * - **Wildcards**: `*` at the end captures all remaining segments
173
+ *
174
+ * @param pattern - The route pattern (e.g., "/users/:id")
175
+ * @param target - The actual URL path (e.g., "/users/123")
176
+ * @returns Object with params and wildcards if matched, null otherwise
177
+ *
178
+ * @example
179
+ * ```ts
180
+ * // Basic parameter
181
+ * Router.match("/users/:id", "/users/123");
182
+ * // { params: { id: "123" }, wildcards: [] }
183
+ *
184
+ * // Optional parameter (present)
185
+ * Router.match("/posts/:id?", "/posts/456");
186
+ * // { params: { id: "456" }, wildcards: [] }
187
+ *
188
+ * // Optional parameter (absent)
189
+ * Router.match("/posts/:id?", "/posts");
190
+ * // { params: { id: "" }, wildcards: [] }
191
+ *
192
+ * // Wildcard
193
+ * Router.match("/files/*", "/files/docs/readme.md");
194
+ * // { params: {}, wildcards: ["docs", "readme.md"] }
195
+ *
196
+ * // No match
197
+ * Router.match("/users/:id", "/products/123");
198
+ * // null
199
+ * ```
200
+ */
201
+ static match(pattern: string, target: string): {
202
+ params: Record<string, string>;
203
+ wildcards: string[];
204
+ } | null;
205
+ }
package/dist/router.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";class t{constructor(t){this.registered=t}static register(...e){return new t(new Set(e.map(t=>({method:t.getMethod(),route:t}))))}match(e,r){const s=this.registered;for(const n of s){if(n.method!==e)continue;const s=t.match(n.route.getPath(),r);if(s)return{route:n.route,params:s.params,wildcards:s.wildcards}}return null}static match(t,e){const r=t.trim().replace(/^\/+/,"").replace(/\/+$/,""),s=e.trim().replace(/^\/+/,"").replace(/\/+$/,""),n=r.split("/"),i=s.split("/"),l={},c=[],o="*"===n[n.length-1],h=o?n.slice(0,-1):n;let a=0;for(const t of h)t.startsWith(":")&&t.endsWith("?")||a++;if(o){if(i.length<a)return null}else if(i.length<a||i.length>n.length)return null;let u=0;for(let t=0;t<h.length;t++){const e=h[t],r=i[u];if(e.startsWith(":")){let s=e.substring(1);const n=s.endsWith("?");if(n&&(s=s.slice(0,-1)),void 0!==r){if(n&&t+1<h.length){const e=h[t+1];if(!e.startsWith(":")&&e===r){l[s]="";continue}if(e.startsWith(":")){const e=i.length-u;let r=0;for(let e=t;e<h.length;e++){const t=h[e];t.startsWith(":")&&t.endsWith("?")||r++}if(e===r){l[s]="";continue}}}l[s]=r,u++}else{if(!n)return null;l[s]=""}}else{if(e!==r)return null;u++}}return o&&c.push(...i.slice(h.length)),{params:l,wildcards:c}}}exports.Router=t;
@@ -0,0 +1 @@
1
+ class t{constructor(t){this.registered=t}static register(...e){return new t(new Set(e.map(t=>({method:t.getMethod(),route:t}))))}match(e,r){const s=this.registered;for(const n of s){if(n.method!==e)continue;const s=t.match(n.route.getPath(),r);if(s)return{route:n.route,params:s.params,wildcards:s.wildcards}}return null}static match(t,e){const r=t.trim().replace(/^\/+/,"").replace(/\/+$/,""),s=e.trim().replace(/^\/+/,"").replace(/\/+$/,""),n=r.split("/"),i=s.split("/"),l={},c=[],o="*"===n[n.length-1],h=o?n.slice(0,-1):n;let a=0;for(const t of h)t.startsWith(":")&&t.endsWith("?")||a++;if(o){if(i.length<a)return null}else if(i.length<a||i.length>n.length)return null;let u=0;for(let t=0;t<h.length;t++){const e=h[t],r=i[u];if(e.startsWith(":")){let s=e.substring(1);const n=s.endsWith("?");if(n&&(s=s.slice(0,-1)),void 0!==r){if(n&&t+1<h.length){const e=h[t+1];if(!e.startsWith(":")&&e===r){l[s]="";continue}if(e.startsWith(":")){const e=i.length-u;let r=0;for(let e=t;e<h.length;e++){const t=h[e];t.startsWith(":")&&t.endsWith("?")||r++}if(e===r){l[s]="";continue}}}l[s]=r,u++}else{if(!n)return null;l[s]=""}}else{if(e!==r)return null;u++}}return o&&c.push(...i.slice(h.length)),{params:l,wildcards:c}}}export{t as Router};