tezx 2.0.6 → 2.0.8

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/core/router.d.ts CHANGED
@@ -6,6 +6,7 @@ export type NextCallback = () => Promise<any>;
6
6
  export type CallbackReturn = Promise<Response> | Response;
7
7
  export type Callback<T extends Record<string, any> = {}> = (ctx: ctx<T>) => CallbackReturn;
8
8
  export type Middleware<T extends Record<string, any> = {}> = (ctx: ctx<T>, next: NextCallback) => Promise<Response | void> | Response | NextCallback;
9
+ export type PathType = string | RegExp;
9
10
  export type RouterConfig = {
10
11
  /**
11
12
  * `env` allows you to define environment variables for the router.
@@ -36,6 +37,8 @@ export type StaticServeOption = {
36
37
  };
37
38
  export type RouterHandler<T extends Record<string, any>> = {
38
39
  callback: Callback<T>;
40
+ paramNames: string[];
41
+ regex: RegExp;
39
42
  middlewares: UniqueMiddlewares | DuplicateMiddlewares;
40
43
  };
41
44
  export declare class Router<T extends Record<string, any> = {}> extends MiddlewareConfigure<T> {
@@ -72,13 +75,14 @@ export declare class Router<T extends Record<string, any> = {}> extends Middlewa
72
75
  *
73
76
  * // With middleware
74
77
  * app.get('/secure', authMiddleware, (ctx) => { ... });
78
+ * app.get(/^\/item\/(\d+)\/(edit|view)?\/?$/, (ctx) => { ... });
75
79
  *
76
80
  * // With multiple middlewares
77
81
  * app.get('/admin', [authMiddleware, adminMiddleware], (ctx) => { ... });
78
82
  */
79
- get(path: string, callback: Callback<T>): this;
80
- get(path: string, middleware: Middleware<T>, callback: Callback<T>): this;
81
- get(path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
83
+ get(path: PathType, callback: Callback<T>): this;
84
+ get(path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
85
+ get(path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
82
86
  /**
83
87
  * Registers a Server-Sent Events (SSE) route handler for the given path.
84
88
  *
@@ -108,66 +112,66 @@ export declare class Router<T extends Record<string, any> = {}> extends Middlewa
108
112
  * });
109
113
  * ```
110
114
  *
111
- * @param {string} path - The route path for SSE (e.g. `/events`).
115
+ * @param {PathType} path - The route path for SSE (e.g. `/events`).
112
116
  * @param {(ctx: Context) => any} handler - A handler function that returns a streamed response.
113
117
  */
114
- sse(path: string, handler: (ctx: Context) => any): void;
118
+ sse(path: PathType, handler: (ctx: Context) => any): void;
115
119
  /**
116
120
  * Registers a POST route with optional middleware(s)
117
121
  * @param path - URL path pattern
118
122
  * @param args - Handler callback or middleware(s) + handler
119
123
  */
120
- post(path: string, callback: Callback<T>): this;
121
- post(path: string, middleware: Middleware<T>, callback: Callback<T>): this;
122
- post(path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
124
+ post(path: PathType, callback: Callback<T>): this;
125
+ post(path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
126
+ post(path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
123
127
  /**
124
128
  * Registers a PUT route with optional middleware(s)
125
129
  * @param path - URL path pattern
126
130
  * @param args - Handler callback or middleware(s) + handler
127
131
  */
128
- put(path: string, callback: Callback<T>): this;
129
- put(path: string, middleware: Middleware<T>, callback: Callback<T>): this;
130
- put(path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
132
+ put(path: PathType, callback: Callback<T>): this;
133
+ put(path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
134
+ put(path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
131
135
  /**
132
136
  * Registers a PATCH route with optional middleware(s)
133
137
  * @param path - URL path pattern
134
138
  * @param args - Handler callback or middleware(s) + handler
135
139
  */
136
- patch(path: string, callback: Callback<T>): this;
137
- patch(path: string, middleware: Middleware<T>, callback: Callback<T>): this;
138
- patch(path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
140
+ patch(path: PathType, callback: Callback<T>): this;
141
+ patch(path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
142
+ patch(path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
139
143
  /**
140
144
  * Registers a DELETE route with optional middleware(s)
141
145
  * @param path - URL path pattern
142
146
  * @param args - Handler callback or middleware(s) + handler
143
147
  */
144
- delete(path: string, callback: Callback<T>): this;
145
- delete(path: string, middleware: Middleware<T>, callback: Callback<T>): this;
146
- delete(path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
148
+ delete(path: PathType, callback: Callback<T>): this;
149
+ delete(path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
150
+ delete(path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
147
151
  /**
148
152
  * Registers an OPTIONS route (primarily for CORS preflight requests)
149
153
  * @param path - URL path pattern
150
154
  * @param args - Handler callback or middleware(s) + handler
151
155
  */
152
- options(path: string, callback: Callback<T>): this;
153
- options(path: string, middleware: Middleware<T>, callback: Callback<T>): this;
154
- options(path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
156
+ options(path: PathType, callback: Callback<T>): this;
157
+ options(path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
158
+ options(path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
155
159
  /**
156
160
  * Registers a HEAD route (returns headers only)
157
161
  * @param path - URL path pattern
158
162
  * @param args - Handler callback or middleware(s) + handler
159
163
  */
160
- head(path: string, callback: Callback<T>): this;
161
- head(path: string, middleware: Middleware<T>, callback: Callback<T>): this;
162
- head(path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
164
+ head(path: PathType, callback: Callback<T>): this;
165
+ head(path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
166
+ head(path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
163
167
  /**
164
168
  * Registers a route that responds to all HTTP methods
165
169
  * @param path - URL path pattern
166
170
  * @param args - Handler callback or middleware(s) + handler
167
171
  */
168
- all(path: string, callback: Callback<T>): this;
169
- all(path: string, middleware: Middleware<T>, callback: Callback<T>): this;
170
- all(path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
172
+ all(path: PathType, callback: Callback<T>): this;
173
+ all(path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
174
+ all(path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
171
175
  /**
172
176
  * Generic method registration for custom HTTP methods
173
177
  * @param method - HTTP method name (e.g., 'PURGE')
@@ -178,10 +182,10 @@ export declare class Router<T extends Record<string, any> = {}> extends Middlewa
178
182
  * // Register custom method
179
183
  * server.addRoute('PURGE', '/cache', purgeHandler);
180
184
  */
181
- addRoute(method: HTTPMethod, path: string, callback: Callback<T>): this;
182
- addRoute(method: HTTPMethod, path: string, middleware: Middleware<T>): this;
183
- addRoute(method: HTTPMethod, path: string, middleware: Middleware<T>, callback: Callback<T>): this;
184
- addRoute(method: HTTPMethod, path: string, middlewares: Middleware<T>[], callback: Callback<T>): this;
185
+ addRoute(method: HTTPMethod, path: PathType, callback: Callback<T>): this;
186
+ addRoute(method: HTTPMethod, path: PathType, middleware: Middleware<T>): this;
187
+ addRoute(method: HTTPMethod, path: PathType, middleware: Middleware<T>, callback: Callback<T>): this;
188
+ addRoute(method: HTTPMethod, path: PathType, middlewares: Middleware<T>[], callback: Callback<T>): this;
185
189
  /**
186
190
  * Mount a sub-router at specific path prefix
187
191
  * @param path - Base path for the sub-router
package/core/router.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { addBaseToRegex, compileRegexRoute } from "../utils/regexRouter.js";
1
2
  import { getFiles } from "../utils/staticFile.js";
2
3
  import { sanitizePathSplit, wildcardOrOptionalParamRegex, } from "../utils/url.js";
3
4
  import { GlobalConfig } from "./config.js";
@@ -191,25 +192,57 @@ export class Router extends MiddlewareConfigure {
191
192
  this.#addRoute(method, path, callback, middlewares);
192
193
  }
193
194
  #addRoute(method, path, callback, middlewares) {
194
- const parts = sanitizePathSplit(this.basePath, path);
195
195
  let finalMiddleware = middlewares;
196
196
  if (!GlobalConfig.allowDuplicateMw) {
197
197
  finalMiddleware = new Set(middlewares);
198
198
  }
199
+ if (path instanceof RegExp) {
200
+ let regex = addBaseToRegex(this.basePath, path);
201
+ let regexPath = `regex://${regex?.source}`;
202
+ let handler = this.routers.get(regexPath);
203
+ if (!handler) {
204
+ handler = new Map();
205
+ handler.set(method, {
206
+ callback: callback,
207
+ paramNames: [],
208
+ regex: regex,
209
+ middlewares: finalMiddleware,
210
+ });
211
+ return this.routers.set(regexPath, handler);
212
+ }
213
+ if (!GlobalConfig.overwriteMethod && handler.has(method))
214
+ return;
215
+ return handler.set(method, {
216
+ callback,
217
+ paramNames: [],
218
+ regex: regex,
219
+ middlewares: finalMiddleware
220
+ });
221
+ }
222
+ const parts = sanitizePathSplit(this.basePath, path);
199
223
  let p = parts.join("/");
200
224
  if (wildcardOrOptionalParamRegex.test(`/${p}`)) {
201
- let handler = this.routers.get(p);
225
+ let strPath = `string://${p}`;
226
+ let { paramNames, regex } = compileRegexRoute(parts);
227
+ let handler = this.routers.get(strPath);
202
228
  if (!handler) {
203
229
  handler = new Map();
204
230
  handler.set(method, {
205
231
  callback: callback,
232
+ regex: regex,
233
+ paramNames: paramNames,
206
234
  middlewares: finalMiddleware,
207
235
  });
208
- return this.routers.set(p, handler);
236
+ return this.routers.set(strPath, handler);
209
237
  }
210
238
  if (!GlobalConfig.overwriteMethod && handler.has(method))
211
239
  return;
212
- return handler.set(method, { callback, middlewares: finalMiddleware });
240
+ return handler.set(method, {
241
+ callback,
242
+ regex: regex,
243
+ paramNames: paramNames,
244
+ middlewares: finalMiddleware
245
+ });
213
246
  }
214
247
  let node = this.triRouter;
215
248
  for (const part of parts) {
@@ -249,17 +282,62 @@ export class Router extends MiddlewareConfigure {
249
282
  const parts = sanitizePathSplit(this.basePath, path);
250
283
  if (router.routers.size) {
251
284
  for (const [segment, handlers] of router.routers) {
252
- let path = parts.length ? parts.join("/") + "/" + segment : segment;
253
- if (this.routers.has(path)) {
254
- const baseRouter = this.routers.get(path);
255
- for (const [method, handler] of handlers) {
256
- if (!GlobalConfig.overwriteMethod && baseRouter.has(method))
257
- return;
258
- baseRouter.set(method, handler);
285
+ if (segment.indexOf("string://") == 0) {
286
+ let pattern = segment.replace(/^string:\/\//, "");
287
+ let joined = [...parts, pattern].join("/");
288
+ let strPath = `string://${joined}`;
289
+ if (this.routers.has(strPath)) {
290
+ const baseRouter = this.routers.get(strPath);
291
+ for (const [method, handler] of handlers) {
292
+ let { regex, paramNames } = baseRouter?.get(method);
293
+ handler.regex = regex;
294
+ handler.paramNames = paramNames;
295
+ if (!GlobalConfig.overwriteMethod && baseRouter.has(method))
296
+ continue;
297
+ baseRouter.set(method, handler);
298
+ }
299
+ }
300
+ else {
301
+ let h = new Map();
302
+ for (const [method, { callback, middlewares }] of handlers) {
303
+ let { paramNames, regex } = compileRegexRoute(joined);
304
+ h.set(method, {
305
+ callback: callback,
306
+ middlewares: middlewares,
307
+ paramNames,
308
+ regex
309
+ });
310
+ }
311
+ this.routers.set(strPath, h);
259
312
  }
260
313
  }
261
314
  else {
262
- this.routers.set(path, new Map(handlers));
315
+ let pattern = segment.replace("regex://", "");
316
+ let base = parts?.join("/");
317
+ let regex = addBaseToRegex(base, new RegExp(pattern));
318
+ let regexPath = `regex://${regex.source}`;
319
+ if (this.routers.has(regexPath)) {
320
+ const baseRouter = this.routers.get(regexPath);
321
+ for (const [method, handler] of handlers) {
322
+ handler.regex = regex;
323
+ handler.paramNames = [];
324
+ if (!GlobalConfig.overwriteMethod && baseRouter.has(method))
325
+ continue;
326
+ baseRouter.set(method, handler);
327
+ }
328
+ }
329
+ else {
330
+ let h = new Map();
331
+ for (const [method, { callback, middlewares }] of handlers) {
332
+ h.set(method, {
333
+ callback: callback,
334
+ middlewares: middlewares,
335
+ paramNames: [],
336
+ regex
337
+ });
338
+ }
339
+ this.routers.set(regexPath, h);
340
+ }
263
341
  }
264
342
  }
265
343
  }
package/core/server.d.ts CHANGED
@@ -62,7 +62,7 @@ export declare class TezX<T extends Record<string, any> = {}> extends Router<T>
62
62
  protected findRoute(method: HTTPMethod, pathname: string): {
63
63
  callback: any;
64
64
  middlewares: Middleware<T>[];
65
- params: Record<string, string>;
65
+ params: Record<string, null | string>;
66
66
  } | null;
67
67
  serve(req: Request, options: TezXServeOptions): Promise<Response | {
68
68
  websocket: (props: any) => any;
package/core/server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { colorText } from "../utils/colors.js";
2
2
  import { httpStatusMap } from "../utils/httpStatusMap.js";
3
- import { useParams } from "../utils/params.js";
3
+ import { regexMatchRoute } from "../utils/regexRouter.js";
4
4
  import { GlobalConfig } from "./config.js";
5
5
  import { Context } from "./context.js";
6
6
  import { Router } from "./router.js";
@@ -16,18 +16,14 @@ export class TezX extends Router {
16
16
  this.#onPathResolve = onPathResolve;
17
17
  this.serve = this.serve.bind(this);
18
18
  }
19
- #hashRouter(method, pathname) {
20
- const routers = this.routers;
21
- for (let pattern of this.routers.keys()) {
22
- const { success, params } = useParams({
23
- path: pathname,
24
- urlPattern: pattern,
25
- });
26
- const handlers = routers.get(pattern)?.get(method) || routers.get(pattern)?.get("ALL");
27
- if (success && handlers) {
19
+ #regexRouter(method, pathname) {
20
+ for (let pattern of this.routers.values()) {
21
+ const handler = pattern?.get(method) || pattern?.get("ALL");
22
+ const { success, params } = regexMatchRoute(handler?.regex, pathname, handler?.paramNames || []);
23
+ if (success && handler) {
28
24
  return {
29
- callback: handlers.callback,
30
- middlewares: handlers.middlewares,
25
+ callback: handler.callback,
26
+ middlewares: handler.middlewares,
31
27
  params: params,
32
28
  };
33
29
  }
@@ -83,7 +79,7 @@ export class TezX extends Router {
83
79
  }
84
80
  findRoute(method, pathname) {
85
81
  const route = this.#triRouter(method, pathname) ||
86
- this.#hashRouter(method, pathname) ||
82
+ this.#regexRouter(method, pathname) ||
87
83
  this.#triRouter(method, pathname, "param");
88
84
  if (route) {
89
85
  return {
package/helper/index.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { Environment } from "../core/environment.js";
2
2
  import { sanitizePathSplit } from "../utils/url.js";
3
3
  import { generateID } from "./common.js";
4
- export { AdapterType, GlobalConfig } from "../core/config.js";
4
+ export { GlobalConfig } from "../core/config.js";
5
+ export type { AdapterType } from "../core/config.js";
5
6
  export { Environment } from "../core/environment.js";
6
- export { sanitizePathSplit, UrlRef } from "../utils/url.js";
7
+ export { sanitizePathSplit } from "../utils/url.js";
8
+ export type { UrlRef } from "../utils/url.js";
7
9
  export { generateID } from "./common.js";
8
10
  declare const _default: {
9
11
  Environment: typeof Environment;
package/index.d.ts CHANGED
@@ -1,20 +1,21 @@
1
1
  import { Router } from "./core/router.js";
2
2
  import { TezX } from "./core/server.js";
3
- import { useParams } from "./utils/params.js";
3
+ import { regexMatchRoute, compileRegexRoute } from "./utils/regexRouter.js";
4
4
  export { Router } from "./core/router.js";
5
- export type { Callback, ctx as Context, Middleware, NextCallback, RouterConfig, StaticServeOption } from "./core/router.js";
5
+ export type { Callback, ctx as Context, Middleware, NextCallback, RouterConfig, PathType, StaticServeOption } from "./core/router.js";
6
6
  export type { AdapterType } from "./core/config.js";
7
7
  export type { CookieOptions, ResponseHeaders } from "./core/context.js";
8
8
  export type { NetAddr as AddressType, ConnAddress, FormDataOptions, HTTPMethod } from "./core/request.js";
9
9
  export { TezX } from "./core/server.js";
10
10
  export type { TezXConfig, TezXServeOptions } from "./core/server.js";
11
11
  export type { UrlRef } from "./utils/url.js";
12
- export { useParams };
12
+ export { regexMatchRoute, compileRegexRoute };
13
13
  export declare let version: string;
14
14
  declare const _default: {
15
15
  Router: typeof Router;
16
+ regexMatchRoute: typeof regexMatchRoute;
17
+ compileRegexRoute: typeof compileRegexRoute;
16
18
  TezX: typeof TezX;
17
- useParams: typeof useParams;
18
19
  version: string;
19
20
  };
20
21
  export default _default;
package/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { Router } from "./core/router.js";
2
2
  import { TezX } from "./core/server.js";
3
- import { useParams } from "./utils/params.js";
3
+ import { regexMatchRoute, compileRegexRoute } from "./utils/regexRouter.js";
4
4
  export { Router } from "./core/router.js";
5
5
  export { TezX } from "./core/server.js";
6
- export { useParams };
7
- export let version = "2.0.6";
6
+ export { regexMatchRoute, compileRegexRoute };
7
+ export let version = "2.0.8";
8
8
  export default {
9
9
  Router,
10
+ regexMatchRoute, compileRegexRoute,
10
11
  TezX,
11
- useParams,
12
12
  version,
13
13
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tezx",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "description": "TezX is a high-performance, lightweight JavaScript framework designed for speed, scalability, and flexibility. It enables efficient routing, middleware management, and static file serving with minimal configuration. Fully compatible with Node.js, Deno, and Bun.",
5
5
  "main": "cjs/index.js",
6
6
  "module": "index.js",
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Compiles a route string or segment array into a regular expression for matching URL paths.
3
+ * Supports dynamic `:param`, optional `:param?`, and wildcard `*param` segments.
4
+ *
5
+ * @param {string | string[]} seg - The route pattern, either as a string (`'/user/:id'`)
6
+ * or an array of segments (`['user', ':id']`).
7
+ *
8
+ * @returns {{
9
+ * regex: RegExp,
10
+ * paramNames: string[]
11
+ * }}
12
+ * @example
13
+ * const { regex, paramNames } = compileRegexRoute('/user/:id/post/:slug?');
14
+ * // regex: /^\/user\/([^\/]+)\/(?:([^\/]+))?\/?$/
15
+ * // paramNames: ['id', 'slug']
16
+ *
17
+ * regex.test('/user/123/post/hello'); // ✅ true
18
+ * regex.test('/user/123/post'); // ✅ true (because :slug? is optional)
19
+ *
20
+ * @example
21
+ * const { regex, paramNames } = compileRegexRoute('/files/*path');
22
+ * // regex: /^\/files\/(.+)\/?$/
23
+ * // paramNames: ['path']
24
+ *
25
+ * regex.test('/files/images/cat.jpg'); // ✅ true
26
+ */
27
+ export declare function compileRegexRoute(seg: string | string[]): {
28
+ regex: RegExp;
29
+ paramNames: string[];
30
+ };
31
+ /**
32
+ * Combines a base path with a route regex pattern.
33
+ *
34
+ * @param basePath - The base path to prepend (e.g., '/api/v1')
35
+ * @param routeRegex - The original route regex (e.g., /^\/users\/([^/]+?)$/)
36
+ * @returns A new regex that includes the base path
37
+ */
38
+ export declare function addBaseToRegex(basePath: string, routeRegex: RegExp): RegExp;
39
+ /**
40
+ * Matches a given URL against a provided regular expression and extracts named parameters.
41
+ *
42
+ * @param {RegExp} regex - The regular expression to match against the URL.
43
+ * It should include capturing groups for each parameter.
44
+ * Example: /^\/user\/(\d+)\/post\/(\w+)$/
45
+ *
46
+ * @param {string} url - The URL string to match.
47
+ * Example: "/user/123/post/abc"
48
+ *
49
+ * @param {string[]} paramNames - An array of parameter names corresponding to the capturing groups in the regex.
50
+ * Example: ["userId", "postId"]
51
+ *
52
+ * @returns {{ success: boolean, params: Record<string, string | null> }} An object indicating:
53
+ * - `success`: whether the URL matched the regex.
54
+ * - `params`: an object mapping parameter names to their matched values, or `null` if not found.
55
+ *
56
+ * @example
57
+ * const regex = /^\/user\/(\d+)\/post\/(\w+)$/;
58
+ * const url = "/user/123/post/abc";
59
+ * const paramNames = ["userId", "postId"];
60
+ * const result = regexMatchRoute(regex, url, paramNames);
61
+ * // result = { success: true, params: { userId: "123", postId: "abc" } }
62
+ */
63
+ export declare function regexMatchRoute(regex: RegExp, url: string, paramNames: string[]): {
64
+ params: Record<string, string | null>;
65
+ success: boolean;
66
+ };
@@ -0,0 +1,53 @@
1
+ import { sanitizePathSplit } from "./url.js";
2
+ export function compileRegexRoute(seg) {
3
+ const segments = typeof seg == 'string' ? seg.split("/").filter(Boolean) : seg;
4
+ let regexStr = "^";
5
+ const paramNames = [];
6
+ for (let seg of segments) {
7
+ if (seg.startsWith(":")) {
8
+ const isOptional = seg.endsWith("?");
9
+ const name = seg.replace(":", "").replace("?", "");
10
+ paramNames.push(name);
11
+ regexStr += isOptional
12
+ ? `(?:\\/([^\\/]+))?`
13
+ : `\\/([^\\/]+)`;
14
+ }
15
+ else if (seg.startsWith("*")) {
16
+ const name = seg.slice(1) || "*";
17
+ paramNames.push(name);
18
+ regexStr += `\\/(.+)`;
19
+ }
20
+ else {
21
+ regexStr += `\\/${seg}`;
22
+ }
23
+ }
24
+ regexStr += "\\/?$";
25
+ return {
26
+ regex: new RegExp(regexStr),
27
+ paramNames,
28
+ };
29
+ }
30
+ export function addBaseToRegex(basePath, routeRegex) {
31
+ basePath = "/" + sanitizePathSplit("/", basePath)?.join("/");
32
+ if (basePath === "/")
33
+ basePath = "";
34
+ let body = routeRegex.source.replace(/^(\^)/, '').replace(/(\$)$/, '');
35
+ body = body.replace(/\\\//g, "/");
36
+ if (body.startsWith("/")) {
37
+ body = body.slice(1);
38
+ }
39
+ const cleaned = body.replace(/^\/+|\/+$/g, "").replace(/\/?\?$/, "");
40
+ const combined = basePath + "/" + cleaned + "/?";
41
+ const finalRegex = new RegExp(`^${combined}$`);
42
+ return finalRegex;
43
+ }
44
+ export function regexMatchRoute(regex, url, paramNames) {
45
+ const match = url.match(regex);
46
+ if (!match)
47
+ return { success: false, params: {} };
48
+ const params = {};
49
+ paramNames.forEach((name, idx) => {
50
+ params[name] = match[idx + 1] ?? null;
51
+ });
52
+ return { params, success: true };
53
+ }
@@ -1,94 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useParams = useParams;
4
- function useParams({ path, urlPattern, }) {
5
- let params = {};
6
- path = path.replace(/^\/+|\/+$/g, "");
7
- urlPattern = urlPattern.replace(/^\/+|\/+$/g, "");
8
- const pathSegments = path ? path.split("/") : [];
9
- const patternSegments = urlPattern ? urlPattern.split("/") : [];
10
- const pathLength = pathSegments.length;
11
- const patternLength = patternSegments.length;
12
- if (pathLength > patternLength && !urlPattern.includes("*")) {
13
- return { success: false, params: {} };
14
- }
15
- let pathIndex = 0;
16
- for (let i = 0; i < patternLength; i++) {
17
- const patternSegment = patternSegments[i];
18
- if (patternSegment?.startsWith("*")) {
19
- const trailingPatterns = patternSegments.slice(i + 1);
20
- let paramName = patternSegment.length == 1 ? "*" : patternSegment?.slice(1);
21
- if (trailingPatterns.length > 0) {
22
- const expectedTrailing = trailingPatterns.join("/");
23
- const actualTrailing = pathSegments
24
- .slice(pathLength - trailingPatterns.length)
25
- .join("/");
26
- const wildcardPath = pathSegments
27
- .slice(pathIndex, pathLength - trailingPatterns.length)
28
- .join("/");
29
- if (expectedTrailing !== actualTrailing || !wildcardPath) {
30
- return { success: false, params: {} };
31
- }
32
- params[paramName] = wildcardPath;
33
- return { success: true, params };
34
- }
35
- else {
36
- const wildcardPath = pathSegments.slice(pathIndex).join("/");
37
- if (!wildcardPath) {
38
- return { success: false, params: {} };
39
- }
40
- params[paramName] = wildcardPath;
41
- return { success: true, params };
42
- }
43
- }
44
- if (patternSegment.startsWith(":") && patternSegment.endsWith("?")) {
45
- const paramName = patternSegment.slice(1, -1);
46
- const nextPattern = patternSegments[i + 1];
47
- if (nextPattern &&
48
- !nextPattern.startsWith(":") &&
49
- nextPattern !== "*" &&
50
- pathIndex < pathLength &&
51
- pathSegments[pathIndex] === nextPattern) {
52
- params[paramName] = null;
53
- continue;
54
- }
55
- const remainingPatterns = patternSegments.slice(i + 1);
56
- const requiredCount = remainingPatterns.filter((seg) => !(seg.startsWith(":") && seg.endsWith("?"))).length;
57
- const remainingPath = pathLength - pathIndex;
58
- if (remainingPath === requiredCount) {
59
- params[paramName] = null;
60
- }
61
- else if (pathIndex < pathLength) {
62
- params[paramName] = pathSegments[pathIndex];
63
- pathIndex++;
64
- }
65
- else {
66
- params[paramName] = null;
67
- }
68
- continue;
69
- }
70
- if (patternSegment.startsWith(":")) {
71
- const paramName = patternSegment.slice(1);
72
- if (!/^[a-zA-Z0-9_]+$/.test(paramName)) {
73
- return { success: false, params: {} };
74
- }
75
- if (pathIndex < pathLength) {
76
- params[paramName] = pathSegments[pathIndex];
77
- pathIndex++;
78
- }
79
- else {
80
- return { success: false, params: {} };
81
- }
82
- continue;
83
- }
84
- const pathSegment = pathSegments[pathIndex];
85
- if (patternSegment !== pathSegment) {
86
- return { success: false, params: {} };
87
- }
88
- pathIndex++;
89
- }
90
- if (pathIndex < pathLength) {
91
- return { success: false, params: {} };
92
- }
93
- return { success: true, params };
94
- }
package/utils/params.d.ts DELETED
@@ -1,7 +0,0 @@
1
- export declare function useParams({ path, urlPattern, }: {
2
- path: string;
3
- urlPattern: string;
4
- }): {
5
- success: boolean;
6
- params: Record<string, any>;
7
- };