azurajs 2.1.2 → 2.2.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 +244 -7
- package/dist/LoggingMiddleware-BQKJUBqT.d.ts +6 -0
- package/dist/LoggingMiddleware-CYNvypha.d.cts +6 -0
- package/dist/Server-Ba-EFdi2.d.ts +53 -0
- package/dist/Server-CY3k1FIL.d.cts +53 -0
- package/dist/common.type-BoV71o_C.d.ts +11 -0
- package/dist/common.type-Ct06XeYQ.d.cts +11 -0
- package/dist/config.cjs +89 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +51 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.js +83 -0
- package/dist/config.js.map +1 -0
- package/dist/cookies.cjs +32 -0
- package/dist/cookies.cjs.map +1 -0
- package/dist/cookies.d.cts +8 -0
- package/dist/cookies.d.ts +8 -0
- package/dist/cookies.js +29 -0
- package/dist/cookies.js.map +1 -0
- package/dist/cors.cjs +29 -0
- package/dist/cors.cjs.map +1 -0
- package/dist/cors.d.cts +14 -0
- package/dist/cors.d.ts +14 -0
- package/dist/cors.js +27 -0
- package/dist/cors.js.map +1 -0
- package/dist/decorators.cjs +141 -0
- package/dist/decorators.cjs.map +1 -0
- package/dist/decorators.d.cts +29 -0
- package/dist/decorators.d.ts +29 -0
- package/dist/decorators.js +122 -0
- package/dist/decorators.js.map +1 -0
- package/dist/http-error.cjs +14 -0
- package/dist/http-error.cjs.map +1 -0
- package/dist/http-error.d.cts +7 -0
- package/dist/http-error.d.ts +7 -0
- package/dist/http-error.js +12 -0
- package/dist/http-error.js.map +1 -0
- package/dist/index.cjs +910 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +899 -0
- package/dist/index.js.map +1 -0
- package/dist/infra.cjs +811 -0
- package/dist/infra.cjs.map +1 -0
- package/dist/infra.d.cts +8 -0
- package/dist/infra.d.ts +8 -0
- package/dist/infra.js +800 -0
- package/dist/infra.js.map +1 -0
- package/dist/logger.cjs +26 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +8 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.js +24 -0
- package/dist/logger.js.map +1 -0
- package/dist/middleware.cjs +117 -0
- package/dist/middleware.cjs.map +1 -0
- package/dist/middleware.d.cts +10 -0
- package/dist/middleware.d.ts +10 -0
- package/dist/middleware.js +114 -0
- package/dist/middleware.js.map +1 -0
- package/dist/plugins.cjs +52 -0
- package/dist/plugins.cjs.map +1 -0
- package/dist/plugins.d.cts +6 -0
- package/dist/plugins.d.ts +6 -0
- package/dist/plugins.js +49 -0
- package/dist/plugins.js.map +1 -0
- package/dist/rate-limit.cjs +27 -0
- package/dist/rate-limit.cjs.map +1 -0
- package/dist/rate-limit.d.cts +8 -0
- package/dist/rate-limit.d.ts +8 -0
- package/dist/rate-limit.js +25 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/request.type-CJ-EGGcM.d.cts +22 -0
- package/dist/request.type-CJ-EGGcM.d.ts +22 -0
- package/dist/response.type-d6e6eU9D.d.cts +33 -0
- package/dist/response.type-d6e6eU9D.d.ts +33 -0
- package/dist/router.cjs +111 -0
- package/dist/router.cjs.map +1 -0
- package/dist/router.d.cts +27 -0
- package/dist/router.d.ts +27 -0
- package/dist/router.js +109 -0
- package/dist/router.js.map +1 -0
- package/dist/routes.type-VPROfhnL.d.cts +14 -0
- package/dist/routes.type-VPROfhnL.d.ts +14 -0
- package/dist/types.cjs +4 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +6 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.cjs +149 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +10 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +141 -0
- package/dist/utils.js.map +1 -0
- package/dist/validations.type-D4ZhF5g6.d.cts +6 -0
- package/dist/validations.type-D4ZhF5g6.d.ts +6 -0
- package/dist/validators.cjs +69 -0
- package/dist/validators.cjs.map +1 -0
- package/dist/validators.d.cts +11 -0
- package/dist/validators.d.ts +11 -0
- package/dist/validators.js +65 -0
- package/dist/validators.js.map +1 -0
- package/package.json +85 -66
- package/src/index.ts +1 -3
- package/src/infra/Router.ts +53 -3
- package/src/infra/Server.ts +37 -10
- package/src/infra/index.ts +1 -1
- package/src/shared/config/ConfigModule.ts +1 -0
package/dist/plugins.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// src/shared/plugins/CORSPlugin.ts
|
|
2
|
+
function cors(opts) {
|
|
3
|
+
const { origin, methods, allowedHeaders } = opts;
|
|
4
|
+
return (ctx, next) => {
|
|
5
|
+
ctx.response.setHeader(
|
|
6
|
+
"Access-Control-Allow-Origin",
|
|
7
|
+
Array.isArray(origin) ? origin.join(",") : origin
|
|
8
|
+
);
|
|
9
|
+
ctx.response.setHeader(
|
|
10
|
+
"Access-Control-Allow-Methods",
|
|
11
|
+
Array.isArray(methods) ? methods.join(",") : methods
|
|
12
|
+
);
|
|
13
|
+
ctx.response.setHeader(
|
|
14
|
+
"Access-Control-Allow-Headers",
|
|
15
|
+
Array.isArray(allowedHeaders) ? allowedHeaders.join(",") : allowedHeaders
|
|
16
|
+
);
|
|
17
|
+
if (ctx.request.method === "OPTIONS") {
|
|
18
|
+
ctx.response.writeHead(204);
|
|
19
|
+
return ctx.response.end();
|
|
20
|
+
}
|
|
21
|
+
return next();
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/shared/plugins/RateLimitPlugin.ts
|
|
26
|
+
var store = /* @__PURE__ */ new Map();
|
|
27
|
+
function rateLimit(limit, ttl) {
|
|
28
|
+
return async (ctx, next) => {
|
|
29
|
+
const ip = ctx.request.socket.remoteAddress;
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
const entry = store.get(ip) ?? { count: 0, ts: now };
|
|
32
|
+
if (now - entry.ts > ttl) {
|
|
33
|
+
entry.count = 1;
|
|
34
|
+
entry.ts = now;
|
|
35
|
+
} else {
|
|
36
|
+
entry.count++;
|
|
37
|
+
}
|
|
38
|
+
store.set(ip, entry);
|
|
39
|
+
if (entry.count > limit) {
|
|
40
|
+
ctx.response.status(429).send("Too many requests");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
await next();
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { cors, rateLimit };
|
|
48
|
+
//# sourceMappingURL=plugins.js.map
|
|
49
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/plugins/CORSPlugin.ts","../src/shared/plugins/RateLimitPlugin.ts"],"names":[],"mappings":";AAGO,SAAS,KAAK,IAAA,EAAmB;AACtC,EAAA,MAAM,EAAE,MAAA,EAAQ,OAAA,EAAS,cAAA,EAAe,GAAI,IAAA;AAE5C,EAAA,OAAO,CAAC,KAAkB,IAAA,KAA8B;AACtD,IAAA,GAAA,CAAI,QAAA,CAAS,SAAA;AAAA,MACX,6BAAA;AAAA,MACA,MAAM,OAAA,CAAQ,MAAM,IAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,GAAI;AAAA,KAC7C;AACA,IAAA,GAAA,CAAI,QAAA,CAAS,SAAA;AAAA,MACX,8BAAA;AAAA,MACA,MAAM,OAAA,CAAQ,OAAO,IAAI,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,GAAI;AAAA,KAC/C;AACA,IAAA,GAAA,CAAI,QAAA,CAAS,SAAA;AAAA,MACX,8BAAA;AAAA,MACA,MAAM,OAAA,CAAQ,cAAc,IAAI,cAAA,CAAe,IAAA,CAAK,GAAG,CAAA,GAAI;AAAA,KAC7D;AAEA,IAAA,IAAI,GAAA,CAAI,OAAA,CAAQ,MAAA,KAAW,SAAA,EAAW;AACpC,MAAA,GAAA,CAAI,QAAA,CAAS,UAAU,GAAG,CAAA;AAC1B,MAAA,OAAO,GAAA,CAAI,SAAS,GAAA,EAAI;AAAA,IAC1B;AAEA,IAAA,OAAO,IAAA,EAAK;AAAA,EACd,CAAA;AACF;;;ACpBA,IAAM,KAAA,uBAAY,GAAA,EAAmB;AAE9B,SAAS,SAAA,CAAU,OAAe,GAAA,EAAa;AACpD,EAAA,OAAO,OAAO,KAAkB,IAAA,KAA8B;AAC5D,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,OAAA,CAAQ,MAAA,CAAO,aAAA;AAC9B,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,EAAG,KAAK,EAAE,KAAA,EAAO,CAAA,EAAG,EAAA,EAAI,GAAA,EAAI;AAEpD,IAAA,IAAI,GAAA,GAAM,KAAA,CAAM,EAAA,GAAK,GAAA,EAAK;AACxB,MAAA,KAAA,CAAM,KAAA,GAAQ,CAAA;AACd,MAAA,KAAA,CAAM,EAAA,GAAK,GAAA;AAAA,IACb,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAA,EAAA;AAAA,IACR;AAEA,IAAA,KAAA,CAAM,GAAA,CAAI,IAAK,KAAK,CAAA;AAEpB,IAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,EAAO;AACvB,MAAA,GAAA,CAAI,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,mBAAmB,CAAA;AACjD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,EAAK;AAAA,EACb,CAAA;AACF","file":"plugins.js","sourcesContent":["import type { HttpContext } from \"../../types/common.type\";\nimport type { CorsOptions } from \"../../types/plugins/cors.type\";\n\nexport function cors(opts: CorsOptions) {\n const { origin, methods, allowedHeaders } = opts;\n\n return (ctx: HttpContext, next: () => Promise<void>) => {\n ctx.response.setHeader(\n \"Access-Control-Allow-Origin\",\n Array.isArray(origin) ? origin.join(\",\") : origin\n );\n ctx.response.setHeader(\n \"Access-Control-Allow-Methods\",\n Array.isArray(methods) ? methods.join(\",\") : methods\n );\n ctx.response.setHeader(\n \"Access-Control-Allow-Headers\",\n Array.isArray(allowedHeaders) ? allowedHeaders.join(\",\") : allowedHeaders\n );\n\n if (ctx.request.method === \"OPTIONS\") {\n ctx.response.writeHead(204);\n return ctx.response.end();\n }\n\n return next();\n };\n}\n","import type { HttpContext } from \"../../types/common.type\";\n\ninterface Entry {\n count: number;\n ts: number;\n}\n\nconst store = new Map<string, Entry>();\n\nexport function rateLimit(limit: number, ttl: number) {\n return async (ctx: HttpContext, next: () => Promise<void>) => {\n const ip = ctx.request.socket.remoteAddress;\n const now = Date.now();\n const entry = store.get(ip!) ?? { count: 0, ts: now };\n\n if (now - entry.ts > ttl) {\n entry.count = 1;\n entry.ts = now;\n } else {\n entry.count++;\n }\n\n store.set(ip!, entry);\n\n if (entry.count > limit) {\n ctx.response.status(429).send(\"Too many requests\");\n return;\n }\n\n await next();\n };\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/shared/plugins/RateLimitPlugin.ts
|
|
4
|
+
var store = /* @__PURE__ */ new Map();
|
|
5
|
+
function rateLimit(limit, ttl) {
|
|
6
|
+
return async (ctx, next) => {
|
|
7
|
+
const ip = ctx.request.socket.remoteAddress;
|
|
8
|
+
const now = Date.now();
|
|
9
|
+
const entry = store.get(ip) ?? { count: 0, ts: now };
|
|
10
|
+
if (now - entry.ts > ttl) {
|
|
11
|
+
entry.count = 1;
|
|
12
|
+
entry.ts = now;
|
|
13
|
+
} else {
|
|
14
|
+
entry.count++;
|
|
15
|
+
}
|
|
16
|
+
store.set(ip, entry);
|
|
17
|
+
if (entry.count > limit) {
|
|
18
|
+
ctx.response.status(429).send("Too many requests");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
await next();
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.rateLimit = rateLimit;
|
|
26
|
+
//# sourceMappingURL=rate-limit.cjs.map
|
|
27
|
+
//# sourceMappingURL=rate-limit.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/plugins/RateLimitPlugin.ts"],"names":[],"mappings":";;;AAOA,IAAM,KAAA,uBAAY,GAAA,EAAmB;AAE9B,SAAS,SAAA,CAAU,OAAe,GAAA,EAAa;AACpD,EAAA,OAAO,OAAO,KAAkB,IAAA,KAA8B;AAC5D,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,OAAA,CAAQ,MAAA,CAAO,aAAA;AAC9B,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,EAAG,KAAK,EAAE,KAAA,EAAO,CAAA,EAAG,EAAA,EAAI,GAAA,EAAI;AAEpD,IAAA,IAAI,GAAA,GAAM,KAAA,CAAM,EAAA,GAAK,GAAA,EAAK;AACxB,MAAA,KAAA,CAAM,KAAA,GAAQ,CAAA;AACd,MAAA,KAAA,CAAM,EAAA,GAAK,GAAA;AAAA,IACb,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAA,EAAA;AAAA,IACR;AAEA,IAAA,KAAA,CAAM,GAAA,CAAI,IAAK,KAAK,CAAA;AAEpB,IAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,EAAO;AACvB,MAAA,GAAA,CAAI,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,mBAAmB,CAAA;AACjD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,EAAK;AAAA,EACb,CAAA;AACF","file":"rate-limit.cjs","sourcesContent":["import type { HttpContext } from \"../../types/common.type\";\n\ninterface Entry {\n count: number;\n ts: number;\n}\n\nconst store = new Map<string, Entry>();\n\nexport function rateLimit(limit: number, ttl: number) {\n return async (ctx: HttpContext, next: () => Promise<void>) => {\n const ip = ctx.request.socket.remoteAddress;\n const now = Date.now();\n const entry = store.get(ip!) ?? { count: 0, ts: now };\n\n if (now - entry.ts > ttl) {\n entry.count = 1;\n entry.ts = now;\n } else {\n entry.count++;\n }\n\n store.set(ip!, entry);\n\n if (entry.count > limit) {\n ctx.response.status(429).send(\"Too many requests\");\n return;\n }\n\n await next();\n };\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { H as HttpContext } from './common.type-Ct06XeYQ.cjs';
|
|
2
|
+
import './request.type-CJ-EGGcM.cjs';
|
|
3
|
+
import 'node:http';
|
|
4
|
+
import './response.type-d6e6eU9D.cjs';
|
|
5
|
+
|
|
6
|
+
declare function rateLimit(limit: number, ttl: number): (ctx: HttpContext, next: () => Promise<void>) => Promise<void>;
|
|
7
|
+
|
|
8
|
+
export { rateLimit };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { H as HttpContext } from './common.type-BoV71o_C.js';
|
|
2
|
+
import './request.type-CJ-EGGcM.js';
|
|
3
|
+
import 'node:http';
|
|
4
|
+
import './response.type-d6e6eU9D.js';
|
|
5
|
+
|
|
6
|
+
declare function rateLimit(limit: number, ttl: number): (ctx: HttpContext, next: () => Promise<void>) => Promise<void>;
|
|
7
|
+
|
|
8
|
+
export { rateLimit };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/shared/plugins/RateLimitPlugin.ts
|
|
2
|
+
var store = /* @__PURE__ */ new Map();
|
|
3
|
+
function rateLimit(limit, ttl) {
|
|
4
|
+
return async (ctx, next) => {
|
|
5
|
+
const ip = ctx.request.socket.remoteAddress;
|
|
6
|
+
const now = Date.now();
|
|
7
|
+
const entry = store.get(ip) ?? { count: 0, ts: now };
|
|
8
|
+
if (now - entry.ts > ttl) {
|
|
9
|
+
entry.count = 1;
|
|
10
|
+
entry.ts = now;
|
|
11
|
+
} else {
|
|
12
|
+
entry.count++;
|
|
13
|
+
}
|
|
14
|
+
store.set(ip, entry);
|
|
15
|
+
if (entry.count > limit) {
|
|
16
|
+
ctx.response.status(429).send("Too many requests");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
await next();
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { rateLimit };
|
|
24
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
25
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/plugins/RateLimitPlugin.ts"],"names":[],"mappings":";AAOA,IAAM,KAAA,uBAAY,GAAA,EAAmB;AAE9B,SAAS,SAAA,CAAU,OAAe,GAAA,EAAa;AACpD,EAAA,OAAO,OAAO,KAAkB,IAAA,KAA8B;AAC5D,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,OAAA,CAAQ,MAAA,CAAO,aAAA;AAC9B,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,EAAG,KAAK,EAAE,KAAA,EAAO,CAAA,EAAG,EAAA,EAAI,GAAA,EAAI;AAEpD,IAAA,IAAI,GAAA,GAAM,KAAA,CAAM,EAAA,GAAK,GAAA,EAAK;AACxB,MAAA,KAAA,CAAM,KAAA,GAAQ,CAAA;AACd,MAAA,KAAA,CAAM,EAAA,GAAK,GAAA;AAAA,IACb,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAA,EAAA;AAAA,IACR;AAEA,IAAA,KAAA,CAAM,GAAA,CAAI,IAAK,KAAK,CAAA;AAEpB,IAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,EAAO;AACvB,MAAA,GAAA,CAAI,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,mBAAmB,CAAA;AACjD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,EAAK;AAAA,EACb,CAAA;AACF","file":"rate-limit.js","sourcesContent":["import type { HttpContext } from \"../../types/common.type\";\n\ninterface Entry {\n count: number;\n ts: number;\n}\n\nconst store = new Map<string, Entry>();\n\nexport function rateLimit(limit: number, ttl: number) {\n return async (ctx: HttpContext, next: () => Promise<void>) => {\n const ip = ctx.request.socket.remoteAddress;\n const now = Date.now();\n const entry = store.get(ip!) ?? { count: 0, ts: now };\n\n if (now - entry.ts > ttl) {\n entry.count = 1;\n entry.ts = now;\n } else {\n entry.count++;\n }\n\n store.set(ip!, entry);\n\n if (entry.count > limit) {\n ctx.response.status(429).send(\"Too many requests\");\n return;\n }\n\n await next();\n };\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { IncomingMessage, IncomingHttpHeaders } from 'node:http';
|
|
2
|
+
|
|
3
|
+
interface RequestServer extends IncomingMessage {
|
|
4
|
+
path: string;
|
|
5
|
+
originalUrl: string;
|
|
6
|
+
method: string;
|
|
7
|
+
protocol: "http" | "https";
|
|
8
|
+
secure: boolean;
|
|
9
|
+
hostname: string;
|
|
10
|
+
subdomains: string[];
|
|
11
|
+
ip: string;
|
|
12
|
+
ips?: string[];
|
|
13
|
+
params: Record<string, string>;
|
|
14
|
+
query: Record<string, string>;
|
|
15
|
+
body: unknown;
|
|
16
|
+
cookies: Record<string, string>;
|
|
17
|
+
headers: IncomingHttpHeaders;
|
|
18
|
+
get(name: string): string | undefined;
|
|
19
|
+
header(name: string): string | undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type { RequestServer as R };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { IncomingMessage, IncomingHttpHeaders } from 'node:http';
|
|
2
|
+
|
|
3
|
+
interface RequestServer extends IncomingMessage {
|
|
4
|
+
path: string;
|
|
5
|
+
originalUrl: string;
|
|
6
|
+
method: string;
|
|
7
|
+
protocol: "http" | "https";
|
|
8
|
+
secure: boolean;
|
|
9
|
+
hostname: string;
|
|
10
|
+
subdomains: string[];
|
|
11
|
+
ip: string;
|
|
12
|
+
ips?: string[];
|
|
13
|
+
params: Record<string, string>;
|
|
14
|
+
query: Record<string, string>;
|
|
15
|
+
body: unknown;
|
|
16
|
+
cookies: Record<string, string>;
|
|
17
|
+
headers: IncomingHttpHeaders;
|
|
18
|
+
get(name: string): string | undefined;
|
|
19
|
+
header(name: string): string | undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type { RequestServer as R };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ServerResponse } from 'node:http';
|
|
2
|
+
|
|
3
|
+
interface CookieOptions {
|
|
4
|
+
domain?: string;
|
|
5
|
+
encode?: (value: string) => string;
|
|
6
|
+
expires?: Date;
|
|
7
|
+
httpOnly?: boolean;
|
|
8
|
+
maxAge?: number;
|
|
9
|
+
path?: string;
|
|
10
|
+
sameSite?: "strict" | "lax" | "none";
|
|
11
|
+
secure?: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface ResponseServer extends ServerResponse {
|
|
14
|
+
end(cb?: () => void): this;
|
|
15
|
+
end(chunk: any, cb?: () => void): this;
|
|
16
|
+
end(chunk: any, encoding: string, cb?: () => void): this;
|
|
17
|
+
headersSent: boolean;
|
|
18
|
+
status(code: number): this;
|
|
19
|
+
set(field: string, value: string | number | string[]): this;
|
|
20
|
+
header(field: string, value: string | number | string[]): this;
|
|
21
|
+
get(field: string): string | undefined;
|
|
22
|
+
type(type: string): this;
|
|
23
|
+
contentType(type: string): this;
|
|
24
|
+
redirect(url: string): this;
|
|
25
|
+
redirect(status: number, url: string): this;
|
|
26
|
+
location(url: string): this;
|
|
27
|
+
cookie(name: string, value: string, options?: CookieOptions): this;
|
|
28
|
+
clearCookie(name: string, options?: CookieOptions): this;
|
|
29
|
+
send(body: any): this;
|
|
30
|
+
json(body: any): this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type { CookieOptions as C, ResponseServer as R };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ServerResponse } from 'node:http';
|
|
2
|
+
|
|
3
|
+
interface CookieOptions {
|
|
4
|
+
domain?: string;
|
|
5
|
+
encode?: (value: string) => string;
|
|
6
|
+
expires?: Date;
|
|
7
|
+
httpOnly?: boolean;
|
|
8
|
+
maxAge?: number;
|
|
9
|
+
path?: string;
|
|
10
|
+
sameSite?: "strict" | "lax" | "none";
|
|
11
|
+
secure?: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface ResponseServer extends ServerResponse {
|
|
14
|
+
end(cb?: () => void): this;
|
|
15
|
+
end(chunk: any, cb?: () => void): this;
|
|
16
|
+
end(chunk: any, encoding: string, cb?: () => void): this;
|
|
17
|
+
headersSent: boolean;
|
|
18
|
+
status(code: number): this;
|
|
19
|
+
set(field: string, value: string | number | string[]): this;
|
|
20
|
+
header(field: string, value: string | number | string[]): this;
|
|
21
|
+
get(field: string): string | undefined;
|
|
22
|
+
type(type: string): this;
|
|
23
|
+
contentType(type: string): this;
|
|
24
|
+
redirect(url: string): this;
|
|
25
|
+
redirect(status: number, url: string): this;
|
|
26
|
+
location(url: string): this;
|
|
27
|
+
cookie(name: string, value: string, options?: CookieOptions): this;
|
|
28
|
+
clearCookie(name: string, options?: CookieOptions): this;
|
|
29
|
+
send(body: any): this;
|
|
30
|
+
json(body: any): this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type { CookieOptions as C, ResponseServer as R };
|
package/dist/router.cjs
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/infra/utils/HttpError.ts
|
|
4
|
+
var HttpError = class extends Error {
|
|
5
|
+
constructor(status, message, payload) {
|
|
6
|
+
super(message ?? String(message ?? "Error"));
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.payload = payload;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// src/infra/utils/route/Node.ts
|
|
13
|
+
var Node = class {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.children = /* @__PURE__ */ new Map();
|
|
16
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// src/infra/Router.ts
|
|
21
|
+
var Router = class {
|
|
22
|
+
constructor(debug = false) {
|
|
23
|
+
this.root = new Node();
|
|
24
|
+
this.debug = debug;
|
|
25
|
+
}
|
|
26
|
+
add(method, path, ...handlers) {
|
|
27
|
+
const segments = path.split("/").filter(Boolean);
|
|
28
|
+
let node = this.root;
|
|
29
|
+
for (const seg of segments) {
|
|
30
|
+
let child;
|
|
31
|
+
if (seg.startsWith(":")) {
|
|
32
|
+
child = new Node();
|
|
33
|
+
child.isParam = true;
|
|
34
|
+
child.paramName = seg.slice(1);
|
|
35
|
+
} else {
|
|
36
|
+
child = node.children.get(seg) ?? new Node();
|
|
37
|
+
}
|
|
38
|
+
node.children.set(seg.startsWith(":") ? ":" : seg, child);
|
|
39
|
+
node = child;
|
|
40
|
+
}
|
|
41
|
+
node.handlers.set(method.toUpperCase(), handlers);
|
|
42
|
+
}
|
|
43
|
+
find(method, path) {
|
|
44
|
+
const cleanPath = path.split("?")[0];
|
|
45
|
+
const segments = cleanPath?.split("/").filter(Boolean) ?? [];
|
|
46
|
+
let node = this.root;
|
|
47
|
+
const params = {};
|
|
48
|
+
if (this.debug && segments?.length === 0 && node.handlers.size === 0) {
|
|
49
|
+
console.error("[Router:DEBUG] Root node has no handlers");
|
|
50
|
+
console.error("[Router:DEBUG] Available methods at root:", Array.from(node.handlers.keys()));
|
|
51
|
+
}
|
|
52
|
+
for (let i = 0; i < segments.length; i++) {
|
|
53
|
+
const seg = segments[i];
|
|
54
|
+
if (!seg) continue;
|
|
55
|
+
let child = node.children.get(seg);
|
|
56
|
+
if (child) {
|
|
57
|
+
node = child;
|
|
58
|
+
} else {
|
|
59
|
+
child = node.children.get(":");
|
|
60
|
+
if (child) {
|
|
61
|
+
node = child;
|
|
62
|
+
if (node.paramName) {
|
|
63
|
+
params[node.paramName] = seg;
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
if (this.debug) {
|
|
67
|
+
console.error(`[Router:DEBUG] Route not found for ${method} ${cleanPath}`);
|
|
68
|
+
console.error(`[Router:DEBUG] Failed at segment: "${seg}"`);
|
|
69
|
+
console.error(`[Router:DEBUG] Available children:`, Array.from(node.children.keys()));
|
|
70
|
+
}
|
|
71
|
+
throw new HttpError(404, "Route not found");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const handlers = node.handlers.get(method.toUpperCase());
|
|
76
|
+
if (!handlers) {
|
|
77
|
+
if (this.debug) {
|
|
78
|
+
console.error(
|
|
79
|
+
`[Router:DEBUG] No handlers for method ${method.toUpperCase()} at path ${cleanPath}`
|
|
80
|
+
);
|
|
81
|
+
console.error(
|
|
82
|
+
`[Router:DEBUG] Available methods at this path:`,
|
|
83
|
+
Array.from(node.handlers.keys())
|
|
84
|
+
);
|
|
85
|
+
console.error(`[Router:DEBUG] Segments matched:`, segments);
|
|
86
|
+
}
|
|
87
|
+
throw new HttpError(404, "Route not found");
|
|
88
|
+
}
|
|
89
|
+
return { handlers, params };
|
|
90
|
+
}
|
|
91
|
+
listRoutes() {
|
|
92
|
+
const routes = [];
|
|
93
|
+
const traverse = (node, path) => {
|
|
94
|
+
if (node.handlers.size > 0) {
|
|
95
|
+
for (const method of node.handlers.keys()) {
|
|
96
|
+
routes.push({ method, path: path || "/" });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (const [segment, child] of node.children) {
|
|
100
|
+
const newPath = path + "/" + (segment === ":" && child.paramName ? `:${child.paramName}` : segment);
|
|
101
|
+
traverse(child, newPath);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
traverse(this.root, "");
|
|
105
|
+
return routes;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
exports.Router = Router;
|
|
110
|
+
//# sourceMappingURL=router.cjs.map
|
|
111
|
+
//# sourceMappingURL=router.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/infra/utils/HttpError.ts","../src/infra/utils/route/Node.ts","../src/infra/Router.ts"],"names":[],"mappings":"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","file":"router.cjs","sourcesContent":["export class HttpError extends Error {\n status: number;\n payload?: any;\n constructor(status: number, message?: string, payload?: any) {\n super(message ?? String(message ?? \"Error\"));\n this.status = status;\n this.payload = payload;\n }\n}\n","import type { RequestServer } from \"../../../types/http/request.type\";\nimport type { ResponseServer } from \"../../../types/http/response.type\";\n\nexport type Handler = (ctx: {\n req: RequestServer;\n res: ResponseServer;\n next?: (err?: any) => void;\n}) => Promise<void> | void;\n\nexport class Node {\n children = new Map<string, Node>();\n handlers = new Map<string, Handler[]>();\n paramName?: string;\n isParam?: boolean;\n}\n","import { HttpError } from \"./utils/HttpError\";\nimport { Node, type Handler } from \"./utils/route/Node\";\n\ninterface MatchResult {\n handlers: Handler[];\n params: Record<string, string>;\n}\n\nexport class Router {\n private root = new Node();\n private debug: boolean;\n\n constructor(debug = false) {\n this.debug = debug;\n }\n\n add(method: string, path: string, ...handlers: Handler[]) {\n const segments = path.split(\"/\").filter(Boolean);\n let node = this.root;\n\n for (const seg of segments) {\n let child: Node;\n\n if (seg.startsWith(\":\")) {\n child = new Node();\n child.isParam = true;\n child.paramName = seg.slice(1);\n } else {\n child = node.children.get(seg) ?? new Node();\n }\n\n node.children.set(seg.startsWith(\":\") ? \":\" : seg, child);\n node = child;\n }\n\n node.handlers.set(method.toUpperCase(), handlers);\n }\n\n find(method: string, path: string): MatchResult {\n const cleanPath = path.split(\"?\")[0];\n const segments = cleanPath?.split(\"/\").filter(Boolean) ?? [];\n let node = this.root;\n const params: Record<string, string> = {};\n\n if (this.debug && segments?.length === 0 && node.handlers.size === 0) {\n console.error(\"[Router:DEBUG] Root node has no handlers\");\n console.error(\"[Router:DEBUG] Available methods at root:\", Array.from(node.handlers.keys()));\n }\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n if (!seg) continue;\n\n let child = node.children.get(seg);\n\n if (child) {\n node = child;\n } else {\n child = node.children.get(\":\");\n if (child) {\n node = child;\n if (node.paramName) {\n params[node.paramName] = seg;\n }\n } else {\n // Debug melhorado - só mostra se debug estiver ativo\n if (this.debug) {\n console.error(`[Router:DEBUG] Route not found for ${method} ${cleanPath}`);\n console.error(`[Router:DEBUG] Failed at segment: \"${seg}\"`);\n console.error(`[Router:DEBUG] Available children:`, Array.from(node.children.keys()));\n }\n throw new HttpError(404, \"Route not found\");\n }\n }\n }\n\n const handlers = node.handlers.get(method.toUpperCase()) as Handler[];\n if (!handlers) {\n if (this.debug) {\n console.error(\n `[Router:DEBUG] No handlers for method ${method.toUpperCase()} at path ${cleanPath}`\n );\n console.error(\n `[Router:DEBUG] Available methods at this path:`,\n Array.from(node.handlers.keys())\n );\n console.error(`[Router:DEBUG] Segments matched:`, segments);\n }\n throw new HttpError(404, \"Route not found\");\n }\n return { handlers, params };\n }\n\n public listRoutes(): Array<{ method: string; path: string }> {\n const routes: Array<{ method: string; path: string }> = [];\n\n const traverse = (node: Node, path: string) => {\n if (node.handlers.size > 0) {\n for (const method of node.handlers.keys()) {\n routes.push({ method, path: path || \"/\" });\n }\n }\n\n for (const [segment, child] of node.children) {\n const newPath =\n path + \"/\" + (segment === \":\" && child.paramName ? `:${child.paramName}` : segment);\n traverse(child, newPath);\n }\n };\n\n traverse(this.root, \"\");\n return routes;\n }\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { R as RequestServer } from './request.type-CJ-EGGcM.cjs';
|
|
2
|
+
import { R as ResponseServer } from './response.type-d6e6eU9D.cjs';
|
|
3
|
+
import 'node:http';
|
|
4
|
+
|
|
5
|
+
type Handler = (ctx: {
|
|
6
|
+
req: RequestServer;
|
|
7
|
+
res: ResponseServer;
|
|
8
|
+
next?: (err?: any) => void;
|
|
9
|
+
}) => Promise<void> | void;
|
|
10
|
+
|
|
11
|
+
interface MatchResult {
|
|
12
|
+
handlers: Handler[];
|
|
13
|
+
params: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
declare class Router {
|
|
16
|
+
private root;
|
|
17
|
+
private debug;
|
|
18
|
+
constructor(debug?: boolean);
|
|
19
|
+
add(method: string, path: string, ...handlers: Handler[]): void;
|
|
20
|
+
find(method: string, path: string): MatchResult;
|
|
21
|
+
listRoutes(): Array<{
|
|
22
|
+
method: string;
|
|
23
|
+
path: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { Router };
|
package/dist/router.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { R as RequestServer } from './request.type-CJ-EGGcM.js';
|
|
2
|
+
import { R as ResponseServer } from './response.type-d6e6eU9D.js';
|
|
3
|
+
import 'node:http';
|
|
4
|
+
|
|
5
|
+
type Handler = (ctx: {
|
|
6
|
+
req: RequestServer;
|
|
7
|
+
res: ResponseServer;
|
|
8
|
+
next?: (err?: any) => void;
|
|
9
|
+
}) => Promise<void> | void;
|
|
10
|
+
|
|
11
|
+
interface MatchResult {
|
|
12
|
+
handlers: Handler[];
|
|
13
|
+
params: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
declare class Router {
|
|
16
|
+
private root;
|
|
17
|
+
private debug;
|
|
18
|
+
constructor(debug?: boolean);
|
|
19
|
+
add(method: string, path: string, ...handlers: Handler[]): void;
|
|
20
|
+
find(method: string, path: string): MatchResult;
|
|
21
|
+
listRoutes(): Array<{
|
|
22
|
+
method: string;
|
|
23
|
+
path: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { Router };
|
package/dist/router.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// src/infra/utils/HttpError.ts
|
|
2
|
+
var HttpError = class extends Error {
|
|
3
|
+
constructor(status, message, payload) {
|
|
4
|
+
super(message ?? String(message ?? "Error"));
|
|
5
|
+
this.status = status;
|
|
6
|
+
this.payload = payload;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// src/infra/utils/route/Node.ts
|
|
11
|
+
var Node = class {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.children = /* @__PURE__ */ new Map();
|
|
14
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/infra/Router.ts
|
|
19
|
+
var Router = class {
|
|
20
|
+
constructor(debug = false) {
|
|
21
|
+
this.root = new Node();
|
|
22
|
+
this.debug = debug;
|
|
23
|
+
}
|
|
24
|
+
add(method, path, ...handlers) {
|
|
25
|
+
const segments = path.split("/").filter(Boolean);
|
|
26
|
+
let node = this.root;
|
|
27
|
+
for (const seg of segments) {
|
|
28
|
+
let child;
|
|
29
|
+
if (seg.startsWith(":")) {
|
|
30
|
+
child = new Node();
|
|
31
|
+
child.isParam = true;
|
|
32
|
+
child.paramName = seg.slice(1);
|
|
33
|
+
} else {
|
|
34
|
+
child = node.children.get(seg) ?? new Node();
|
|
35
|
+
}
|
|
36
|
+
node.children.set(seg.startsWith(":") ? ":" : seg, child);
|
|
37
|
+
node = child;
|
|
38
|
+
}
|
|
39
|
+
node.handlers.set(method.toUpperCase(), handlers);
|
|
40
|
+
}
|
|
41
|
+
find(method, path) {
|
|
42
|
+
const cleanPath = path.split("?")[0];
|
|
43
|
+
const segments = cleanPath?.split("/").filter(Boolean) ?? [];
|
|
44
|
+
let node = this.root;
|
|
45
|
+
const params = {};
|
|
46
|
+
if (this.debug && segments?.length === 0 && node.handlers.size === 0) {
|
|
47
|
+
console.error("[Router:DEBUG] Root node has no handlers");
|
|
48
|
+
console.error("[Router:DEBUG] Available methods at root:", Array.from(node.handlers.keys()));
|
|
49
|
+
}
|
|
50
|
+
for (let i = 0; i < segments.length; i++) {
|
|
51
|
+
const seg = segments[i];
|
|
52
|
+
if (!seg) continue;
|
|
53
|
+
let child = node.children.get(seg);
|
|
54
|
+
if (child) {
|
|
55
|
+
node = child;
|
|
56
|
+
} else {
|
|
57
|
+
child = node.children.get(":");
|
|
58
|
+
if (child) {
|
|
59
|
+
node = child;
|
|
60
|
+
if (node.paramName) {
|
|
61
|
+
params[node.paramName] = seg;
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
if (this.debug) {
|
|
65
|
+
console.error(`[Router:DEBUG] Route not found for ${method} ${cleanPath}`);
|
|
66
|
+
console.error(`[Router:DEBUG] Failed at segment: "${seg}"`);
|
|
67
|
+
console.error(`[Router:DEBUG] Available children:`, Array.from(node.children.keys()));
|
|
68
|
+
}
|
|
69
|
+
throw new HttpError(404, "Route not found");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const handlers = node.handlers.get(method.toUpperCase());
|
|
74
|
+
if (!handlers) {
|
|
75
|
+
if (this.debug) {
|
|
76
|
+
console.error(
|
|
77
|
+
`[Router:DEBUG] No handlers for method ${method.toUpperCase()} at path ${cleanPath}`
|
|
78
|
+
);
|
|
79
|
+
console.error(
|
|
80
|
+
`[Router:DEBUG] Available methods at this path:`,
|
|
81
|
+
Array.from(node.handlers.keys())
|
|
82
|
+
);
|
|
83
|
+
console.error(`[Router:DEBUG] Segments matched:`, segments);
|
|
84
|
+
}
|
|
85
|
+
throw new HttpError(404, "Route not found");
|
|
86
|
+
}
|
|
87
|
+
return { handlers, params };
|
|
88
|
+
}
|
|
89
|
+
listRoutes() {
|
|
90
|
+
const routes = [];
|
|
91
|
+
const traverse = (node, path) => {
|
|
92
|
+
if (node.handlers.size > 0) {
|
|
93
|
+
for (const method of node.handlers.keys()) {
|
|
94
|
+
routes.push({ method, path: path || "/" });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
for (const [segment, child] of node.children) {
|
|
98
|
+
const newPath = path + "/" + (segment === ":" && child.paramName ? `:${child.paramName}` : segment);
|
|
99
|
+
traverse(child, newPath);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
traverse(this.root, "");
|
|
103
|
+
return routes;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export { Router };
|
|
108
|
+
//# sourceMappingURL=router.js.map
|
|
109
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/infra/utils/HttpError.ts","../src/infra/utils/route/Node.ts","../src/infra/Router.ts"],"names":[],"mappings":"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","file":"router.js","sourcesContent":["export class HttpError extends Error {\n status: number;\n payload?: any;\n constructor(status: number, message?: string, payload?: any) {\n super(message ?? String(message ?? \"Error\"));\n this.status = status;\n this.payload = payload;\n }\n}\n","import type { RequestServer } from \"../../../types/http/request.type\";\nimport type { ResponseServer } from \"../../../types/http/response.type\";\n\nexport type Handler = (ctx: {\n req: RequestServer;\n res: ResponseServer;\n next?: (err?: any) => void;\n}) => Promise<void> | void;\n\nexport class Node {\n children = new Map<string, Node>();\n handlers = new Map<string, Handler[]>();\n paramName?: string;\n isParam?: boolean;\n}\n","import { HttpError } from \"./utils/HttpError\";\nimport { Node, type Handler } from \"./utils/route/Node\";\n\ninterface MatchResult {\n handlers: Handler[];\n params: Record<string, string>;\n}\n\nexport class Router {\n private root = new Node();\n private debug: boolean;\n\n constructor(debug = false) {\n this.debug = debug;\n }\n\n add(method: string, path: string, ...handlers: Handler[]) {\n const segments = path.split(\"/\").filter(Boolean);\n let node = this.root;\n\n for (const seg of segments) {\n let child: Node;\n\n if (seg.startsWith(\":\")) {\n child = new Node();\n child.isParam = true;\n child.paramName = seg.slice(1);\n } else {\n child = node.children.get(seg) ?? new Node();\n }\n\n node.children.set(seg.startsWith(\":\") ? \":\" : seg, child);\n node = child;\n }\n\n node.handlers.set(method.toUpperCase(), handlers);\n }\n\n find(method: string, path: string): MatchResult {\n const cleanPath = path.split(\"?\")[0];\n const segments = cleanPath?.split(\"/\").filter(Boolean) ?? [];\n let node = this.root;\n const params: Record<string, string> = {};\n\n if (this.debug && segments?.length === 0 && node.handlers.size === 0) {\n console.error(\"[Router:DEBUG] Root node has no handlers\");\n console.error(\"[Router:DEBUG] Available methods at root:\", Array.from(node.handlers.keys()));\n }\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n if (!seg) continue;\n\n let child = node.children.get(seg);\n\n if (child) {\n node = child;\n } else {\n child = node.children.get(\":\");\n if (child) {\n node = child;\n if (node.paramName) {\n params[node.paramName] = seg;\n }\n } else {\n // Debug melhorado - só mostra se debug estiver ativo\n if (this.debug) {\n console.error(`[Router:DEBUG] Route not found for ${method} ${cleanPath}`);\n console.error(`[Router:DEBUG] Failed at segment: \"${seg}\"`);\n console.error(`[Router:DEBUG] Available children:`, Array.from(node.children.keys()));\n }\n throw new HttpError(404, \"Route not found\");\n }\n }\n }\n\n const handlers = node.handlers.get(method.toUpperCase()) as Handler[];\n if (!handlers) {\n if (this.debug) {\n console.error(\n `[Router:DEBUG] No handlers for method ${method.toUpperCase()} at path ${cleanPath}`\n );\n console.error(\n `[Router:DEBUG] Available methods at this path:`,\n Array.from(node.handlers.keys())\n );\n console.error(`[Router:DEBUG] Segments matched:`, segments);\n }\n throw new HttpError(404, \"Route not found\");\n }\n return { handlers, params };\n }\n\n public listRoutes(): Array<{ method: string; path: string }> {\n const routes: Array<{ method: string; path: string }> = [];\n\n const traverse = (node: Node, path: string) => {\n if (node.handlers.size > 0) {\n for (const method of node.handlers.keys()) {\n routes.push({ method, path: path || \"/\" });\n }\n }\n\n for (const [segment, child] of node.children) {\n const newPath =\n path + \"/\" + (segment === \":\" && child.paramName ? `:${child.paramName}` : segment);\n traverse(child, newPath);\n }\n };\n\n traverse(this.root, \"\");\n return routes;\n }\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type ParamSource = "param" | "query" | "body" | "headers" | "req" | "res" | "next" | "ip" | "useragent";
|
|
2
|
+
interface ParamDefinition {
|
|
3
|
+
index: number;
|
|
4
|
+
type: ParamSource;
|
|
5
|
+
name?: string;
|
|
6
|
+
}
|
|
7
|
+
interface RouteDefinition {
|
|
8
|
+
method: string;
|
|
9
|
+
path: string;
|
|
10
|
+
propertyKey: string;
|
|
11
|
+
params: ParamDefinition[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type { ParamDefinition as P, RouteDefinition as R, ParamSource as a };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type ParamSource = "param" | "query" | "body" | "headers" | "req" | "res" | "next" | "ip" | "useragent";
|
|
2
|
+
interface ParamDefinition {
|
|
3
|
+
index: number;
|
|
4
|
+
type: ParamSource;
|
|
5
|
+
name?: string;
|
|
6
|
+
}
|
|
7
|
+
interface RouteDefinition {
|
|
8
|
+
method: string;
|
|
9
|
+
path: string;
|
|
10
|
+
propertyKey: string;
|
|
11
|
+
params: ParamDefinition[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type { ParamDefinition as P, RouteDefinition as R, ParamSource as a };
|
package/dist/types.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"types.cjs"}
|
package/dist/types.d.cts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { R as RequestServer } from './request.type-CJ-EGGcM.cjs';
|
|
2
|
+
export { R as ResponseServer } from './response.type-d6e6eU9D.cjs';
|
|
3
|
+
export { H as HttpContext, R as RequestHandler } from './common.type-Ct06XeYQ.cjs';
|
|
4
|
+
export { P as ParamDefinition, a as ParamSource, R as RouteDefinition } from './routes.type-VPROfhnL.cjs';
|
|
5
|
+
export { S as ValidationSchema } from './validations.type-D4ZhF5g6.cjs';
|
|
6
|
+
import 'node:http';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { R as RequestServer } from './request.type-CJ-EGGcM.js';
|
|
2
|
+
export { R as ResponseServer } from './response.type-d6e6eU9D.js';
|
|
3
|
+
export { H as HttpContext, R as RequestHandler } from './common.type-BoV71o_C.js';
|
|
4
|
+
export { P as ParamDefinition, a as ParamSource, R as RouteDefinition } from './routes.type-VPROfhnL.js';
|
|
5
|
+
export { S as ValidationSchema } from './validations.type-D4ZhF5g6.js';
|
|
6
|
+
import 'node:http';
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"types.js"}
|