@alis-kit/routers 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 (90) hide show
  1. package/README.md +302 -0
  2. package/dist/adapters/BaseAdapter.d.ts +63 -0
  3. package/dist/adapters/BaseAdapter.d.ts.map +1 -0
  4. package/dist/adapters/BaseAdapter.js +17 -0
  5. package/dist/adapters/BaseAdapter.js.map +1 -0
  6. package/dist/adapters/ExpressAdapter.d.ts +44 -0
  7. package/dist/adapters/ExpressAdapter.d.ts.map +1 -0
  8. package/dist/adapters/ExpressAdapter.js +73 -0
  9. package/dist/adapters/ExpressAdapter.js.map +1 -0
  10. package/dist/adapters/FastifyAdapter.d.ts +61 -0
  11. package/dist/adapters/FastifyAdapter.d.ts.map +1 -0
  12. package/dist/adapters/FastifyAdapter.js +132 -0
  13. package/dist/adapters/FastifyAdapter.js.map +1 -0
  14. package/dist/cookie/CookieSetter.d.ts +74 -0
  15. package/dist/cookie/CookieSetter.d.ts.map +1 -0
  16. package/dist/cookie/CookieSetter.js +89 -0
  17. package/dist/cookie/CookieSetter.js.map +1 -0
  18. package/dist/core/Logger.d.ts +36 -0
  19. package/dist/core/Logger.d.ts.map +1 -0
  20. package/dist/core/Logger.js +53 -0
  21. package/dist/core/Logger.js.map +1 -0
  22. package/dist/core/RouteResolver.d.ts +91 -0
  23. package/dist/core/RouteResolver.d.ts.map +1 -0
  24. package/dist/core/RouteResolver.js +279 -0
  25. package/dist/core/RouteResolver.js.map +1 -0
  26. package/dist/core/RouterKit.d.ts +116 -0
  27. package/dist/core/RouterKit.d.ts.map +1 -0
  28. package/dist/core/RouterKit.js +175 -0
  29. package/dist/core/RouterKit.js.map +1 -0
  30. package/dist/decorators/controller/ReqController.d.ts +29 -0
  31. package/dist/decorators/controller/ReqController.d.ts.map +1 -0
  32. package/dist/decorators/controller/ReqController.js +62 -0
  33. package/dist/decorators/controller/ReqController.js.map +1 -0
  34. package/dist/decorators/mapping/index.d.ts +93 -0
  35. package/dist/decorators/mapping/index.d.ts.map +1 -0
  36. package/dist/decorators/mapping/index.js +128 -0
  37. package/dist/decorators/mapping/index.js.map +1 -0
  38. package/dist/decorators/method/index.d.ts +67 -0
  39. package/dist/decorators/method/index.d.ts.map +1 -0
  40. package/dist/decorators/method/index.js +83 -0
  41. package/dist/decorators/method/index.js.map +1 -0
  42. package/dist/decorators/parameter/index.d.ts +155 -0
  43. package/dist/decorators/parameter/index.d.ts.map +1 -0
  44. package/dist/decorators/parameter/index.js +196 -0
  45. package/dist/decorators/parameter/index.js.map +1 -0
  46. package/dist/exceptions/BadRequestException.d.ts +37 -0
  47. package/dist/exceptions/BadRequestException.d.ts.map +1 -0
  48. package/dist/exceptions/BadRequestException.js +37 -0
  49. package/dist/exceptions/BadRequestException.js.map +1 -0
  50. package/dist/exceptions/BaseException.d.ts +29 -0
  51. package/dist/exceptions/BaseException.d.ts.map +1 -0
  52. package/dist/exceptions/BaseException.js +29 -0
  53. package/dist/exceptions/BaseException.js.map +1 -0
  54. package/dist/exceptions/ConflictException.d.ts +28 -0
  55. package/dist/exceptions/ConflictException.d.ts.map +1 -0
  56. package/dist/exceptions/ConflictException.js +28 -0
  57. package/dist/exceptions/ConflictException.js.map +1 -0
  58. package/dist/exceptions/ForbiddenException.d.ts +26 -0
  59. package/dist/exceptions/ForbiddenException.d.ts.map +1 -0
  60. package/dist/exceptions/ForbiddenException.js +26 -0
  61. package/dist/exceptions/ForbiddenException.js.map +1 -0
  62. package/dist/exceptions/NotFoundException.d.ts +28 -0
  63. package/dist/exceptions/NotFoundException.d.ts.map +1 -0
  64. package/dist/exceptions/NotFoundException.js +28 -0
  65. package/dist/exceptions/NotFoundException.js.map +1 -0
  66. package/dist/exceptions/ServerErrorException.d.ts +33 -0
  67. package/dist/exceptions/ServerErrorException.d.ts.map +1 -0
  68. package/dist/exceptions/ServerErrorException.js +33 -0
  69. package/dist/exceptions/ServerErrorException.js.map +1 -0
  70. package/dist/exceptions/UnauthorizedException.d.ts +28 -0
  71. package/dist/exceptions/UnauthorizedException.d.ts.map +1 -0
  72. package/dist/exceptions/UnauthorizedException.js +28 -0
  73. package/dist/exceptions/UnauthorizedException.js.map +1 -0
  74. package/dist/index.d.ts +15 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +21 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/swagger/SwaggerGenerator.d.ts +63 -0
  79. package/dist/swagger/SwaggerGenerator.d.ts.map +1 -0
  80. package/dist/swagger/SwaggerGenerator.js +266 -0
  81. package/dist/swagger/SwaggerGenerator.js.map +1 -0
  82. package/dist/swagger/SwaggerUI.d.ts +30 -0
  83. package/dist/swagger/SwaggerUI.d.ts.map +1 -0
  84. package/dist/swagger/SwaggerUI.js +52 -0
  85. package/dist/swagger/SwaggerUI.js.map +1 -0
  86. package/dist/types/index.d.ts +255 -0
  87. package/dist/types/index.d.ts.map +1 -0
  88. package/dist/types/index.js +31 -0
  89. package/dist/types/index.js.map +1 -0
  90. package/package.json +52 -0
