sashiko 0.0.0-stage → 0.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/LICENSE +15 -0
- package/README.md +398 -2
- package/dist/core/app.d.ts +104 -0
- package/dist/core/app.d.ts.map +1 -0
- package/dist/core/app.js +202 -0
- package/dist/core/app.js.map +1 -0
- package/dist/core/body-parser.d.ts +4 -0
- package/dist/core/body-parser.d.ts.map +1 -0
- package/dist/core/body-parser.js +38 -0
- package/dist/core/body-parser.js.map +1 -0
- package/dist/core/compiler.d.ts +52 -0
- package/dist/core/compiler.d.ts.map +1 -0
- package/dist/core/compiler.js +74 -0
- package/dist/core/compiler.js.map +1 -0
- package/dist/core/compose.d.ts +4 -0
- package/dist/core/compose.d.ts.map +1 -0
- package/dist/core/compose.js +11 -0
- package/dist/core/compose.js.map +1 -0
- package/dist/core/context.d.ts +84 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +121 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/errors.d.ts +24 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +23 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/guard.d.ts +10 -0
- package/dist/core/guard.d.ts.map +1 -0
- package/dist/core/guard.js +12 -0
- package/dist/core/guard.js.map +1 -0
- package/dist/core/index.d.ts +15 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/infer.d.ts +36 -0
- package/dist/core/infer.d.ts.map +1 -0
- package/dist/core/infer.js +2 -0
- package/dist/core/infer.js.map +1 -0
- package/dist/core/inject.d.ts +27 -0
- package/dist/core/inject.d.ts.map +1 -0
- package/dist/core/inject.js +72 -0
- package/dist/core/inject.js.map +1 -0
- package/dist/core/logger.d.ts +28 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +27 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/metadata.d.ts +59 -0
- package/dist/core/metadata.d.ts.map +1 -0
- package/dist/core/metadata.js +83 -0
- package/dist/core/metadata.js.map +1 -0
- package/dist/core/mounted-group.d.ts +41 -0
- package/dist/core/mounted-group.d.ts.map +1 -0
- package/dist/core/mounted-group.js +43 -0
- package/dist/core/mounted-group.js.map +1 -0
- package/dist/core/request-validation.d.ts +11 -0
- package/dist/core/request-validation.d.ts.map +1 -0
- package/dist/core/request-validation.js +30 -0
- package/dist/core/request-validation.js.map +1 -0
- package/dist/core/response.d.ts +16 -0
- package/dist/core/response.d.ts.map +1 -0
- package/dist/core/response.js +49 -0
- package/dist/core/response.js.map +1 -0
- package/dist/core/route-table.d.ts +29 -0
- package/dist/core/route-table.d.ts.map +1 -0
- package/dist/core/route-table.js +41 -0
- package/dist/core/route-table.js.map +1 -0
- package/dist/decorators/http.d.ts +16 -0
- package/dist/decorators/http.d.ts.map +1 -0
- package/dist/decorators/http.js +27 -0
- package/dist/decorators/http.js.map +1 -0
- package/dist/decorators/index.d.ts +6 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +6 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/log.d.ts +10 -0
- package/dist/decorators/log.d.ts.map +1 -0
- package/dist/decorators/log.js +32 -0
- package/dist/decorators/log.js.map +1 -0
- package/dist/decorators/middlewares.d.ts +28 -0
- package/dist/decorators/middlewares.d.ts.map +1 -0
- package/dist/decorators/middlewares.js +40 -0
- package/dist/decorators/middlewares.js.map +1 -0
- package/dist/decorators/router.d.ts +12 -0
- package/dist/decorators/router.d.ts.map +1 -0
- package/dist/decorators/router.js +19 -0
- package/dist/decorators/router.js.map +1 -0
- package/dist/decorators/schema.d.ts +8 -0
- package/dist/decorators/schema.d.ts.map +1 -0
- package/dist/decorators/schema.js +13 -0
- package/dist/decorators/schema.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/middlewares/cors.d.ts +24 -0
- package/dist/middlewares/cors.d.ts.map +1 -0
- package/dist/middlewares/cors.js +63 -0
- package/dist/middlewares/cors.js.map +1 -0
- package/dist/middlewares/index.d.ts +4 -0
- package/dist/middlewares/index.d.ts.map +1 -0
- package/dist/middlewares/index.js +4 -0
- package/dist/middlewares/index.js.map +1 -0
- package/dist/middlewares/rate-limit.d.ts +35 -0
- package/dist/middlewares/rate-limit.d.ts.map +1 -0
- package/dist/middlewares/rate-limit.js +45 -0
- package/dist/middlewares/rate-limit.js.map +1 -0
- package/dist/middlewares/security-headers.d.ts +26 -0
- package/dist/middlewares/security-headers.d.ts.map +1 -0
- package/dist/middlewares/security-headers.js +34 -0
- package/dist/middlewares/security-headers.js.map +1 -0
- package/dist/schema/serialization.d.ts +2 -0
- package/dist/schema/serialization.d.ts.map +1 -0
- package/dist/schema/serialization.js +11 -0
- package/dist/schema/serialization.js.map +1 -0
- package/dist/schema/validation.d.ts +11 -0
- package/dist/schema/validation.d.ts.map +1 -0
- package/dist/schema/validation.js +48 -0
- package/dist/schema/validation.js.map +1 -0
- package/dist/shims/symbol-metadata.d.ts +2 -0
- package/dist/shims/symbol-metadata.d.ts.map +1 -0
- package/dist/shims/symbol-metadata.js +8 -0
- package/dist/shims/symbol-metadata.js.map +1 -0
- package/dist/utils/content-type.d.ts +5 -0
- package/dist/utils/content-type.d.ts.map +1 -0
- package/dist/utils/content-type.js +10 -0
- package/dist/utils/content-type.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/path.d.ts +3 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +7 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/query.d.ts +13 -0
- package/dist/utils/query.d.ts.map +1 -0
- package/dist/utils/query.js +30 -0
- package/dist/utils/query.js.map +1 -0
- package/package.json +74 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/core/metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type http from 'node:http';
|
|
2
|
+
import type { SashikoApp } from './app.ts';
|
|
3
|
+
import type { ManualRouteOptions, MethodSelector, MountOptions, RouteGroup } from './compiler.ts';
|
|
4
|
+
import type { InjectOptions, InjectResponse } from './inject.ts';
|
|
5
|
+
import type { ListenOptions } from './app.ts';
|
|
6
|
+
import type { Logger } from './logger.ts';
|
|
7
|
+
import type { Middleware } from './compose.ts';
|
|
8
|
+
import type { Context } from './context.ts';
|
|
9
|
+
/**
|
|
10
|
+
* Retorno de `app.mount()` (F-30): permite mapear manualmente métodos do grupo e continuar
|
|
11
|
+
* encadeando chamadas do app.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* app
|
|
15
|
+
* .mount(new UserRoutes(repo))
|
|
16
|
+
* .get('/legacy/:id', (r) => r.getUser, { guards: [isAdmin] })
|
|
17
|
+
* .mount(HealthRoutes);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class MountedGroup<T extends object> {
|
|
21
|
+
#private;
|
|
22
|
+
readonly app: SashikoApp;
|
|
23
|
+
/** @internal Criado por `app.mount()`. */
|
|
24
|
+
constructor(app: SashikoApp, group: RouteGroup, register: (group: RouteGroup, method: string, path: string, select: MethodSelector<object>, opts?: ManualRouteOptions) => void);
|
|
25
|
+
/** Mapeia `GET path` (relativo ao prefixo do grupo) para o método selecionado. */
|
|
26
|
+
get(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
27
|
+
post(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
28
|
+
put(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
29
|
+
patch(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
30
|
+
delete(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
31
|
+
mount<U extends object>(ref: new () => U, options?: MountOptions<U>): MountedGroup<U>;
|
|
32
|
+
mount<U extends object>(ref: U extends abstract new (...args: never) => unknown ? never : U, options?: MountOptions<U>): MountedGroup<U>;
|
|
33
|
+
use(mw: Middleware): SashikoApp;
|
|
34
|
+
onError(h: (err: unknown, ctx: Context) => void | Promise<void>): SashikoApp;
|
|
35
|
+
listen(options?: number | ListenOptions): Promise<http.Server>;
|
|
36
|
+
close(graceMs?: number): Promise<void>;
|
|
37
|
+
callback(): (req: http.IncomingMessage, res: http.ServerResponse) => void;
|
|
38
|
+
inject(opts: InjectOptions | string): Promise<InjectResponse>;
|
|
39
|
+
get log(): Logger;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=mounted-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mounted-group.d.ts","sourceRoot":"","sources":["../../src/core/mounted-group.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retorno de `app.mount()` (F-30): permite mapear manualmente métodos do grupo e continuar
|
|
3
|
+
* encadeando chamadas do app.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* app
|
|
7
|
+
* .mount(new UserRoutes(repo))
|
|
8
|
+
* .get('/legacy/:id', (r) => r.getUser, { guards: [isAdmin] })
|
|
9
|
+
* .mount(HealthRoutes);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export class MountedGroup {
|
|
13
|
+
app;
|
|
14
|
+
#group;
|
|
15
|
+
#register;
|
|
16
|
+
/** @internal Criado por `app.mount()`. */
|
|
17
|
+
constructor(app, group, register) {
|
|
18
|
+
this.app = app;
|
|
19
|
+
this.#group = group;
|
|
20
|
+
this.#register = register;
|
|
21
|
+
}
|
|
22
|
+
#map(method, path, select, opts) {
|
|
23
|
+
this.#register(this.#group, method, path, select, opts);
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
/** Mapeia `GET path` (relativo ao prefixo do grupo) para o método selecionado. */
|
|
27
|
+
get(path, select, opts) { return this.#map('GET', path, select, opts); }
|
|
28
|
+
post(path, select, opts) { return this.#map('POST', path, select, opts); }
|
|
29
|
+
put(path, select, opts) { return this.#map('PUT', path, select, opts); }
|
|
30
|
+
patch(path, select, opts) { return this.#map('PATCH', path, select, opts); }
|
|
31
|
+
delete(path, select, opts) { return this.#map('DELETE', path, select, opts); }
|
|
32
|
+
mount(ref, options) {
|
|
33
|
+
return this.app.mount(ref, options);
|
|
34
|
+
}
|
|
35
|
+
use(mw) { return this.app.use(mw); }
|
|
36
|
+
onError(h) { return this.app.onError(h); }
|
|
37
|
+
listen(options) { return this.app.listen(options); }
|
|
38
|
+
close(graceMs) { return this.app.close(graceMs); }
|
|
39
|
+
callback() { return this.app.callback(); }
|
|
40
|
+
inject(opts) { return this.app.inject(opts); }
|
|
41
|
+
get log() { return this.app.log; }
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=mounted-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mounted-group.js","sourceRoot":"","sources":["../../src/core/mounted-group.ts"],"names":[],"mappings":"AASA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,YAAY;IACd,GAAG,CAAa;IAChB,MAAM,CAAa;IACnB,SAAS,CAAuH;IAEzI,0CAA0C;IAC1C,YACE,GAAe,EACf,KAAiB,EACjB,QAA8H;QAE9H,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,MAAc,EAAE,IAAY,EAAE,MAAyB,EAAE,IAAyB;QACrF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAgC,EAAE,IAAI,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kFAAkF;IAClF,GAAG,CAAC,IAAY,EAAE,MAAyB,EAAE,IAAyB,IAAU,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9H,IAAI,CAAC,IAAY,EAAE,MAAyB,EAAE,IAAyB,IAAU,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAChI,GAAG,CAAC,IAAY,EAAE,MAAyB,EAAE,IAAyB,IAAU,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9H,KAAK,CAAC,IAAY,EAAE,MAAyB,EAAE,IAAyB,IAAU,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAClI,MAAM,CAAC,IAAY,EAAE,MAAyB,EAAE,IAAyB,IAAU,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAKpI,KAAK,CAAC,GAAW,EAAE,OAA8B;QAC/C,OAAQ,IAAI,CAAC,GAAG,CAAC,KAAuE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzG,CAAC;IACD,GAAG,CAAC,EAAc,IAAgB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,CAAuD,IAAgB,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5G,MAAM,CAAC,OAAgC,IAA0B,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnG,KAAK,CAAC,OAAgB,IAAmB,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1E,QAAQ,KAAoE,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACzG,MAAM,CAAC,IAA4B,IAA6B,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/F,IAAI,GAAG,KAAa,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3C"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Context } from './context.ts';
|
|
2
|
+
import type { RouteSchemas } from './metadata.ts';
|
|
3
|
+
/** Valida cada parte da requisição que tiver schema; o primeiro erro vira 400 com detalhes (B-02/B-03). */
|
|
4
|
+
export declare function validateRequest(ctx: Context, schemas: RouteSchemas): void;
|
|
5
|
+
/** Modo `requireSchemas` (S-07): falha no registro se a rota não tiver os schemas obrigatórios. */
|
|
6
|
+
export declare function assertSchemas(owner: string, route: {
|
|
7
|
+
method: string;
|
|
8
|
+
path: string;
|
|
9
|
+
schemas: RouteSchemas;
|
|
10
|
+
}): void;
|
|
11
|
+
//# sourceMappingURL=request-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-validation.d.ts","sourceRoot":"","sources":["../../src/core/request-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAQlD,2GAA2G;AAC3G,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CASzE;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAAG,IAAI,CAQjH"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HttpError } from './errors.js';
|
|
2
|
+
import { validate } from '../schema/validation.js';
|
|
3
|
+
const VALIDATION_ORDER = ['headers', 'params', 'query', 'body'];
|
|
4
|
+
const TARGET_LABEL = {
|
|
5
|
+
headers: 'Invalid headers', params: 'Invalid params', query: 'Invalid query', body: 'Invalid body',
|
|
6
|
+
};
|
|
7
|
+
/** Valida cada parte da requisição que tiver schema; o primeiro erro vira 400 com detalhes (B-02/B-03). */
|
|
8
|
+
export function validateRequest(ctx, schemas) {
|
|
9
|
+
for (const target of VALIDATION_ORDER) {
|
|
10
|
+
const schema = schemas[target];
|
|
11
|
+
if (!schema)
|
|
12
|
+
continue;
|
|
13
|
+
// Headers: validamos uma cópia, para coerção/defaults não alterarem `req.headers`.
|
|
14
|
+
const data = target === 'headers' ? { ...ctx.req.headers } : ctx[target];
|
|
15
|
+
const issues = validate(schema, data, target);
|
|
16
|
+
if (issues)
|
|
17
|
+
throw new HttpError(400, TARGET_LABEL[target], 'VALIDATION_ERROR', { details: issues });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Modo `requireSchemas` (S-07): falha no registro se a rota não tiver os schemas obrigatórios. */
|
|
21
|
+
export function assertSchemas(owner, route) {
|
|
22
|
+
const where = `${owner}: ${route.method} ${route.path}`;
|
|
23
|
+
if (['POST', 'PUT', 'PATCH'].includes(route.method) && !route.schemas.body) {
|
|
24
|
+
throw new Error(`[sashiko] requireSchemas: ${where} has no body schema.`);
|
|
25
|
+
}
|
|
26
|
+
if (!route.schemas.response || Object.keys(route.schemas.response).length === 0) {
|
|
27
|
+
throw new Error(`[sashiko] requireSchemas: ${where} has no response schema.`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=request-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-validation.js","sourceRoot":"","sources":["../../src/core/request-validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAyB,MAAM,yBAAyB,CAAC;AAE1E,MAAM,gBAAgB,GAAgC,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAC7F,MAAM,YAAY,GAAqC;IACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc;CACnG,CAAC;AAEF,2GAA2G;AAC3G,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,OAAqB;IACjE,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,mFAAmF;QACnF,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,MAAM;YAAE,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACtG,CAAC;AACH,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,KAA8D;IACzG,MAAM,KAAK,GAAG,GAAG,KAAK,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;IACxD,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,sBAAsB,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChF,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,0BAA0B,CAAC,CAAC;IAChF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Context } from './context.ts';
|
|
2
|
+
import type { RouteSchemas } from './metadata.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Envia o retorno do handler (B-05):
|
|
5
|
+
* - Sem `ctx.status()` e com um único 2xx declarado, esse 2xx vira o status padrão.
|
|
6
|
+
* - Com schemas de resposta declarados, um status sem schema correspondente **não** cai no
|
|
7
|
+
* `JSON.stringify`, que mandaria o objeto inteiro (S-07): vira 500 e o motivo vai para o log.
|
|
8
|
+
* - Respostas sem corpo (`undefined`) dispensam schema.
|
|
9
|
+
*/
|
|
10
|
+
export declare function sendResult(ctx: Context, response: RouteSchemas['response'], result: unknown): void;
|
|
11
|
+
/**
|
|
12
|
+
* Resposta de erro padrão. Só mensagens marcadas como `expose` chegam ao cliente;
|
|
13
|
+
* o resto vira 500 genérico e o erro original é logado no servidor (S-05).
|
|
14
|
+
*/
|
|
15
|
+
export declare function sendError(ctx: Context, err: unknown): void;
|
|
16
|
+
//# sourceMappingURL=response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/core/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKlD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAkBlG;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAY1D"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { HttpError } from './errors.js';
|
|
2
|
+
import { serialize } from '../schema/serialization.js';
|
|
3
|
+
const GENERIC_500 = 'Internal Server Error';
|
|
4
|
+
/**
|
|
5
|
+
* Envia o retorno do handler (B-05):
|
|
6
|
+
* - Sem `ctx.status()` e com um único 2xx declarado, esse 2xx vira o status padrão.
|
|
7
|
+
* - Com schemas de resposta declarados, um status sem schema correspondente **não** cai no
|
|
8
|
+
* `JSON.stringify`, que mandaria o objeto inteiro (S-07): vira 500 e o motivo vai para o log.
|
|
9
|
+
* - Respostas sem corpo (`undefined`) dispensam schema.
|
|
10
|
+
*/
|
|
11
|
+
export function sendResult(ctx, response, result) {
|
|
12
|
+
if (response && !ctx.statusExplicit) {
|
|
13
|
+
const success = Object.keys(response).map(Number).filter((s) => s >= 200 && s < 300);
|
|
14
|
+
if (success.length === 1 && response[200] === undefined)
|
|
15
|
+
ctx.res.statusCode = success[0];
|
|
16
|
+
}
|
|
17
|
+
if (result === undefined)
|
|
18
|
+
return void ctx.res.end();
|
|
19
|
+
const status = ctx.res.statusCode;
|
|
20
|
+
const schema = response?.[status];
|
|
21
|
+
if (schema) {
|
|
22
|
+
ctx.res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
23
|
+
return void ctx.res.end(serialize(schema, result));
|
|
24
|
+
}
|
|
25
|
+
if (response && Object.keys(response).length > 0) {
|
|
26
|
+
throw new Error(`[sashiko] ${ctx.method} ${ctx.path}: no response schema for status ${status}`);
|
|
27
|
+
}
|
|
28
|
+
ctx.json(result);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resposta de erro padrão. Só mensagens marcadas como `expose` chegam ao cliente;
|
|
32
|
+
* o resto vira 500 genérico e o erro original é logado no servidor (S-05).
|
|
33
|
+
*/
|
|
34
|
+
export function sendError(ctx, err) {
|
|
35
|
+
const httpErr = err instanceof HttpError ? err : undefined;
|
|
36
|
+
const status = httpErr?.status ?? 500;
|
|
37
|
+
const exposed = httpErr?.expose === true;
|
|
38
|
+
if (!exposed)
|
|
39
|
+
ctx.log.error({ err, method: ctx.method, path: ctx.path, status }, 'request failed');
|
|
40
|
+
if (ctx.res.writableEnded)
|
|
41
|
+
return;
|
|
42
|
+
if (ctx.res.headersSent)
|
|
43
|
+
return void ctx.res.end();
|
|
44
|
+
const body = { error: exposed ? httpErr.message : GENERIC_500 };
|
|
45
|
+
if (exposed && httpErr.details !== undefined)
|
|
46
|
+
body.details = httpErr.details;
|
|
47
|
+
ctx.status(status).json(body);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/core/response.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,QAAkC,EAAE,MAAe;IAC1F,IAAI,QAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACrF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;IAC5F,CAAC;IAED,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAEpD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC;IAClC,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,MAAM,EAAE,CAAC;QACX,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;QACrE,OAAO,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,mCAAmC,MAAM,EAAE,CAAC,CAAC;IAClG,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,GAAY,EAAE,GAAY;IAClD,MAAM,OAAO,GAAG,GAAG,YAAY,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,GAAG,CAAC;IACtC,MAAM,OAAO,GAAG,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzC,IAAI,CAAC,OAAO;QAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC;IACnG,IAAI,GAAG,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO;IAClC,IAAI,GAAG,CAAC,GAAG,CAAC,WAAW;QAAE,OAAO,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAEnD,MAAM,IAAI,GAAyC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,OAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACvG,IAAI,OAAO,IAAI,OAAQ,CAAC,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,GAAG,OAAQ,CAAC,OAAO,CAAC;IAC/E,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Middleware } from './compose.ts';
|
|
2
|
+
import type { Context } from './context.ts';
|
|
3
|
+
import type { Guard } from './guard.ts';
|
|
4
|
+
import type { RouteSchemas } from './metadata.ts';
|
|
5
|
+
export type Handler = (ctx: Context) => unknown | Promise<unknown>;
|
|
6
|
+
/** Tudo o que o app precisa para executar uma rota. */
|
|
7
|
+
export interface RouteDefinition {
|
|
8
|
+
handler: Handler;
|
|
9
|
+
schemas: RouteSchemas;
|
|
10
|
+
middlewares: readonly Middleware[];
|
|
11
|
+
guards: readonly Guard[];
|
|
12
|
+
}
|
|
13
|
+
export interface RouteMatch extends RouteDefinition {
|
|
14
|
+
params: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
/** Tabela de rotas interna sobre o find-my-way. */
|
|
17
|
+
export declare class RouteTable {
|
|
18
|
+
private inner;
|
|
19
|
+
on(method: string, path: string, route: RouteDefinition): void;
|
|
20
|
+
find(method: string, path: string): RouteMatch | null;
|
|
21
|
+
/**
|
|
22
|
+
* Descobre quais métodos existem para o path informado.
|
|
23
|
+
* Estratégia: pergunta ao find-my-way método por método.
|
|
24
|
+
* O custo é O(número de métodos registrados) por lookup, o que é trivial
|
|
25
|
+
* (no máximo 7 find() O(log n) cada).
|
|
26
|
+
*/
|
|
27
|
+
allowedMethods(path: string): string[];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=route-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-table.d.ts","sourceRoot":"","sources":["../../src/core/route-table.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnE,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;IACnC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,UAAW,SAAQ,eAAe;IACjD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAQD,mDAAmD;AACnD,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAyC;IAEtD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAE7D;IAED,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAOpD;IAED;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAUrC;CACF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// src/core/route-table.ts
|
|
2
|
+
import Router from 'find-my-way';
|
|
3
|
+
// O find-my-way exige um handler próprio; usamos só o `store`, então ele nunca é chamado.
|
|
4
|
+
const NOOP = () => { };
|
|
5
|
+
const PROBE_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'];
|
|
6
|
+
/** Tabela de rotas interna sobre o find-my-way. */
|
|
7
|
+
export class RouteTable {
|
|
8
|
+
inner = Router({ ignoreTrailingSlash: true });
|
|
9
|
+
on(method, path, route) {
|
|
10
|
+
this.inner.on(method, path, NOOP, route);
|
|
11
|
+
}
|
|
12
|
+
find(method, path) {
|
|
13
|
+
// F-08: HEAD usa o handler do GET quando não houver rota HEAD própria.
|
|
14
|
+
// O Node já descarta o corpo de respostas a HEAD.
|
|
15
|
+
const found = this.inner.find(method, path)
|
|
16
|
+
?? (method === 'HEAD' ? this.inner.find('GET', path) : null);
|
|
17
|
+
if (!found)
|
|
18
|
+
return null;
|
|
19
|
+
return { ...found.store, params: found.params };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Descobre quais métodos existem para o path informado.
|
|
23
|
+
* Estratégia: pergunta ao find-my-way método por método.
|
|
24
|
+
* O custo é O(número de métodos registrados) por lookup, o que é trivial
|
|
25
|
+
* (no máximo 7 find() O(log n) cada).
|
|
26
|
+
*/
|
|
27
|
+
allowedMethods(path) {
|
|
28
|
+
const methods = new Set();
|
|
29
|
+
for (const method of PROBE_METHODS) {
|
|
30
|
+
if (this.inner.find(method, path)) {
|
|
31
|
+
methods.add(method);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (methods.has('GET'))
|
|
35
|
+
methods.add('HEAD');
|
|
36
|
+
if (methods.size > 0)
|
|
37
|
+
methods.add('OPTIONS');
|
|
38
|
+
return [...methods].sort();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=route-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-table.js","sourceRoot":"","sources":["../../src/core/route-table.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,OAAO,MAAM,MAAM,aAAa,CAAC;AAsBjC,0FAA0F;AAC1F,MAAM,IAAI,GAA0C,GAAG,EAAE,GAAE,CAAC,CAAC;AAC7D,MAAM,aAAa,GAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AAEtG,mDAAmD;AACnD,MAAM,OAAO,UAAU;IACb,KAAK,GAAG,MAAM,CAAC,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtD,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,KAAsB;QACrD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,MAAc,EAAE,IAAY;QAC/B,uEAAuE;QACvE,kDAAkD;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAgB,EAAE,IAAI,CAAC;eAChD,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,OAAO,EAAE,GAAI,KAAK,CAAC,KAAyB,EAAE,MAAM,EAAE,KAAK,CAAC,MAAgC,EAAE,CAAC;IACjG,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,IAAY;QACzB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;gBAClC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type RouteSchemas } from '../core/metadata.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Decorators de rota. O segundo argumento, opcional, são os schemas da rota: o mesmo que `@Schema`,
|
|
4
|
+
* na mesma linha do verbo.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* @Get('/:id', byId)
|
|
8
|
+
* getUser(ctx: Context<typeof byId>) {}
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare const Get: (path?: string, schemas?: RouteSchemas) => <This, Args extends [any, ...unknown[]], Return>(_target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => void;
|
|
12
|
+
export declare const Post: (path?: string, schemas?: RouteSchemas) => <This, Args extends [any, ...unknown[]], Return>(_target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => void;
|
|
13
|
+
export declare const Put: (path?: string, schemas?: RouteSchemas) => <This, Args extends [any, ...unknown[]], Return>(_target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => void;
|
|
14
|
+
export declare const Patch: (path?: string, schemas?: RouteSchemas) => <This, Args extends [any, ...unknown[]], Return>(_target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => void;
|
|
15
|
+
export declare const Delete: (path?: string, schemas?: RouteSchemas) => <This, Args extends [any, ...unknown[]], Return>(_target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => void;
|
|
16
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/decorators/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAgBtG;;;;;;;;GAQG;AACH,eAAO,MAAM,GAAG,4BAA0B,YAAY,MArBnC,IAAI,EAAE,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,MAAM,WACpD,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,WACrC,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,SAmBW,CAAC;AACjG,eAAO,MAAM,IAAI,4BAA0B,YAAY,MAtBpC,IAAI,EAAE,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,MAAM,WACpD,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,WACrC,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,SAoBa,CAAC;AACnG,eAAO,MAAM,GAAG,4BAA0B,YAAY,MAvBnC,IAAI,EAAE,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,MAAM,WACpD,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,WACrC,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,SAqBW,CAAC;AACjG,eAAO,MAAM,KAAK,4BAA0B,YAAY,MAxBrC,IAAI,EAAE,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,MAAM,WACpD,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,WACrC,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,SAsBe,CAAC;AACrG,eAAO,MAAM,MAAM,4BAA0B,YAAY,MAzBtC,IAAI,EAAE,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,MAAM,WACpD,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,WACrC,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,SAuBiB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getOrCreateMethod, mergeSchemas, metadataFor } from '../core/metadata.js';
|
|
2
|
+
function methodDecorator(httpMethod, path, schemas) {
|
|
3
|
+
const label = httpMethod[0] + httpMethod.slice(1).toLowerCase();
|
|
4
|
+
return function (_target, context) {
|
|
5
|
+
const meta = metadataFor(context, label);
|
|
6
|
+
const m = getOrCreateMethod(meta, context.name);
|
|
7
|
+
m.method = httpMethod;
|
|
8
|
+
m.path = path;
|
|
9
|
+
if (schemas)
|
|
10
|
+
mergeSchemas(m, schemas, `@${label}`);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Decorators de rota. O segundo argumento, opcional, são os schemas da rota: o mesmo que `@Schema`,
|
|
15
|
+
* na mesma linha do verbo.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* @Get('/:id', byId)
|
|
19
|
+
* getUser(ctx: Context<typeof byId>) {}
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export const Get = (path = '/', schemas) => methodDecorator('GET', path, schemas);
|
|
23
|
+
export const Post = (path = '/', schemas) => methodDecorator('POST', path, schemas);
|
|
24
|
+
export const Put = (path = '/', schemas) => methodDecorator('PUT', path, schemas);
|
|
25
|
+
export const Patch = (path = '/', schemas) => methodDecorator('PATCH', path, schemas);
|
|
26
|
+
export const Delete = (path = '/', schemas) => methodDecorator('DELETE', path, schemas);
|
|
27
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/decorators/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,qBAAqB,CAAC;AAEtG,SAAS,eAAe,CAAC,UAAkB,EAAE,IAAY,EAAE,OAAsB;IAC/E,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAChE,OAAO,UACL,OAA8C,EAC9C,OAAiF;QAEjF,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;QACtB,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;QACd,IAAI,OAAO;YAAE,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,OAAsB,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACjG,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,OAAsB,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACnG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,OAAsB,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACjG,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,OAAsB,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACrG,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,OAAsB,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Delete, Get, Patch, Post, Put } from './http.ts';
|
|
2
|
+
export { timer, type TimerOptions } from './log.ts';
|
|
3
|
+
export { Router } from './router.ts';
|
|
4
|
+
export { Schema } from './schema.ts';
|
|
5
|
+
export { Guards, Middlewares } from './middlewares.ts';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAqB,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface TimerOptions {
|
|
2
|
+
/** Destino da medição. Padrão: `console.debug`. */
|
|
3
|
+
log?: (message: string, ms: number) => void;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Mede o tempo do handler, inclusive de handlers `async` (B-04).
|
|
7
|
+
* Uso: `@timer()` ou `@timer({ log: (msg, ms) => logger.info({ ms }, msg) })`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function timer(opts?: TimerOptions): <This, Args extends unknown[], Return>(target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => (this: This, ...args: Args) => Return;
|
|
10
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/decorators/log.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,IAAI,GAAE,YAAiB,IAG1B,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,UAC3C,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,WACpC,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,YAQ1D,IAAI,WAAW,IAAI,KAAG,MAAM,CAgBtD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { performance } from 'node:perf_hooks';
|
|
2
|
+
/**
|
|
3
|
+
* Mede o tempo do handler, inclusive de handlers `async` (B-04).
|
|
4
|
+
* Uso: `@timer()` ou `@timer({ log: (msg, ms) => logger.info({ ms }, msg) })`.
|
|
5
|
+
*/
|
|
6
|
+
export function timer(opts = {}) {
|
|
7
|
+
const log = opts.log ?? ((msg) => console.debug(msg));
|
|
8
|
+
return function (target, context) {
|
|
9
|
+
const name = String(context.name);
|
|
10
|
+
const report = (start) => {
|
|
11
|
+
const ms = performance.now() - start;
|
|
12
|
+
log(`${name} took ${ms.toFixed(2)}ms`, ms);
|
|
13
|
+
};
|
|
14
|
+
return function (...args) {
|
|
15
|
+
const start = performance.now();
|
|
16
|
+
let result;
|
|
17
|
+
try {
|
|
18
|
+
result = target.call(this, ...args);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
report(start);
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
if (result instanceof Promise) {
|
|
25
|
+
return result.finally(() => report(start));
|
|
26
|
+
}
|
|
27
|
+
report(start);
|
|
28
|
+
return result;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/decorators/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAO9C;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAC,IAAI,GAAiB,EAAE;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAE9D,OAAO,UACL,MAA6C,EAC7C,OAAiF;QAEjF,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;YAC/B,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACrC,GAAG,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC;QAEF,OAAO,UAAsB,GAAG,IAAU;YACxC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAChC,IAAI,MAAc,CAAC;YACnB,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;YACtC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC9B,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAW,CAAC;YACvD,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,CAAC;YACd,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Middleware } from '../core/compose.ts';
|
|
2
|
+
import type { Guard } from '../core/guard.ts';
|
|
3
|
+
type ClassOrMethodContext = ClassDecoratorContext | ClassMethodDecoratorContext;
|
|
4
|
+
/**
|
|
5
|
+
* Middlewares para todas as rotas da classe ou para um método (F-01, F-30). Rodam depois dos globais
|
|
6
|
+
* e dos `middlewares` do `mount`, e antes dos guards. É o mesmo nome da opção `middlewares`.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* @Middlewares(rateLimit({ max: 10 })) // todas as rotas da classe
|
|
10
|
+
* @Router('/auth')
|
|
11
|
+
* class AuthRoutes {
|
|
12
|
+
* @Middlewares(audit) @Post('/login') login() {}
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare function Middlewares(...middlewares: Middleware[]): (_value: unknown, context: ClassOrMethodContext) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Guards para todas as rotas da classe ou para um método (F-01, F-30). Rodam antes da validação;
|
|
19
|
+
* `false` responde 403. É o mesmo nome da opção `guards`.
|
|
20
|
+
*
|
|
21
|
+
* ```ts
|
|
22
|
+
* const isAdmin: Guard = (ctx) => ctx.state.user?.role === 'admin';
|
|
23
|
+
* @Guards(isAdmin) @Delete('/:id') remove() {}
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function Guards(...guards: Guard[]): (_value: unknown, context: ClassOrMethodContext) => void;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=middlewares.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middlewares.d.ts","sourceRoot":"","sources":["../../src/decorators/middlewares.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C,KAAK,oBAAoB,GAAG,qBAAqB,GAAG,2BAA2B,CAAC;AAchF;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,GAAG,WAAW,EAAE,UAAU,EAAE,YAnB7B,OAAO,WAAW,oBAAoB,KAAG,IAAI,CAqBvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,YAhCd,OAAO,WAAW,oBAAoB,KAAG,IAAI,CAkCvE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getOrCreateMethod, metadataFor } from '../core/metadata.js';
|
|
2
|
+
/**
|
|
3
|
+
* Aplica `items` na classe (todas as rotas) ou no método. Decorators são avaliados de baixo para
|
|
4
|
+
* cima; inserimos no início para que a ordem de execução siga a ordem de leitura (de cima para baixo).
|
|
5
|
+
*/
|
|
6
|
+
function register(decorator, pick, items) {
|
|
7
|
+
return function (_value, context) {
|
|
8
|
+
const meta = metadataFor(context, decorator);
|
|
9
|
+
const target = context.kind === 'class' ? meta : getOrCreateMethod(meta, context.name);
|
|
10
|
+
target[pick].unshift(...items);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Middlewares para todas as rotas da classe ou para um método (F-01, F-30). Rodam depois dos globais
|
|
15
|
+
* e dos `middlewares` do `mount`, e antes dos guards. É o mesmo nome da opção `middlewares`.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* @Middlewares(rateLimit({ max: 10 })) // todas as rotas da classe
|
|
19
|
+
* @Router('/auth')
|
|
20
|
+
* class AuthRoutes {
|
|
21
|
+
* @Middlewares(audit) @Post('/login') login() {}
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function Middlewares(...middlewares) {
|
|
26
|
+
return register('Middlewares', 'middlewares', middlewares);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Guards para todas as rotas da classe ou para um método (F-01, F-30). Rodam antes da validação;
|
|
30
|
+
* `false` responde 403. É o mesmo nome da opção `guards`.
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* const isAdmin: Guard = (ctx) => ctx.state.user?.role === 'admin';
|
|
34
|
+
* @Guards(isAdmin) @Delete('/:id') remove() {}
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export function Guards(...guards) {
|
|
38
|
+
return register('Guards', 'guards', guards);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=middlewares.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middlewares.js","sourceRoot":"","sources":["../../src/decorators/middlewares.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIrE;;;GAGG;AACH,SAAS,QAAQ,CAAC,SAAiB,EAAE,IAA8B,EAAE,KAAyB;IAC5F,OAAO,UAAU,MAAe,EAAE,OAA6B;QAC7D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACtF,MAAM,CAAC,IAAI,CAAe,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,GAAG,WAAyB;IACtD,OAAO,QAAQ,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,MAAM,CAAC,GAAG,MAAe;IACvC,OAAO,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marca a classe como um grupo de rotas que o app pode registrar com `app.mount()` (F-28)
|
|
3
|
+
* e define o prefixo padrão. Sem `@Router` próprio, a classe é recusada.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* @Router('/users')
|
|
7
|
+
* class UserRoutes { @Get('/:id') getById() {} }
|
|
8
|
+
* app.mount(UserRoutes);
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare function Router(prefix?: string): <T extends abstract new (...args: any[]) => object>(_value: T, context: ClassDecoratorContext<T>) => void;
|
|
12
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/decorators/router.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,MAAM,SAAK,IACf,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,UAAU,CAAC,WAAW,qBAAqB,CAAC,CAAC,CAAC,UAKjH"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { metadataFor } from '../core/metadata.js';
|
|
2
|
+
/**
|
|
3
|
+
* Marca a classe como um grupo de rotas que o app pode registrar com `app.mount()` (F-28)
|
|
4
|
+
* e define o prefixo padrão. Sem `@Router` próprio, a classe é recusada.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* @Router('/users')
|
|
8
|
+
* class UserRoutes { @Get('/:id') getById() {} }
|
|
9
|
+
* app.mount(UserRoutes);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export function Router(prefix = '') {
|
|
13
|
+
return function (_value, context) {
|
|
14
|
+
const meta = metadataFor(context, 'Router');
|
|
15
|
+
meta.isRouter = true;
|
|
16
|
+
meta.prefix = prefix;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/decorators/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;;;;;;GASG;AACH,MAAM,UAAU,MAAM,CAAC,MAAM,GAAG,EAAE;IAChC,OAAO,UAA6D,MAAS,EAAE,OAAiC;QAC9G,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RouteSchemas } from '../core/metadata.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Schemas da rota em um decorator separado, para quem prefere manter o verbo enxuto.
|
|
4
|
+
* Equivale ao segundo argumento de `@Get`/`@Post`/…; as duas formas podem conviver no mesmo método,
|
|
5
|
+
* desde que não declarem a mesma parte (ex.: `body`) duas vezes.
|
|
6
|
+
*/
|
|
7
|
+
export declare function Schema(schemas: RouteSchemas): <This, Args extends [any, ...unknown[]], Return>(_target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>) => void;
|
|
8
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/decorators/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEtG;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,YAAY,IACzB,IAAI,EAAE,IAAI,SAAS,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,EAAE,MAAM,WACpD,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,WACrC,2BAA2B,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,UAKpF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getOrCreateMethod, mergeSchemas, metadataFor } from '../core/metadata.js';
|
|
2
|
+
/**
|
|
3
|
+
* Schemas da rota em um decorator separado, para quem prefere manter o verbo enxuto.
|
|
4
|
+
* Equivale ao segundo argumento de `@Get`/`@Post`/…; as duas formas podem conviver no mesmo método,
|
|
5
|
+
* desde que não declarem a mesma parte (ex.: `body`) duas vezes.
|
|
6
|
+
*/
|
|
7
|
+
export function Schema(schemas) {
|
|
8
|
+
return function (_target, context) {
|
|
9
|
+
const meta = metadataFor(context, 'Schema');
|
|
10
|
+
mergeSchemas(getOrCreateMethod(meta, context.name), schemas, '@Schema');
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/decorators/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,qBAAqB,CAAC;AAEtG;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,OAAqB;IAC1C,OAAO,UACL,OAA8C,EAC9C,OAAiF;QAEjF,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5C,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC1E,CAAC,CAAC;AACJ,CAAC"}
|