azurajs 3.0.3 → 3.0.4
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 +32 -0
- package/dist/IpResolver-BVgnGnpf.d.mts +5 -0
- package/dist/IpResolver-BVgnGnpf.d.ts +5 -0
- package/dist/SwaggerPlugin-C0UZTjaZ.d.ts +6 -0
- package/dist/SwaggerPlugin-wr9S4SRG.d.mts +6 -0
- package/dist/cookies/index.d.mts +7 -0
- package/dist/cookies/index.d.ts +7 -0
- package/dist/cookies/index.js +38 -0
- package/dist/cookies/index.js.map +1 -0
- package/dist/cookies/index.mjs +35 -0
- package/dist/cookies/index.mjs.map +1 -0
- package/dist/core/index.d.mts +17 -26
- package/dist/core/index.d.ts +17 -26
- package/dist/core/index.js +214 -14
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +214 -14
- package/dist/core/index.mjs.map +1 -1
- package/dist/cors/index.d.mts +7 -0
- package/dist/cors/index.d.ts +7 -0
- package/dist/cors/index.js +52 -0
- package/dist/cors/index.js.map +1 -0
- package/dist/cors/index.mjs +50 -0
- package/dist/cors/index.mjs.map +1 -0
- package/dist/decorators/index.d.mts +2 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +25 -0
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/index.mjs +24 -1
- package/dist/decorators/index.mjs.map +1 -1
- package/dist/decorators-B6l3CbxC.d.ts +13 -0
- package/dist/decorators-D5nY109r.d.mts +13 -0
- package/dist/http-error/index.d.mts +18 -0
- package/dist/http-error/index.d.ts +18 -0
- package/dist/http-error/index.js +81 -0
- package/dist/http-error/index.js.map +1 -0
- package/dist/http-error/index.mjs +79 -0
- package/dist/http-error/index.mjs.map +1 -0
- package/dist/index-j6QGMhZU.d.mts +30 -0
- package/dist/index-tpPZS_UK.d.ts +30 -0
- package/dist/index.d.mts +15 -4
- package/dist/index.d.ts +15 -4
- package/dist/index.js +1178 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1176 -15
- package/dist/index.mjs.map +1 -1
- package/dist/infra/index.d.mts +6 -0
- package/dist/infra/index.d.ts +6 -0
- package/dist/infra/index.js +162 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/index.mjs +159 -0
- package/dist/infra/index.mjs.map +1 -0
- package/dist/plugins/index.d.mts +8 -6
- package/dist/plugins/index.d.ts +8 -6
- package/dist/plugins/index.js +1101 -0
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/index.mjs +1101 -1
- package/dist/plugins/index.mjs.map +1 -1
- package/dist/rate-limit/index.d.mts +7 -0
- package/dist/rate-limit/index.d.ts +7 -0
- package/dist/rate-limit/index.js +81 -0
- package/dist/rate-limit/index.js.map +1 -0
- package/dist/rate-limit/index.mjs +79 -0
- package/dist/rate-limit/index.mjs.map +1 -0
- package/dist/router/index.d.mts +4 -0
- package/dist/router/index.d.ts +4 -0
- package/dist/router/index.js +218 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/index.mjs +216 -0
- package/dist/router/index.mjs.map +1 -0
- package/dist/routes.type-DZO5VBW2.d.mts +58 -0
- package/dist/routes.type-DzHNkCag.d.ts +58 -0
- package/dist/swagger/index.d.mts +30 -0
- package/dist/swagger/index.d.ts +30 -0
- package/dist/swagger/index.js +1136 -0
- package/dist/swagger/index.js.map +1 -0
- package/dist/swagger/index.mjs +1126 -0
- package/dist/swagger/index.mjs.map +1 -0
- package/dist/swagger/swagger-ui-modern.html +894 -0
- package/dist/swagger.type-Bfn5nGR8.d.mts +42 -0
- package/dist/swagger.type-CfDbFCZC.d.ts +42 -0
- package/dist/types/index.d.mts +5 -58
- package/dist/types/index.d.ts +5 -58
- package/dist/utils/index.d.mts +6 -71
- package/dist/utils/index.d.ts +6 -71
- package/dist/validators/index.d.mts +48 -0
- package/dist/validators/index.d.ts +48 -0
- package/dist/validators/index.js +144 -0
- package/dist/validators/index.js.map +1 -0
- package/dist/validators/index.mjs +141 -0
- package/dist/validators/index.mjs.map +1 -0
- package/package.json +77 -2
- package/src/cookies/index.ts +1 -0
- package/src/core/index.ts +1 -0
- package/src/core/router.ts +26 -15
- package/src/core/server.ts +64 -14
- package/src/cors/index.ts +2 -0
- package/src/decorators/index.ts +2 -0
- package/src/http-error/index.ts +1 -0
- package/src/infra/index.ts +3 -0
- package/src/plugins/SwaggerPlugin.ts +45 -0
- package/src/plugins/index.ts +1 -0
- package/src/rate-limit/index.ts +2 -0
- package/src/router/index.ts +1 -0
- package/src/swagger/constants.ts +8 -0
- package/src/swagger/decorators.ts +35 -0
- package/src/swagger/index.ts +10 -0
- package/src/swagger/openapi-builder.ts +199 -0
- package/src/swagger/swagger-ui-html.ts +24 -0
- package/src/swagger/swagger-ui-modern.html +894 -0
- package/src/swagger/swagger-ui-template.ts +5 -0
- package/src/types/index.ts +7 -0
- package/src/types/swagger.type.ts +36 -0
- package/src/validators/index.ts +4 -0
package/README.md
CHANGED
|
@@ -100,6 +100,38 @@ app.listen(3000);
|
|
|
100
100
|
| `SSEPlugin` | Server-Sent Events with client management |
|
|
101
101
|
| `ProxyPlugin` | HTTP reverse proxy |
|
|
102
102
|
| `MultipartPlugin` | Multipart file upload parsing |
|
|
103
|
+
| `SwaggerPlugin` | OpenAPI 3 spec + Swagger UI (dark minimal theme, zero extra deps) |
|
|
104
|
+
|
|
105
|
+
### OpenAPI & Swagger UI
|
|
106
|
+
|
|
107
|
+
Register `SwaggerPlugin` **before** heavy middleware so `/docs` and `/openapi.json` are served. Use `@ApiTags` / `@ApiOperation` on controllers, or pass a [RouteMeta](src/types/routes.type.ts) object as the last argument to `app.get()` / `app.post()` for imperative routes.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { AzuraServer, SwaggerPlugin, ApiTags, ApiOperation, Controller, Get } from "azurats";
|
|
111
|
+
|
|
112
|
+
@Controller("/api")
|
|
113
|
+
class UsersController {
|
|
114
|
+
@ApiTags("users")
|
|
115
|
+
@ApiOperation({ summary: "List users" })
|
|
116
|
+
@Get("/")
|
|
117
|
+
list() {
|
|
118
|
+
return { users: [] };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const app = new AzuraServer();
|
|
123
|
+
app.plugin(
|
|
124
|
+
SwaggerPlugin({
|
|
125
|
+
getDocuments: () => app.getRouteDocuments(),
|
|
126
|
+
info: { title: "My API", version: "1.0.0" },
|
|
127
|
+
}),
|
|
128
|
+
);
|
|
129
|
+
app.register(UsersController);
|
|
130
|
+
// http://localhost:3000/docs — Swagger UI
|
|
131
|
+
// http://localhost:3000/openapi.json — raw OpenAPI
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If you use `HelmetPlugin` with a strict `Content-Security-Policy`, allow inline scripts for the docs path or register Swagger without CSP on `/docs`.
|
|
103
135
|
|
|
104
136
|
### Plugin Usage
|
|
105
137
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { C as CookieOptions } from '../common.type-BhGCNyEm.mjs';
|
|
2
|
+
import 'node:http';
|
|
3
|
+
|
|
4
|
+
declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
|
|
5
|
+
declare function clearCookieHeader(name: string, options?: CookieOptions): string;
|
|
6
|
+
|
|
7
|
+
export { clearCookieHeader, serializeCookie };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { C as CookieOptions } from '../common.type-BhGCNyEm.js';
|
|
2
|
+
import 'node:http';
|
|
3
|
+
|
|
4
|
+
declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
|
|
5
|
+
declare function clearCookieHeader(name: string, options?: CookieOptions): string;
|
|
6
|
+
|
|
7
|
+
export { clearCookieHeader, serializeCookie };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/utils/cookies/CookieManager.ts
|
|
4
|
+
function serializeCookie(name, value, options = {}) {
|
|
5
|
+
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
6
|
+
if (options.maxAge != null) {
|
|
7
|
+
cookie += `; Max-Age=${Math.floor(options.maxAge)}`;
|
|
8
|
+
}
|
|
9
|
+
if (options.expires) {
|
|
10
|
+
cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
11
|
+
}
|
|
12
|
+
if (options.domain) {
|
|
13
|
+
cookie += `; Domain=${options.domain}`;
|
|
14
|
+
}
|
|
15
|
+
cookie += `; Path=${options.path ?? "/"}`;
|
|
16
|
+
if (options.secure) {
|
|
17
|
+
cookie += "; Secure";
|
|
18
|
+
}
|
|
19
|
+
if (options.httpOnly !== false) {
|
|
20
|
+
cookie += "; HttpOnly";
|
|
21
|
+
}
|
|
22
|
+
if (options.sameSite) {
|
|
23
|
+
cookie += `; SameSite=${options.sameSite}`;
|
|
24
|
+
}
|
|
25
|
+
return cookie;
|
|
26
|
+
}
|
|
27
|
+
function clearCookieHeader(name, options = {}) {
|
|
28
|
+
return serializeCookie(name, "", {
|
|
29
|
+
...options,
|
|
30
|
+
maxAge: 0,
|
|
31
|
+
expires: /* @__PURE__ */ new Date(0)
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
exports.clearCookieHeader = clearCookieHeader;
|
|
36
|
+
exports.serializeCookie = serializeCookie;
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cookies/CookieManager.ts"],"names":[],"mappings":";;;AAEO,SAAS,eAAA,CACd,IAAA,EACA,KAAA,EACA,OAAA,GAAyB,EAAC,EAClB;AACR,EAAA,IAAI,MAAA,GAAS,GAAG,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA,EAAI,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAErE,EAAA,IAAI,OAAA,CAAQ,UAAU,IAAA,EAAM;AAC1B,IAAA,MAAA,IAAU,CAAA,UAAA,EAAa,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAC,CAAA,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,MAAA,IAAU,CAAA,UAAA,EAAa,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA;AAAA,EACtD;AAEA,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,MAAA,IAAU,CAAA,SAAA,EAAY,QAAQ,MAAM,CAAA,CAAA;AAAA,EACtC;AAEA,EAAA,MAAA,IAAU,CAAA,OAAA,EAAU,OAAA,CAAQ,IAAA,IAAQ,GAAG,CAAA,CAAA;AAEvC,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,MAAA,IAAU,UAAA;AAAA,EACZ;AAEA,EAAA,IAAI,OAAA,CAAQ,aAAa,KAAA,EAAO;AAC9B,IAAA,MAAA,IAAU,YAAA;AAAA,EACZ;AAEA,EAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,IAAA,MAAA,IAAU,CAAA,WAAA,EAAc,QAAQ,QAAQ,CAAA,CAAA;AAAA,EAC1C;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,iBAAA,CACd,IAAA,EACA,OAAA,GAAyB,EAAC,EAClB;AACR,EAAA,OAAO,eAAA,CAAgB,MAAM,EAAA,EAAI;AAAA,IAC/B,GAAG,OAAA;AAAA,IACH,MAAA,EAAQ,CAAA;AAAA,IACR,OAAA,kBAAS,IAAI,IAAA,CAAK,CAAC;AAAA,GACpB,CAAA;AACH","file":"index.js","sourcesContent":["import type { CookieOptions } from \"../../types/common.type.js\";\r\n\r\nexport function serializeCookie(\r\n name: string,\r\n value: string,\r\n options: CookieOptions = {},\r\n): string {\r\n let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;\r\n\r\n if (options.maxAge != null) {\r\n cookie += `; Max-Age=${Math.floor(options.maxAge)}`;\r\n }\r\n\r\n if (options.expires) {\r\n cookie += `; Expires=${options.expires.toUTCString()}`;\r\n }\r\n\r\n if (options.domain) {\r\n cookie += `; Domain=${options.domain}`;\r\n }\r\n\r\n cookie += `; Path=${options.path ?? \"/\"}`;\r\n\r\n if (options.secure) {\r\n cookie += \"; Secure\";\r\n }\r\n\r\n if (options.httpOnly !== false) {\r\n cookie += \"; HttpOnly\";\r\n }\r\n\r\n if (options.sameSite) {\r\n cookie += `; SameSite=${options.sameSite}`;\r\n }\r\n\r\n return cookie;\r\n}\r\n\r\nexport function clearCookieHeader(\r\n name: string,\r\n options: CookieOptions = {},\r\n): string {\r\n return serializeCookie(name, \"\", {\r\n ...options,\r\n maxAge: 0,\r\n expires: new Date(0),\r\n });\r\n}\r\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/utils/cookies/CookieManager.ts
|
|
2
|
+
function serializeCookie(name, value, options = {}) {
|
|
3
|
+
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
4
|
+
if (options.maxAge != null) {
|
|
5
|
+
cookie += `; Max-Age=${Math.floor(options.maxAge)}`;
|
|
6
|
+
}
|
|
7
|
+
if (options.expires) {
|
|
8
|
+
cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
9
|
+
}
|
|
10
|
+
if (options.domain) {
|
|
11
|
+
cookie += `; Domain=${options.domain}`;
|
|
12
|
+
}
|
|
13
|
+
cookie += `; Path=${options.path ?? "/"}`;
|
|
14
|
+
if (options.secure) {
|
|
15
|
+
cookie += "; Secure";
|
|
16
|
+
}
|
|
17
|
+
if (options.httpOnly !== false) {
|
|
18
|
+
cookie += "; HttpOnly";
|
|
19
|
+
}
|
|
20
|
+
if (options.sameSite) {
|
|
21
|
+
cookie += `; SameSite=${options.sameSite}`;
|
|
22
|
+
}
|
|
23
|
+
return cookie;
|
|
24
|
+
}
|
|
25
|
+
function clearCookieHeader(name, options = {}) {
|
|
26
|
+
return serializeCookie(name, "", {
|
|
27
|
+
...options,
|
|
28
|
+
maxAge: 0,
|
|
29
|
+
expires: /* @__PURE__ */ new Date(0)
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { clearCookieHeader, serializeCookie };
|
|
34
|
+
//# sourceMappingURL=index.mjs.map
|
|
35
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cookies/CookieManager.ts"],"names":[],"mappings":";AAEO,SAAS,eAAA,CACd,IAAA,EACA,KAAA,EACA,OAAA,GAAyB,EAAC,EAClB;AACR,EAAA,IAAI,MAAA,GAAS,GAAG,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA,EAAI,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAErE,EAAA,IAAI,OAAA,CAAQ,UAAU,IAAA,EAAM;AAC1B,IAAA,MAAA,IAAU,CAAA,UAAA,EAAa,IAAA,CAAK,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAC,CAAA,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,MAAA,IAAU,CAAA,UAAA,EAAa,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA;AAAA,EACtD;AAEA,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,MAAA,IAAU,CAAA,SAAA,EAAY,QAAQ,MAAM,CAAA,CAAA;AAAA,EACtC;AAEA,EAAA,MAAA,IAAU,CAAA,OAAA,EAAU,OAAA,CAAQ,IAAA,IAAQ,GAAG,CAAA,CAAA;AAEvC,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,MAAA,IAAU,UAAA;AAAA,EACZ;AAEA,EAAA,IAAI,OAAA,CAAQ,aAAa,KAAA,EAAO;AAC9B,IAAA,MAAA,IAAU,YAAA;AAAA,EACZ;AAEA,EAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,IAAA,MAAA,IAAU,CAAA,WAAA,EAAc,QAAQ,QAAQ,CAAA,CAAA;AAAA,EAC1C;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,iBAAA,CACd,IAAA,EACA,OAAA,GAAyB,EAAC,EAClB;AACR,EAAA,OAAO,eAAA,CAAgB,MAAM,EAAA,EAAI;AAAA,IAC/B,GAAG,OAAA;AAAA,IACH,MAAA,EAAQ,CAAA;AAAA,IACR,OAAA,kBAAS,IAAI,IAAA,CAAK,CAAC;AAAA,GACpB,CAAA;AACH","file":"index.mjs","sourcesContent":["import type { CookieOptions } from \"../../types/common.type.js\";\r\n\r\nexport function serializeCookie(\r\n name: string,\r\n value: string,\r\n options: CookieOptions = {},\r\n): string {\r\n let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;\r\n\r\n if (options.maxAge != null) {\r\n cookie += `; Max-Age=${Math.floor(options.maxAge)}`;\r\n }\r\n\r\n if (options.expires) {\r\n cookie += `; Expires=${options.expires.toUTCString()}`;\r\n }\r\n\r\n if (options.domain) {\r\n cookie += `; Domain=${options.domain}`;\r\n }\r\n\r\n cookie += `; Path=${options.path ?? \"/\"}`;\r\n\r\n if (options.secure) {\r\n cookie += \"; Secure\";\r\n }\r\n\r\n if (options.httpOnly !== false) {\r\n cookie += \"; HttpOnly\";\r\n }\r\n\r\n if (options.sameSite) {\r\n cookie += `; SameSite=${options.sameSite}`;\r\n }\r\n\r\n return cookie;\r\n}\r\n\r\nexport function clearCookieHeader(\r\n name: string,\r\n options: CookieOptions = {},\r\n): string {\r\n return serializeCookie(name, \"\", {\r\n ...options,\r\n maxAge: 0,\r\n expires: new Date(0),\r\n });\r\n}\r\n"]}
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
|
+
import { R as Router, a as RouteDocument } from '../index-j6QGMhZU.mjs';
|
|
1
2
|
import { Server } from 'node:http';
|
|
2
|
-
import { H as HttpMethod, R as RouteHandler, M as MiddlewareHandler, b as RouteMatch, E as ErrorHandler } from '../common.type-BhGCNyEm.mjs';
|
|
3
3
|
import { Logger } from '../logger/index.mjs';
|
|
4
|
+
import { M as MiddlewareHandler, E as ErrorHandler, H as HttpMethod } from '../common.type-BhGCNyEm.mjs';
|
|
4
5
|
import { A as AzuraConfig } from '../config.type-4K-xcMSy.mjs';
|
|
5
6
|
import { g as PluginHandler } from '../plugin.type-BNooWhKa.mjs';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
private root;
|
|
9
|
-
private cache;
|
|
10
|
-
private staticRoutes;
|
|
11
|
-
constructor(cacheSize?: number);
|
|
12
|
-
add(method: HttpMethod, path: string, handler: RouteHandler, middlewares?: MiddlewareHandler[], meta?: Record<string, any>): void;
|
|
13
|
-
find(method: HttpMethod, path: string): RouteMatch | null;
|
|
14
|
-
private matchNode;
|
|
15
|
-
private normalizePath;
|
|
16
|
-
getAllRoutes(): Array<{
|
|
17
|
-
method: HttpMethod;
|
|
18
|
-
path: string;
|
|
19
|
-
}>;
|
|
20
|
-
private collectRoutes;
|
|
21
|
-
}
|
|
7
|
+
import { d as RouteMeta } from '../routes.type-DZO5VBW2.mjs';
|
|
8
|
+
import { B as BuildOpenApiOptions } from '../swagger.type-Bfn5nGR8.mjs';
|
|
22
9
|
|
|
23
10
|
declare class AzuraServer {
|
|
24
11
|
private server;
|
|
@@ -33,14 +20,14 @@ declare class AzuraServer {
|
|
|
33
20
|
use(handler: MiddlewareHandler | PluginHandler): this;
|
|
34
21
|
plugin(handler: PluginHandler): this;
|
|
35
22
|
onError(handler: ErrorHandler): this;
|
|
36
|
-
get(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
37
|
-
post(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
38
|
-
put(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
39
|
-
delete(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
40
|
-
patch(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
41
|
-
head(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
42
|
-
options(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
43
|
-
all(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
23
|
+
get(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
24
|
+
post(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
25
|
+
put(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
26
|
+
delete(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
27
|
+
patch(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
28
|
+
head(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
29
|
+
options(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
30
|
+
all(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
44
31
|
private route;
|
|
45
32
|
register(...controllers: (new (...args: any[]) => any)[]): this;
|
|
46
33
|
private registerController;
|
|
@@ -60,6 +47,10 @@ declare class AzuraServer {
|
|
|
60
47
|
method: HttpMethod;
|
|
61
48
|
path: string;
|
|
62
49
|
}>;
|
|
50
|
+
/** Rotas com metadados OpenAPI (para Swagger ou export manual). */
|
|
51
|
+
getRouteDocuments(): RouteDocument[];
|
|
52
|
+
/** Gera documento OpenAPI 3.0 a partir das rotas registadas. */
|
|
53
|
+
getOpenApiDocument(options?: BuildOpenApiOptions): Record<string, unknown>;
|
|
63
54
|
}
|
|
64
55
|
|
|
65
|
-
export { AzuraServer, Router };
|
|
56
|
+
export { AzuraServer, RouteDocument, Router };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
|
+
import { R as Router, a as RouteDocument } from '../index-tpPZS_UK.js';
|
|
1
2
|
import { Server } from 'node:http';
|
|
2
|
-
import { H as HttpMethod, R as RouteHandler, M as MiddlewareHandler, b as RouteMatch, E as ErrorHandler } from '../common.type-BhGCNyEm.js';
|
|
3
3
|
import { Logger } from '../logger/index.js';
|
|
4
|
+
import { M as MiddlewareHandler, E as ErrorHandler, H as HttpMethod } from '../common.type-BhGCNyEm.js';
|
|
4
5
|
import { A as AzuraConfig } from '../config.type-s3ImgfM_.js';
|
|
5
6
|
import { g as PluginHandler } from '../plugin.type-D4HHceYz.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
private root;
|
|
9
|
-
private cache;
|
|
10
|
-
private staticRoutes;
|
|
11
|
-
constructor(cacheSize?: number);
|
|
12
|
-
add(method: HttpMethod, path: string, handler: RouteHandler, middlewares?: MiddlewareHandler[], meta?: Record<string, any>): void;
|
|
13
|
-
find(method: HttpMethod, path: string): RouteMatch | null;
|
|
14
|
-
private matchNode;
|
|
15
|
-
private normalizePath;
|
|
16
|
-
getAllRoutes(): Array<{
|
|
17
|
-
method: HttpMethod;
|
|
18
|
-
path: string;
|
|
19
|
-
}>;
|
|
20
|
-
private collectRoutes;
|
|
21
|
-
}
|
|
7
|
+
import { d as RouteMeta } from '../routes.type-DzHNkCag.js';
|
|
8
|
+
import { B as BuildOpenApiOptions } from '../swagger.type-CfDbFCZC.js';
|
|
22
9
|
|
|
23
10
|
declare class AzuraServer {
|
|
24
11
|
private server;
|
|
@@ -33,14 +20,14 @@ declare class AzuraServer {
|
|
|
33
20
|
use(handler: MiddlewareHandler | PluginHandler): this;
|
|
34
21
|
plugin(handler: PluginHandler): this;
|
|
35
22
|
onError(handler: ErrorHandler): this;
|
|
36
|
-
get(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
37
|
-
post(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
38
|
-
put(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
39
|
-
delete(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
40
|
-
patch(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
41
|
-
head(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
42
|
-
options(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
43
|
-
all(path: string, ...handlers: (MiddlewareHandler | Function)[]): this;
|
|
23
|
+
get(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
24
|
+
post(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
25
|
+
put(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
26
|
+
delete(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
27
|
+
patch(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
28
|
+
head(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
29
|
+
options(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
30
|
+
all(path: string, ...handlers: (MiddlewareHandler | Function | RouteMeta)[]): this;
|
|
44
31
|
private route;
|
|
45
32
|
register(...controllers: (new (...args: any[]) => any)[]): this;
|
|
46
33
|
private registerController;
|
|
@@ -60,6 +47,10 @@ declare class AzuraServer {
|
|
|
60
47
|
method: HttpMethod;
|
|
61
48
|
path: string;
|
|
62
49
|
}>;
|
|
50
|
+
/** Rotas com metadados OpenAPI (para Swagger ou export manual). */
|
|
51
|
+
getRouteDocuments(): RouteDocument[];
|
|
52
|
+
/** Gera documento OpenAPI 3.0 a partir das rotas registadas. */
|
|
53
|
+
getOpenApiDocument(options?: BuildOpenApiOptions): Record<string, unknown>;
|
|
63
54
|
}
|
|
64
55
|
|
|
65
|
-
export { AzuraServer, Router };
|
|
56
|
+
export { AzuraServer, RouteDocument, Router };
|
package/dist/core/index.js
CHANGED
|
@@ -183,31 +183,37 @@ var Router = class {
|
|
|
183
183
|
return path;
|
|
184
184
|
}
|
|
185
185
|
getAllRoutes() {
|
|
186
|
+
return this.getRouteDocuments().map(({ method, path }) => ({ method, path }));
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Todas as rotas com metadados (ex.: OpenAPI) associados ao handler.
|
|
190
|
+
*/
|
|
191
|
+
getRouteDocuments() {
|
|
186
192
|
const routes = [];
|
|
187
|
-
for (const [key] of this.staticRoutes) {
|
|
193
|
+
for (const [key, stored] of this.staticRoutes) {
|
|
188
194
|
const [method, path] = key.split(":", 2);
|
|
189
|
-
routes.push({ method, path });
|
|
195
|
+
routes.push({ method, path, meta: stored.meta });
|
|
190
196
|
}
|
|
191
|
-
this.
|
|
197
|
+
this.collectRoutesWithMeta(this.root, "", routes);
|
|
192
198
|
return routes;
|
|
193
199
|
}
|
|
194
|
-
|
|
195
|
-
for (const [method] of node.handlers) {
|
|
196
|
-
routes.push({ method, path: prefix || "/" });
|
|
200
|
+
collectRoutesWithMeta(node, prefix, routes) {
|
|
201
|
+
for (const [method, stored] of node.handlers) {
|
|
202
|
+
routes.push({ method, path: prefix || "/", meta: stored.meta });
|
|
197
203
|
}
|
|
198
204
|
for (const [seg, child] of node.children) {
|
|
199
|
-
this.
|
|
205
|
+
this.collectRoutesWithMeta(child, `${prefix}/${seg}`, routes);
|
|
200
206
|
}
|
|
201
207
|
if (node.paramChild) {
|
|
202
|
-
this.
|
|
208
|
+
this.collectRoutesWithMeta(
|
|
203
209
|
node.paramChild,
|
|
204
210
|
`${prefix}/:${node.paramChild.paramName}`,
|
|
205
211
|
routes
|
|
206
212
|
);
|
|
207
213
|
}
|
|
208
214
|
if (node.wildcardHandler) {
|
|
209
|
-
for (const [method] of node.wildcardHandler) {
|
|
210
|
-
routes.push({ method, path: `${prefix}
|
|
215
|
+
for (const [method, stored] of node.wildcardHandler) {
|
|
216
|
+
routes.push({ method, path: `${prefix}/*`, meta: stored.meta });
|
|
211
217
|
}
|
|
212
218
|
}
|
|
213
219
|
}
|
|
@@ -615,7 +621,174 @@ function clearCookieHeader(name, options = {}) {
|
|
|
615
621
|
});
|
|
616
622
|
}
|
|
617
623
|
|
|
624
|
+
// src/swagger/constants.ts
|
|
625
|
+
var API_TAGS_KEY = "azura:api-tags";
|
|
626
|
+
var METHOD_TAGS_KEY = "azura:swagger-method-tags";
|
|
627
|
+
var API_OPERATION_KEY = "azura:swagger-operation";
|
|
628
|
+
|
|
629
|
+
// src/swagger/openapi-builder.ts
|
|
630
|
+
function resolveInfo(options) {
|
|
631
|
+
return options.info ?? {
|
|
632
|
+
title: "AzuraJS API",
|
|
633
|
+
version: "1.0.0",
|
|
634
|
+
description: "Generated OpenAPI specification"
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
function toOpenApiPath(path) {
|
|
638
|
+
if (path === "/") return "/";
|
|
639
|
+
const mapped = path.split("/").map((seg) => {
|
|
640
|
+
if (seg === "*") return "{wildcard}";
|
|
641
|
+
return seg.startsWith(":") ? `{${seg.slice(1)}}` : seg;
|
|
642
|
+
}).join("/").replace(/\/{2,}/g, "/");
|
|
643
|
+
if (mapped.endsWith("/*")) {
|
|
644
|
+
return mapped.slice(0, -2) + "/{wildcard}";
|
|
645
|
+
}
|
|
646
|
+
return mapped;
|
|
647
|
+
}
|
|
648
|
+
function pathParametersFromTemplate(path) {
|
|
649
|
+
const re = /\{([^}]+)\}/g;
|
|
650
|
+
const out = [];
|
|
651
|
+
let m;
|
|
652
|
+
const seen = /* @__PURE__ */ new Set();
|
|
653
|
+
while ((m = re.exec(path)) !== null) {
|
|
654
|
+
const name = m[1];
|
|
655
|
+
if (seen.has(name)) continue;
|
|
656
|
+
seen.add(name);
|
|
657
|
+
out.push({
|
|
658
|
+
name,
|
|
659
|
+
in: "path",
|
|
660
|
+
required: true,
|
|
661
|
+
schema: { type: "string" }
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
return out;
|
|
665
|
+
}
|
|
666
|
+
function defaultResponses(meta) {
|
|
667
|
+
if (meta?.responses && Object.keys(meta.responses).length > 0) {
|
|
668
|
+
const out = {};
|
|
669
|
+
for (const [code, r] of Object.entries(meta.responses)) {
|
|
670
|
+
out[String(code)] = {
|
|
671
|
+
description: r.description,
|
|
672
|
+
...r.schema ? { content: { "application/json": { schema: r.schema } } } : {}
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
return out;
|
|
676
|
+
}
|
|
677
|
+
return {
|
|
678
|
+
"200": {
|
|
679
|
+
description: "Successful response",
|
|
680
|
+
content: {
|
|
681
|
+
"application/json": {
|
|
682
|
+
schema: { type: "object", additionalProperties: true }
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
function mergeParameters(meta, pathParams) {
|
|
689
|
+
const fromMeta = meta?.parameters ?? [];
|
|
690
|
+
const names = new Set(pathParams.map((p) => p.name));
|
|
691
|
+
const rest = fromMeta.filter((p) => !(p.in === "path" && names.has(p.name)));
|
|
692
|
+
const mapped = fromMeta.filter((p) => p.in === "path").map((p) => ({
|
|
693
|
+
name: p.name,
|
|
694
|
+
in: "path",
|
|
695
|
+
required: p.required ?? true,
|
|
696
|
+
description: p.description,
|
|
697
|
+
schema: p.schema ?? { type: p.type ?? "string" }
|
|
698
|
+
}));
|
|
699
|
+
const pathMerged = [...pathParams];
|
|
700
|
+
for (const m of mapped) {
|
|
701
|
+
if (!pathMerged.find((x) => x.name === m.name)) pathMerged.push(m);
|
|
702
|
+
}
|
|
703
|
+
return [...pathMerged, ...rest.map((p) => mapParameter(p))];
|
|
704
|
+
}
|
|
705
|
+
function mapParameter(p) {
|
|
706
|
+
const base = {
|
|
707
|
+
name: p.name,
|
|
708
|
+
in: p.in,
|
|
709
|
+
required: p.required ?? (p.in === "path" ? true : false),
|
|
710
|
+
description: p.description
|
|
711
|
+
};
|
|
712
|
+
if (p.in === "body") {
|
|
713
|
+
return {
|
|
714
|
+
...base,
|
|
715
|
+
content: {
|
|
716
|
+
"application/json": {
|
|
717
|
+
schema: p.schema ?? { type: "object" }
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
return {
|
|
723
|
+
...base,
|
|
724
|
+
schema: p.schema ?? { type: p.type ?? "string" }
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
function operationIdFor(method, oPath) {
|
|
728
|
+
const slug = oPath.replace(/[/{}\-*]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
729
|
+
return `${method.toLowerCase()}_${slug || "root"}`;
|
|
730
|
+
}
|
|
731
|
+
function operationForMethod(method, oPath, meta) {
|
|
732
|
+
const op = {
|
|
733
|
+
operationId: operationIdFor(method, oPath),
|
|
734
|
+
summary: meta?.summary ?? `${method} ${oPath}`,
|
|
735
|
+
...meta?.description ? { description: meta.description } : {},
|
|
736
|
+
...meta?.deprecated ? { deprecated: true } : {},
|
|
737
|
+
...meta?.tags?.length ? { tags: meta.tags } : {},
|
|
738
|
+
...meta?.security?.length ? { security: meta.security } : {}
|
|
739
|
+
};
|
|
740
|
+
if (["POST", "PUT", "PATCH"].includes(method) && !meta?.parameters?.some((x) => x.in === "body")) {
|
|
741
|
+
op.requestBody = {
|
|
742
|
+
content: {
|
|
743
|
+
"application/json": {
|
|
744
|
+
schema: { type: "object", additionalProperties: true }
|
|
745
|
+
}
|
|
746
|
+
},
|
|
747
|
+
required: false
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
op.responses = defaultResponses(meta);
|
|
751
|
+
return op;
|
|
752
|
+
}
|
|
753
|
+
function buildOpenApiDocument(routes, options) {
|
|
754
|
+
const info = resolveInfo(options);
|
|
755
|
+
const prefix = options.pathPrefix ?? "";
|
|
756
|
+
const paths = {};
|
|
757
|
+
const seen = /* @__PURE__ */ new Set();
|
|
758
|
+
for (const r of routes) {
|
|
759
|
+
const full = prefix + r.path;
|
|
760
|
+
const oPath = toOpenApiPath(full);
|
|
761
|
+
const key = `${r.method}:${oPath}`;
|
|
762
|
+
if (seen.has(key)) continue;
|
|
763
|
+
seen.add(key);
|
|
764
|
+
const pathParams = pathParametersFromTemplate(oPath);
|
|
765
|
+
const op = operationForMethod(r.method, oPath, r.meta);
|
|
766
|
+
const parameters = mergeParameters(r.meta, pathParams);
|
|
767
|
+
if (parameters.length) op.parameters = parameters;
|
|
768
|
+
const methodLc = r.method.toLowerCase();
|
|
769
|
+
if (!paths[oPath]) paths[oPath] = {};
|
|
770
|
+
paths[oPath][methodLc] = op;
|
|
771
|
+
}
|
|
772
|
+
return {
|
|
773
|
+
openapi: "3.0.3",
|
|
774
|
+
info: {
|
|
775
|
+
title: info.title,
|
|
776
|
+
version: info.version,
|
|
777
|
+
...info.description ? { description: info.description } : {},
|
|
778
|
+
...info.contact ? { contact: info.contact } : {},
|
|
779
|
+
...info.license ? { license: info.license } : {}
|
|
780
|
+
},
|
|
781
|
+
...options.servers?.length ? { servers: options.servers } : {},
|
|
782
|
+
paths
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
|
|
618
786
|
// src/core/server.ts
|
|
787
|
+
function isRouteDocumentMeta(o) {
|
|
788
|
+
if (!o || typeof o !== "object" || Array.isArray(o)) return false;
|
|
789
|
+
const x = o;
|
|
790
|
+
return "summary" in x || "description" in x || "tags" in x || "deprecated" in x || "parameters" in x || "responses" in x || "security" in x || "produces" in x || "consumes" in x;
|
|
791
|
+
}
|
|
619
792
|
var CONTROLLER_META_KEY = "azura:controller";
|
|
620
793
|
var ROUTES_META_KEY = "azura:routes";
|
|
621
794
|
var PARAMS_META_KEY = "azura:params";
|
|
@@ -704,9 +877,19 @@ var AzuraServer = class {
|
|
|
704
877
|
return this;
|
|
705
878
|
}
|
|
706
879
|
route(method, path, handlers) {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
880
|
+
let meta;
|
|
881
|
+
let list = handlers;
|
|
882
|
+
const last = list[list.length - 1];
|
|
883
|
+
if (list.length >= 2 && isRouteDocumentMeta(last)) {
|
|
884
|
+
meta = last;
|
|
885
|
+
list = list.slice(0, -1);
|
|
886
|
+
}
|
|
887
|
+
if (list.length === 0) {
|
|
888
|
+
throw new Error(`Route ${method} ${path} requires a handler function`);
|
|
889
|
+
}
|
|
890
|
+
const routeHandler = list[list.length - 1];
|
|
891
|
+
const middlewares = list.slice(0, -1);
|
|
892
|
+
this.router.add(method, path, routeHandler, middlewares, meta);
|
|
710
893
|
return this;
|
|
711
894
|
}
|
|
712
895
|
register(...controllers) {
|
|
@@ -719,6 +902,7 @@ var AzuraServer = class {
|
|
|
719
902
|
const instance = new Controller();
|
|
720
903
|
const prefix = Reflect.getMetadata?.(CONTROLLER_META_KEY, Controller) ?? "";
|
|
721
904
|
const controllerMiddlewares = Reflect.getMetadata?.("azura:middlewares", Controller) ?? [];
|
|
905
|
+
const controllerTags = Reflect.getMetadata?.(API_TAGS_KEY, Controller) ?? [];
|
|
722
906
|
const prototype = Controller.prototype;
|
|
723
907
|
const propertyNames = Object.getOwnPropertyNames(prototype).filter(
|
|
724
908
|
(p) => p !== "constructor"
|
|
@@ -734,6 +918,14 @@ var AzuraServer = class {
|
|
|
734
918
|
const paramsMeta = Reflect.getMetadata?.(PARAMS_META_KEY, prototype, propertyKey) ?? [];
|
|
735
919
|
const routeMiddlewares = Reflect.getMetadata?.("azura:middlewares", prototype, propertyKey) ?? [];
|
|
736
920
|
const allMiddlewares = [...controllerMiddlewares, ...routeMiddlewares];
|
|
921
|
+
const methodTags = Reflect.getMetadata?.(METHOD_TAGS_KEY, prototype, propertyKey) ?? [];
|
|
922
|
+
const opExtra = Reflect.getMetadata?.(API_OPERATION_KEY, prototype, propertyKey) ?? {};
|
|
923
|
+
const tagList = [...controllerTags, ...methodTags, ...routeMeta.meta?.tags ?? []];
|
|
924
|
+
const mergedMeta = (() => {
|
|
925
|
+
const m = { ...routeMeta.meta, ...opExtra };
|
|
926
|
+
if (tagList.length) m.tags = tagList;
|
|
927
|
+
return Object.keys(m).length ? m : void 0;
|
|
928
|
+
})();
|
|
737
929
|
const handler = async (req, res) => {
|
|
738
930
|
const args = this.resolveParams(paramsMeta, req, res);
|
|
739
931
|
const result = await instance[propertyKey](...args);
|
|
@@ -745,7 +937,7 @@ var AzuraServer = class {
|
|
|
745
937
|
}
|
|
746
938
|
}
|
|
747
939
|
};
|
|
748
|
-
this.router.add(routeMeta.method, fullPath, handler, allMiddlewares,
|
|
940
|
+
this.router.add(routeMeta.method, fullPath, handler, allMiddlewares, mergedMeta);
|
|
749
941
|
}
|
|
750
942
|
}
|
|
751
943
|
resolveParams(paramsMeta, req, res) {
|
|
@@ -1099,6 +1291,14 @@ var AzuraServer = class {
|
|
|
1099
1291
|
getRoutes() {
|
|
1100
1292
|
return this.router.getAllRoutes();
|
|
1101
1293
|
}
|
|
1294
|
+
/** Rotas com metadados OpenAPI (para Swagger ou export manual). */
|
|
1295
|
+
getRouteDocuments() {
|
|
1296
|
+
return this.router.getRouteDocuments();
|
|
1297
|
+
}
|
|
1298
|
+
/** Gera documento OpenAPI 3.0 a partir das rotas registadas. */
|
|
1299
|
+
getOpenApiDocument(options = {}) {
|
|
1300
|
+
return buildOpenApiDocument(this.getRouteDocuments(), options);
|
|
1301
|
+
}
|
|
1102
1302
|
};
|
|
1103
1303
|
|
|
1104
1304
|
exports.AzuraServer = AzuraServer;
|