@@ -0,0 +1,132 @@
1
+ import { BaseAdapter } from "./BaseAdapter.js";
2
+ /**
3
+ * Fastify adapter implementation.
4
+ *
5
+ * Middleware Express-style dikonversi ke Fastify `preHandler` hooks.
6
+ * Handler di-await dan reply di-return untuk mencegah Fastify auto-send.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const fastify = Fastify();
11
+ * const adapter = new FastifyAdapter(fastify);
12
+ * adapter.registerRoute("get", "/hello", [], async (req, reply) => {
13
+ * reply.code(200).send({ message: "OK" });
14
+ * });
15
+ * ```
16
+ */
17
+ export class FastifyAdapter extends BaseAdapter {
18
+ app;
19
+ constructor(app) {
20
+ super();
21
+ this.app = app;
22
+ }
23
+ /**
24
+ * Fastify route handler signature berbeda dari Express.
25
+ * Middleware dikonversi ke preHandler, handler di-await.
26
+ */
27
+ registerRoute(method, path, middlewares, handler) {
28
+ const fastifyPath = path;
29
+ const routeHandler = this.app[method].bind(this.app);
30
+ const preHandlers = middlewares.map((mw) => {
31
+ return async (request, reply) => {
32
+ return new Promise((resolve, reject) => {
33
+ mw(request, reply, (err) => {
34
+ if (err)
35
+ reject(err);
36
+ else
37
+ resolve();
38
+ });
39
+ });
40
+ };
41
+ });
42
+ routeHandler(fastifyPath, { preHandler: preHandlers }, async (request, reply) => {
43
+ await handler(request, reply);
44
+ return reply;
45
+ });
46
+ }
47
+ getBody(req) {
48
+ return req.body;
49
+ }
50
+ getQuery(req) {
51
+ return req.query;
52
+ }
53
+ getParams(req) {
54
+ return req.params;
55
+ }
56
+ getHeaders(req) {
57
+ return req.headers;
58
+ }
59
+ getCookies(req) {
60
+ return req.cookies ?? {};
61
+ }
62
+ /**
63
+ * Sets a cookie on Fastify reply.
64
+ * Fallback ke manual Set-Cookie header jika `setCookie` tidak tersedia.
65
+ */
66
+ setCookie(res, key, value, options) {
67
+ const fastifyReply = res;
68
+ if (typeof fastifyReply.setCookie === "function") {
69
+ fastifyReply.setCookie(key, value, {
70
+ httpOnly: options.httpOnly,
71
+ secure: options.secure,
72
+ maxAge: options.maxAge ?? undefined,
73
+ path: options.path,
74
+ sameSite: options.sameSite,
75
+ });
76
+ }
77
+ else {
78
+ const parts = [`${key}=${value}`];
79
+ if (options.path)
80
+ parts.push(`Path=${options.path}`);
81
+ if (options.httpOnly)
82
+ parts.push("HttpOnly");
83
+ if (options.secure)
84
+ parts.push("Secure");
85
+ if (options.maxAge)
86
+ parts.push(`Max-Age=${options.maxAge}`);
87
+ if (options.sameSite)
88
+ parts.push(`SameSite=${options.sameSite}`);
89
+ fastifyReply.header("Set-Cookie", parts.join("; "));
90
+ }
91
+ }
92
+ /**
93
+ * Deletes a cookie on Fastify reply.
94
+ * Fallback ke Expires header manual jika `clearCookie` tidak tersedia.
95
+ */
96
+ deleteCookie(res, key) {
97
+ const fastifyReply = res;
98
+ if (typeof fastifyReply.clearCookie === "function") {
99
+ fastifyReply.clearCookie(key, { path: "/" });
100
+ }
101
+ else {
102
+ fastifyReply.header("Set-Cookie", `${key}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT`);
103
+ }
104
+ }
105
+ getUrl(req) {
106
+ const r = req;
107
+ return r.raw?.url || r.url || "";
108
+ }
109
+ getMethod(req) {
110
+ const r = req;
111
+ return r.raw?.method || r.method || "UNKNOWN";
112
+ }
113
+ sendResponse(res, status, body) {
114
+ const fastifyReply = res;
115
+ fastifyReply.code(status).send(body);
116
+ }
117
+ /**
118
+ * Fastify memiliki `setNotFoundHandler` native. Jika tidak ada,
119
+ * fallback ke warning — tidak runtime error.
120
+ */
121
+ registerNotFoundHandler(handler) {
122
+ if (typeof this.app.setNotFoundHandler === "function") {
123
+ this.app.setNotFoundHandler((request, reply) => {
124
+ handler(request, reply);
125
+ });
126
+ }
127
+ else {
128
+ console.warn("[RouterKit] Fastify instance is missing setNotFoundHandler. Catch-all route not registered.");
129
+ }
130
+ }
131
+ }
132
+ //# sourceMappingURL=FastifyAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FastifyAdapter.js","sourceRoot":"","sources":["../../adapters/FastifyAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import type { CookieOptions } from "../types/index.js";
2
+ import type { BaseAdapter } from "../adapters/BaseAdapter.js";
3
+ /**
4
+ * Helper class for reading, setting, and deleting cookies.
5
+ *
6
+ * Mengabstraksi operasi cookie antara Express dan Fastify melalui adapter pattern.
7
+ * Di-inject ke controller method via decorator `@Cookie()`.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * @ReqController("/auth")
12
+ * class AuthController {
13
+ * @PostMapping("/login")
14
+ * async login(@Body(LoginSchema) body: ILogin, @Cookie() cookie: CookieSetter) {
15
+ * // Set cookie
16
+ * cookie.set("refresh_token", "jwt-token", {
17
+ * httpOnly: true,
18
+ * secure: true,
19
+ * maxAge: 7 * 24 * 60 * 60, // 7 hari dalam detik
20
+ * });
21
+ *
22
+ * // Read cookie
23
+ * const existing = cookie.get("refresh_token");
24
+ *
25
+ * // Delete cookie
26
+ * cookie.delete("old_session");
27
+ * }
28
+ * }
29
+ * ```
30
+ */
31
+ export declare class CookieSetter {
32
+ private readonly adapter;
33
+ private readonly req;
34
+ private readonly res;
35
+ constructor(adapter: BaseAdapter, req: unknown, res: unknown);
36
+ /**
37
+ * Sets a cookie with the given key, value, and options.
38
+ *
39
+ * @param key - Cookie name
40
+ * @param value - Cookie value
41
+ * @param options - Cookie options (httpOnly, secure, maxAge, path, sameSite)
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * cookie.set("session", "abc123", { httpOnly: true, maxAge: 3600 });
46
+ * ```
47
+ */
48
+ set(key: string, value: string, options?: CookieOptions): void;
49
+ /**
50
+ * Gets a cookie value by key.
51
+ *
52
+ * @param key - Cookie name
53
+ * @returns The cookie value, or `undefined` if the cookie doesn't exist
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const token = cookie.get("refresh_token");
58
+ * if (token) { /* use token *\/ }
59
+ * ```
60
+ */
61
+ get(key: string): string | undefined;
62
+ /**
63
+ * Deletes a cookie by key (sets empty value with expired date).
64
+ *
65
+ * @param key - Cookie name to delete
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * cookie.delete("refresh_token");
70
+ * ```
71
+ */
72
+ delete(key: string): void;
73
+ }
74
+ //# sourceMappingURL=CookieSetter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CookieSetter.d.ts","sourceRoot":"","sources":["../../cookie/CookieSetter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAFH,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,OAAO;IAG/B;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;IAU9D;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKpC;;;;;;;;;OASG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG1B"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Helper class for reading, setting, and deleting cookies.
3
+ *
4
+ * Mengabstraksi operasi cookie antara Express dan Fastify melalui adapter pattern.
5
+ * Di-inject ke controller method via decorator `@Cookie()`.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * @ReqController("/auth")
10
+ * class AuthController {
11
+ * @PostMapping("/login")
12
+ * async login(@Body(LoginSchema) body: ILogin, @Cookie() cookie: CookieSetter) {
13
+ * // Set cookie
14
+ * cookie.set("refresh_token", "jwt-token", {
15
+ * httpOnly: true,
16
+ * secure: true,
17
+ * maxAge: 7 * 24 * 60 * 60, // 7 hari dalam detik
18
+ * });
19
+ *
20
+ * // Read cookie
21
+ * const existing = cookie.get("refresh_token");
22
+ *
23
+ * // Delete cookie
24
+ * cookie.delete("old_session");
25
+ * }
26
+ * }
27
+ * ```
28
+ */
29
+ export class CookieSetter {
30
+ adapter;
31
+ req;
32
+ res;
33
+ constructor(adapter, req, res) {
34
+ this.adapter = adapter;
35
+ this.req = req;
36
+ this.res = res;
37
+ }
38
+ /**
39
+ * Sets a cookie with the given key, value, and options.
40
+ *
41
+ * @param key - Cookie name
42
+ * @param value - Cookie value
43
+ * @param options - Cookie options (httpOnly, secure, maxAge, path, sameSite)
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * cookie.set("session", "abc123", { httpOnly: true, maxAge: 3600 });
48
+ * ```
49
+ */
50
+ set(key, value, options) {
51
+ this.adapter.setCookie(this.res, key, value, {
52
+ httpOnly: options?.httpOnly !== false,
53
+ secure: options?.secure !== false,
54
+ maxAge: options?.maxAge,
55
+ path: options?.path ?? "/",
56
+ sameSite: options?.sameSite,
57
+ });
58
+ }
59
+ /**
60
+ * Gets a cookie value by key.
61
+ *
62
+ * @param key - Cookie name
63
+ * @returns The cookie value, or `undefined` if the cookie doesn't exist
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const token = cookie.get("refresh_token");
68
+ * if (token) { /* use token *\/ }
69
+ * ```
70
+ */
71
+ get(key) {
72
+ const cookies = this.adapter.getCookies(this.req);
73
+ return cookies[key];
74
+ }
75
+ /**
76
+ * Deletes a cookie by key (sets empty value with expired date).
77
+ *
78
+ * @param key - Cookie name to delete
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * cookie.delete("refresh_token");
83
+ * ```
84
+ */
85
+ delete(key) {
86
+ this.adapter.deleteCookie(this.res, key);
87
+ }
88
+ }
89
+ //# sourceMappingURL=CookieSetter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CookieSetter.js","sourceRoot":"","sources":["../../cookie/CookieSetter.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,OAAO,YAAY;IAEJ;IACA;IACA;IAHnB,YACmB,OAAoB,EACpB,GAAY,EACZ,GAAY;QAFZ,YAAO,GAAP,OAAO,CAAa;QACpB,QAAG,GAAH,GAAG,CAAS;QACZ,QAAG,GAAH,GAAG,CAAS;IAC5B,CAAC;IAEJ;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,OAAuB;QACrD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE;YAC3C,QAAQ,EAAE,OAAO,EAAE,QAAQ,KAAK,KAAK;YACrC,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,KAAK;YACjC,MAAM,EAAE,OAAO,EAAE,MAAM;YACvB,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,GAAG;YAC1B,QAAQ,EAAE,OAAO,EAAE,QAAQ;SAC5B,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,GAAW;QACb,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;CACF"}
@@ -0,0 +1,36 @@
1
+ import type { LoggerMeta } from "../types/index.js";
2
+ /**
3
+ * Utility class for structured request logging with ANSI-colored output.
4
+ * Mendukung console logging dan custom handler untuk integrasi eksternal.
5
+ */
6
+ export declare class Logger {
7
+ /**
8
+ * Logs an HTTP request with method, URL, status code, and duration.
9
+ * Error responses (status >= 500) include the error object for debugging.
10
+ *
11
+ * @param method - HTTP method (GET, POST, dll)
12
+ * @param url - Request URL path
13
+ * @param status - HTTP response status code
14
+ * @param durationMs - Request duration in milliseconds
15
+ * @param error - Optional error object (ditampilkan jika status >= 500)
16
+ * @param customHandler - Optional custom handler untuk log ke file/service eksternal
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Default console logging
21
+ * Logger.logRequest("GET", "/users", 200, 42);
22
+ * // Output: ✅ [GET] /users - 200 (42ms)
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // Custom handler — kirim ke file atau service monitoring
28
+ * const customLogger = (level, msg, meta) => {
29
+ * fileLog.write(`[${level}] ${msg}`);
30
+ * };
31
+ * Logger.logRequest("POST", "/users", 201, 120, undefined, customLogger);
32
+ * ```
33
+ */
34
+ static logRequest(method: string, url: string, status: number, durationMs: number, error?: unknown, customHandler?: (level: "info" | "error", message: string, meta: LoggerMeta) => void): void;
35
+ }
36
+ //# sourceMappingURL=Logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../core/Logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;GAGG;AACH,qBAAa,MAAM;IACjB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,MAAM,CAAC,UAAU,CACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,OAAO,EACf,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI;CAwBvF"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Utility class for structured request logging with ANSI-colored output.
3
+ * Mendukung console logging dan custom handler untuk integrasi eksternal.
4
+ */
5
+ export class Logger {
6
+ /**
7
+ * Logs an HTTP request with method, URL, status code, and duration.
8
+ * Error responses (status >= 500) include the error object for debugging.
9
+ *
10
+ * @param method - HTTP method (GET, POST, dll)
11
+ * @param url - Request URL path
12
+ * @param status - HTTP response status code
13
+ * @param durationMs - Request duration in milliseconds
14
+ * @param error - Optional error object (ditampilkan jika status >= 500)
15
+ * @param customHandler - Optional custom handler untuk log ke file/service eksternal
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Default console logging
20
+ * Logger.logRequest("GET", "/users", 200, 42);
21
+ * // Output: ✅ [GET] /users - 200 (42ms)
22
+ * ```
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // Custom handler — kirim ke file atau service monitoring
27
+ * const customLogger = (level, msg, meta) => {
28
+ * fileLog.write(`[${level}] ${msg}`);
29
+ * };
30
+ * Logger.logRequest("POST", "/users", 201, 120, undefined, customLogger);
31
+ * ```
32
+ */
33
+ static logRequest(method, url, status, durationMs, error, customHandler) {
34
+ const isError = status >= 400;
35
+ const level = isError ? "error" : "info";
36
+ const icon = isError ? "❌" : "✅";
37
+ const reset = "\x1b[0m";
38
+ const methodColor = "\x1b[36m";
39
+ const statusColor = isError ? "\x1b[31m" : "\x1b[32m";
40
+ const timeColor = "\x1b[90m";
41
+ const methodUpper = String(method).toUpperCase();
42
+ const message = `${icon} ${methodColor}[${methodUpper}]${reset} ${url} - ${statusColor}${status}${reset} ${timeColor}(${durationMs}ms)${reset}`;
43
+ console.log(message);
44
+ if (isError && error && status >= 500) {
45
+ console.error(error);
46
+ }
47
+ if (customHandler) {
48
+ const cleanMessage = `${icon} [${methodUpper}] ${url} - ${status} (${durationMs}ms)`;
49
+ customHandler(level, cleanMessage, { method: methodUpper, path: url, status, durationMs, error });
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=Logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../core/Logger.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,MAAM;IACjB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,MAAM,CAAC,UAAU,CACf,MAAc,EACd,GAAW,EACX,MAAc,EACd,UAAkB,EAClB,KAAe,EACf,aAAoF;QAEpF,MAAM,OAAO,GAAG,MAAM,IAAI,GAAG,CAAC;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACzC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAEjC,MAAM,KAAK,GAAG,SAAS,CAAC;QACxB,MAAM,WAAW,GAAG,UAAU,CAAC;QAC/B,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;QACtD,MAAM,SAAS,GAAG,UAAU,CAAC;QAE7B,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QACjD,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,WAAW,IAAI,WAAW,IAAI,KAAK,IAAI,GAAG,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,IAAI,SAAS,IAAI,UAAU,MAAM,KAAK,EAAE,CAAC;QAEhJ,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,OAAO,IAAI,KAAK,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YACrC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,YAAY,GAAG,GAAG,IAAI,KAAK,WAAW,KAAK,GAAG,MAAM,MAAM,KAAK,UAAU,KAAK,CAAC;YACrF,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QACpG,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,91 @@
1
+ import type { MiddlewareFn, ResolvedRoute, Class } from "../types/index.js";
2
+ import type { BaseAdapter } from "../adapters/BaseAdapter.js";
3
+ /**
4
+ * Internal engine yang membaca metadata dari TC39 decorators (`Symbol.metadata`)
5
+ * dan WeakMap (parameter decorators), lalu mendaftarkan route ke framework adapter.
6
+ *
7
+ * Semua logic inti ada di sini: parameter injection, Zod validation,
8
+ * error handling, response envelope, auth middleware, dan logging.
9
+ */
10
+ export declare class RouteResolver {
11
+ private readonly adapter;
12
+ private readonly loggerConfig?;
13
+ private readonly authMiddleware?;
14
+ private readonly refreshMiddleware?;
15
+ private readonly responseEnvelope;
16
+ private readonly globalPrefix;
17
+ /** Melacak route yang sudah didaftarkan untuk deteksi duplikat */
18
+ private readonly registeredRoutes;
19
+ /** Semua route yang sudah di-resolve — digunakan untuk generate Swagger spec */
20
+ readonly resolvedRoutes: ResolvedRoute[];
21
+ /**
22
+ * @param adapter - Framework adapter (Express / Fastify)
23
+ * @param loggerConfig - Konfigurasi logger
24
+ * @param authMiddleware - Middleware untuk authentication type "auth"
25
+ * @param refreshMiddleware - Middleware untuk authentication type "refresh"
26
+ * @param responseEnvelope - Mode response wrapping ("wrap" | "raw")
27
+ * @param globalPrefix - Prefix global untuk semua route (contoh: "/api")
28
+ */
29
+ constructor(adapter: BaseAdapter, loggerConfig?: (boolean | import("../types/index.js").LoggerConfig) | undefined, authMiddleware?: MiddlewareFn | undefined, refreshMiddleware?: MiddlewareFn | undefined, responseEnvelope?: "wrap" | "raw", globalPrefix?: string);
30
+ /**
31
+ * Resolves and registers all routes from a controller class.
32
+ * Membaca metadata dari `Symbol.metadata` (TC39) dan WeakMap (parameter),
33
+ * lalu mendaftarkan setiap route ke adapter.
34
+ *
35
+ * @param Controller - Controller class yang sudah di-decorate dengan @ReqController
36
+ *
37
+ * @throws Error jika class tidak memiliki @ReqController
38
+ * @throws Error jika ditemukan duplikat route
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const resolver = new RouteResolver(adapter);
43
+ * resolver.resolve(UserController);
44
+ * ```
45
+ */
46
+ resolve(Controller: Class): void;
47
+ /**
48
+ * Registers a single route: build path, resolve auth, inject params, register to adapter.
49
+ */
50
+ private registerRoute;
51
+ /**
52
+ * Builds the full URL path from controller base path + method path + global prefix.
53
+ */
54
+ private buildFullPath;
55
+ /**
56
+ * Resolves effective auth type: method-level override, else controller-level.
57
+ */
58
+ private resolveAuthType;
59
+ /**
60
+ * Resolves authentication middleware array from auth type.
61
+ * Returns empty array if auth is disabled or middleware not configured.
62
+ */
63
+ private resolveAuthMiddleware;
64
+ /**
65
+ * Creates the route handler that manages parameter injection, response sending,
66
+ * error handling, and logging.
67
+ */
68
+ private createHandler;
69
+ /**
70
+ * Resolves parameter values from the request based on param metadata.
71
+ * Parameters are sorted by index to ensure correct order.
72
+ */
73
+ private resolveParams;
74
+ /**
75
+ * Resolves a single parameter value from the request.
76
+ * Supports: body, query, param, req, cookie, reply.
77
+ */
78
+ private resolveParam;
79
+ /**
80
+ * Validates data against a Zod schema.
81
+ * Throws BadRequestException with field-level errors on validation failure.
82
+ */
83
+ private validateWithZod;
84
+ /**
85
+ * Handles errors thrown during route execution:
86
+ * - BaseException → send with its status code
87
+ * - Unknown errors → wrap as 500 ServerErrorException
88
+ */
89
+ private handleError;
90
+ }
91
+ //# sourceMappingURL=RouteResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteResolver.d.ts","sourceRoot":"","sources":["../../core/RouteResolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAIV,YAAY,EACZ,aAAa,EACb,KAAK,EAEN,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAO9D;;;;;;GAMG;AACH,qBAAa,aAAa;IAgBtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IApB/B,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IAEtD,gFAAgF;IAChF,QAAQ,CAAC,cAAc,EAAE,aAAa,EAAE,CAAM;IAE9C;;;;;;;OAOG;gBAEgB,OAAO,EAAE,WAAW,EACpB,YAAY,CAAC,GAAE,OAAO,GAAG,OAAO,mBAAmB,EAAE,YAAY,aAAA,EACjE,cAAc,CAAC,EAAE,YAAY,YAAA,EAC7B,iBAAiB,CAAC,EAAE,YAAY,YAAA,EAChC,gBAAgB,GAAE,MAAM,GAAG,KAAc,EACzC,YAAY,GAAE,MAAW;IAG5C;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,UAAU,EAAE,KAAK,GAAG,IAAI;IAmBhC;;OAEG;IACH,OAAO,CAAC,aAAa;IAkDrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAUrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAqDrB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAWrB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAqCpB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAiBvB;;;;OAIG;IACH,OAAO,CAAC,WAAW;CAsBpB"}