flowingts 0.0.0 → 0.19.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 +74 -3
- package/dist/core/abort.d.ts +23 -0
- package/dist/core/abort.d.ts.map +1 -0
- package/dist/core/abort.js +23 -0
- package/dist/core/abort.js.map +1 -0
- package/dist/core/app/core.d.ts +35 -0
- package/dist/core/app/core.d.ts.map +1 -0
- package/dist/core/app/core.js +2 -0
- package/dist/core/app/core.js.map +1 -0
- package/dist/core/app/options.d.ts +178 -0
- package/dist/core/app/options.d.ts.map +1 -0
- package/dist/core/app/options.js +2 -0
- package/dist/core/app/options.js.map +1 -0
- package/dist/core/app.d.ts +143 -0
- package/dist/core/app.d.ts.map +1 -0
- package/dist/core/app.js +283 -0
- package/dist/core/app.js.map +1 -0
- package/dist/core/body-parser.d.ts +14 -0
- package/dist/core/body-parser.d.ts.map +1 -0
- package/dist/core/body-parser.js +76 -0
- package/dist/core/body-parser.js.map +1 -0
- package/dist/core/compiler.d.ts +104 -0
- package/dist/core/compiler.d.ts.map +1 -0
- package/dist/core/compiler.js +151 -0
- package/dist/core/compiler.js.map +1 -0
- package/dist/core/compose.d.ts +16 -0
- package/dist/core/compose.d.ts.map +1 -0
- package/dist/core/compose.js +41 -0
- package/dist/core/compose.js.map +1 -0
- package/dist/core/context.d.ts +290 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +460 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/contracts.d.ts +76 -0
- package/dist/core/contracts.d.ts.map +1 -0
- package/dist/core/contracts.js +87 -0
- package/dist/core/contracts.js.map +1 -0
- package/dist/core/errors.d.ts +50 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +25 -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 +14 -0
- package/dist/core/guard.js.map +1 -0
- package/dist/core/health.d.ts +37 -0
- package/dist/core/health.d.ts.map +1 -0
- package/dist/core/health.js +68 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/hooks.d.ts +34 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +27 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/index.d.ts +30 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +11 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/infer.d.ts +68 -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 +85 -0
- package/dist/core/inject.js.map +1 -0
- package/dist/core/logger.d.ts +57 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +134 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/metadata.d.ts +83 -0
- package/dist/core/metadata.d.ts.map +1 -0
- package/dist/core/metadata.js +91 -0
- package/dist/core/metadata.js.map +1 -0
- package/dist/core/mounted-group.d.ts +77 -0
- package/dist/core/mounted-group.d.ts.map +1 -0
- package/dist/core/mounted-group.js +131 -0
- package/dist/core/mounted-group.js.map +1 -0
- package/dist/core/registry/framework-routes.d.ts +28 -0
- package/dist/core/registry/framework-routes.d.ts.map +1 -0
- package/dist/core/registry/framework-routes.js +83 -0
- package/dist/core/registry/framework-routes.js.map +1 -0
- package/dist/core/registry/registry.d.ts +58 -0
- package/dist/core/registry/registry.d.ts.map +1 -0
- package/dist/core/registry/registry.js +208 -0
- package/dist/core/registry/registry.js.map +1 -0
- package/dist/core/registry/route-program.d.ts +16 -0
- package/dist/core/registry/route-program.d.ts.map +1 -0
- package/dist/core/registry/route-program.js +62 -0
- package/dist/core/registry/route-program.js.map +1 -0
- package/dist/core/request-validation.d.ts +15 -0
- package/dist/core/request-validation.d.ts.map +1 -0
- package/dist/core/request-validation.js +67 -0
- package/dist/core/request-validation.js.map +1 -0
- package/dist/core/response/pipeline.d.ts +51 -0
- package/dist/core/response/pipeline.d.ts.map +1 -0
- package/dist/core/response/pipeline.js +169 -0
- package/dist/core/response/pipeline.js.map +1 -0
- package/dist/core/route-table.d.ts +58 -0
- package/dist/core/route-table.d.ts.map +1 -0
- package/dist/core/route-table.js +108 -0
- package/dist/core/route-table.js.map +1 -0
- package/dist/core/runtime/observer.d.ts +47 -0
- package/dist/core/runtime/observer.d.ts.map +1 -0
- package/dist/core/runtime/observer.js +125 -0
- package/dist/core/runtime/observer.js.map +1 -0
- package/dist/core/runtime/request-handler.d.ts +62 -0
- package/dist/core/runtime/request-handler.d.ts.map +1 -0
- package/dist/core/runtime/request-handler.js +256 -0
- package/dist/core/runtime/request-handler.js.map +1 -0
- package/dist/core/runtime/server.d.ts +59 -0
- package/dist/core/runtime/server.d.ts.map +1 -0
- package/dist/core/runtime/server.js +180 -0
- package/dist/core/runtime/server.js.map +1 -0
- package/dist/core/shutdown.d.ts +41 -0
- package/dist/core/shutdown.d.ts.map +1 -0
- package/dist/core/shutdown.js +53 -0
- package/dist/core/shutdown.js.map +1 -0
- package/dist/core/streaming/sse.d.ts +35 -0
- package/dist/core/streaming/sse.d.ts.map +1 -0
- package/dist/core/streaming/sse.js +121 -0
- package/dist/core/streaming/sse.js.map +1 -0
- package/dist/core/symbols.d.ts +28 -0
- package/dist/core/symbols.d.ts.map +1 -0
- package/dist/core/symbols.js +28 -0
- package/dist/core/symbols.js.map +1 -0
- package/dist/core/telemetry.d.ts +83 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +96 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/core/uploads/receive.d.ts +63 -0
- package/dist/core/uploads/receive.d.ts.map +1 -0
- package/dist/core/uploads/receive.js +342 -0
- package/dist/core/uploads/receive.js.map +1 -0
- package/dist/core/uploads/types.d.ts +79 -0
- package/dist/core/uploads/types.d.ts.map +1 -0
- package/dist/core/uploads/types.js +2 -0
- package/dist/core/uploads/types.js.map +1 -0
- package/dist/decorators/hooks.d.ts +25 -0
- package/dist/decorators/hooks.d.ts.map +1 -0
- package/dist/decorators/hooks.js +36 -0
- package/dist/decorators/hooks.js.map +1 -0
- package/dist/decorators/http.d.ts +21 -0
- package/dist/decorators/http.d.ts.map +1 -0
- package/dist/decorators/http.js +21 -0
- package/dist/decorators/http.js.map +1 -0
- package/dist/decorators/index.d.ts +7 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +7 -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 +20 -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 +14 -0
- package/dist/decorators/schema.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/middlewares/auth.d.ts +41 -0
- package/dist/middlewares/auth.d.ts.map +1 -0
- package/dist/middlewares/auth.js +74 -0
- package/dist/middlewares/auth.js.map +1 -0
- package/dist/middlewares/cors.d.ts +30 -0
- package/dist/middlewares/cors.d.ts.map +1 -0
- package/dist/middlewares/cors.js +69 -0
- package/dist/middlewares/cors.js.map +1 -0
- package/dist/middlewares/csrf.d.ts +42 -0
- package/dist/middlewares/csrf.d.ts.map +1 -0
- package/dist/middlewares/csrf.js +70 -0
- package/dist/middlewares/csrf.js.map +1 -0
- package/dist/middlewares/index.d.ts +6 -0
- package/dist/middlewares/index.d.ts.map +1 -0
- package/dist/middlewares/index.js +6 -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 +28 -0
- package/dist/middlewares/security-headers.d.ts.map +1 -0
- package/dist/middlewares/security-headers.js +42 -0
- package/dist/middlewares/security-headers.js.map +1 -0
- package/dist/openapi/generate.d.ts +51 -0
- package/dist/openapi/generate.d.ts.map +1 -0
- package/dist/openapi/generate.js +175 -0
- package/dist/openapi/generate.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 +22 -0
- package/dist/schema/validation.d.ts.map +1 -0
- package/dist/schema/validation.js +68 -0
- package/dist/schema/validation.js.map +1 -0
- package/dist/server/static.d.ts +45 -0
- package/dist/server/static.d.ts.map +1 -0
- package/dist/server/static.js +204 -0
- package/dist/server/static.js.map +1 -0
- package/dist/server/tls.d.ts +48 -0
- package/dist/server/tls.d.ts.map +1 -0
- package/dist/server/tls.js +60 -0
- package/dist/server/tls.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 +13 -0
- package/dist/utils/content-type.d.ts.map +1 -0
- package/dist/utils/content-type.js +75 -0
- package/dist/utils/content-type.js.map +1 -0
- package/dist/utils/cookie.d.ts +34 -0
- package/dist/utils/cookie.d.ts.map +1 -0
- package/dist/utils/cookie.js +94 -0
- package/dist/utils/cookie.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/mime.d.ts +2 -0
- package/dist/utils/mime.d.ts.map +1 -0
- package/dist/utils/mime.js +52 -0
- package/dist/utils/mime.js.map +1 -0
- package/dist/utils/origin-match.d.ts +58 -0
- package/dist/utils/origin-match.d.ts.map +1 -0
- package/dist/utils/origin-match.js +194 -0
- package/dist/utils/origin-match.js.map +1 -0
- package/dist/utils/path.d.ts +10 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +60 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/query.d.ts +28 -0
- package/dist/utils/query.d.ts.map +1 -0
- package/dist/utils/query.js +67 -0
- package/dist/utils/query.js.map +1 -0
- package/dist/utils/request-target.d.ts +31 -0
- package/dist/utils/request-target.d.ts.map +1 -0
- package/dist/utils/request-target.js +80 -0
- package/dist/utils/request-target.js.map +1 -0
- package/dist/utils/safe-json.d.ts +24 -0
- package/dist/utils/safe-json.d.ts.map +1 -0
- package/dist/utils/safe-json.js +83 -0
- package/dist/utils/safe-json.js.map +1 -0
- package/dist/utils/trace-context.d.ts +17 -0
- package/dist/utils/trace-context.d.ts.map +1 -0
- package/dist/utils/trace-context.js +30 -0
- package/dist/utils/trace-context.js.map +1 -0
- package/package.json +85 -6
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contrato de logger compatível com o pino (F-06): `logger.info({ reqId }, 'mensagem')`.
|
|
3
|
+
* Para usar o pino, basta passar a instância: `createApp({ logger: pino() })`.
|
|
4
|
+
*/
|
|
5
|
+
export interface Logger {
|
|
6
|
+
debug(obj: object, msg?: string): void;
|
|
7
|
+
debug(msg: string): void;
|
|
8
|
+
info(obj: object, msg?: string): void;
|
|
9
|
+
info(msg: string): void;
|
|
10
|
+
warn(obj: object, msg?: string): void;
|
|
11
|
+
warn(msg: string): void;
|
|
12
|
+
error(obj: object, msg?: string): void;
|
|
13
|
+
error(msg: string): void;
|
|
14
|
+
child(bindings: Record<string, unknown>): Logger;
|
|
15
|
+
/**
|
|
16
|
+
* Opcionais, para não exigir de loggers próprios (F-38): o `consoleLogger` e o pino têm os dois. Os níveis
|
|
17
|
+
* seguem o pino e o OpenTelemetry: `trace` abaixo de `debug`, `fatal` acima de `error`.
|
|
18
|
+
*/
|
|
19
|
+
trace?(obj: object, msg?: string): void;
|
|
20
|
+
trace?(msg: string): void;
|
|
21
|
+
fatal?(obj: object, msg?: string): void;
|
|
22
|
+
fatal?(msg: string): void;
|
|
23
|
+
}
|
|
24
|
+
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent';
|
|
25
|
+
export interface ConsoleLoggerOptions {
|
|
26
|
+
/** Padrão: `info`. */
|
|
27
|
+
level?: LogLevel;
|
|
28
|
+
/**
|
|
29
|
+
* Chaves mascaradas como `[REDACTED]` em qualquer nível dos dados logados (S-11). Somadas às padrão
|
|
30
|
+
* ({@link DEFAULT_REDACT_KEYS}); `false` desliga. A comparação ignora maiúsculas, `-` e `_`, então
|
|
31
|
+
* `'apiKey'` também cobre `api_key` e `X-Api-Key`.
|
|
32
|
+
*/
|
|
33
|
+
redact?: readonly string[] | false;
|
|
34
|
+
/**
|
|
35
|
+
* `'pretty'` (padrão): `[flowing] mensagem { ...dados }`, para o terminal. `'json'`: uma linha JSON por
|
|
36
|
+
* evento (`{ level, time, msg, ...dados }`), para coletores de log (Datadog, Loki, CloudWatch…).
|
|
37
|
+
*/
|
|
38
|
+
format?: 'pretty' | 'json';
|
|
39
|
+
/**
|
|
40
|
+
* `'stdout'` manda todos os níveis para a saída padrão. O padrão (`'console'`) segue o `console`: `warn`,
|
|
41
|
+
* `error` e `fatal` vão para o stderr, que alguns coletores tratam inteiro como erro (F-38).
|
|
42
|
+
*/
|
|
43
|
+
stream?: 'console' | 'stdout';
|
|
44
|
+
}
|
|
45
|
+
/** Chaves mascaradas por padrão: credenciais, cookies e tokens. */
|
|
46
|
+
export declare const DEFAULT_REDACT_KEYS: readonly string[];
|
|
47
|
+
/** Cópia dos dados com as chaves sensíveis mascaradas. Erros, datas e buffers passam como estão. */
|
|
48
|
+
export declare function redactValue(value: unknown, keys: ReadonlySet<string>, seen?: WeakSet<object>, depth?: number): unknown;
|
|
49
|
+
/**
|
|
50
|
+
* Logger padrão sobre o `console`, sem dependências. Formato: `[flowing] mensagem { ...dados }`.
|
|
51
|
+
* O core não registra headers nem body. O que você logar passa pelo `redact`: `authorization`,
|
|
52
|
+
* `cookie`, `password`, `token` e afins saem como `[REDACTED]` (S-11).
|
|
53
|
+
*/
|
|
54
|
+
export declare function consoleLogger(opts?: ConsoleLoggerOptions, bindings?: Record<string, unknown>): Logger;
|
|
55
|
+
/** Logger que descarta tudo (`createApp({ logger: false })`). */
|
|
56
|
+
export declare const silentLogger: Logger;
|
|
57
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;IACjD;;;OAGG;IACH,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAO1F,MAAM,WAAW,oBAAoB;IACnC,sBAAsB;IACtB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAAC;IACnC;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC/B;AAoBD,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAehD,CAAC;AAKF,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,kBAAwB,EAAE,KAAK,SAAI,GAAG,OAAO,CAWvH;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,oBAAyB,EAAE,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAE7G;AAkED,iEAAiE;AACjE,eAAO,MAAM,YAAY,EAAE,MAQ1B,CAAC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
const LEVELS = { trace: 5, debug: 10, info: 20, warn: 30, error: 40, fatal: 50, silent: 99 };
|
|
2
|
+
/** Método do `console` de cada nível (`trace` e `fatal` não existem lá com esse sentido). */
|
|
3
|
+
const CONSOLE_METHOD = { trace: 'debug', debug: 'debug', info: 'info', warn: 'warn', error: 'error', fatal: 'error' };
|
|
4
|
+
/** `JSON.stringify` que não falha: erros viram `{ type, message, stack }` e ciclos viram `[Circular]`. */
|
|
5
|
+
function toJsonLine(record) {
|
|
6
|
+
const seen = new WeakSet();
|
|
7
|
+
return JSON.stringify(record, (_key, value) => {
|
|
8
|
+
if (value instanceof Error) {
|
|
9
|
+
const out = { type: value.name, message: value.message, stack: value.stack };
|
|
10
|
+
for (const [k, v] of Object.entries(value))
|
|
11
|
+
out[k] = v;
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
if (typeof value === 'bigint')
|
|
15
|
+
return value.toString();
|
|
16
|
+
if (typeof value === 'object' && value !== null) {
|
|
17
|
+
if (seen.has(value))
|
|
18
|
+
return '[Circular]';
|
|
19
|
+
seen.add(value);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** Chaves mascaradas por padrão: credenciais, cookies e tokens. */
|
|
25
|
+
export const DEFAULT_REDACT_KEYS = [
|
|
26
|
+
'authorization',
|
|
27
|
+
'proxy-authorization',
|
|
28
|
+
'cookie',
|
|
29
|
+
'set-cookie',
|
|
30
|
+
'x-api-key',
|
|
31
|
+
'api-key',
|
|
32
|
+
'password',
|
|
33
|
+
'passwd',
|
|
34
|
+
'secret',
|
|
35
|
+
'client-secret',
|
|
36
|
+
'token',
|
|
37
|
+
'access-token',
|
|
38
|
+
'refresh-token',
|
|
39
|
+
'id-token',
|
|
40
|
+
];
|
|
41
|
+
const REDACTED = '[REDACTED]';
|
|
42
|
+
const normalizeKey = (key) => key.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
43
|
+
/** Cópia dos dados com as chaves sensíveis mascaradas. Erros, datas e buffers passam como estão. */
|
|
44
|
+
export function redactValue(value, keys, seen = new WeakSet(), depth = 0) {
|
|
45
|
+
if (typeof value !== 'object' || value === null || depth > 10)
|
|
46
|
+
return value;
|
|
47
|
+
if (value instanceof Error || value instanceof Date || ArrayBuffer.isView(value))
|
|
48
|
+
return value;
|
|
49
|
+
if (seen.has(value))
|
|
50
|
+
return '[Circular]';
|
|
51
|
+
seen.add(value);
|
|
52
|
+
if (Array.isArray(value))
|
|
53
|
+
return value.map((v) => redactValue(v, keys, seen, depth + 1));
|
|
54
|
+
const out = {};
|
|
55
|
+
for (const [k, v] of Object.entries(value)) {
|
|
56
|
+
out[k] = keys.has(normalizeKey(k)) ? REDACTED : redactValue(v, keys, seen, depth + 1);
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Logger padrão sobre o `console`, sem dependências. Formato: `[flowing] mensagem { ...dados }`.
|
|
62
|
+
* O core não registra headers nem body. O que você logar passa pelo `redact`: `authorization`,
|
|
63
|
+
* `cookie`, `password`, `token` e afins saem como `[REDACTED]` (S-11).
|
|
64
|
+
*/
|
|
65
|
+
export function consoleLogger(opts = {}, bindings = {}) {
|
|
66
|
+
return new ConsoleLogger(compileConsoleConfig(opts), bindings);
|
|
67
|
+
}
|
|
68
|
+
function compileConsoleConfig(opts) {
|
|
69
|
+
return {
|
|
70
|
+
min: LEVELS[opts.level ?? 'info'],
|
|
71
|
+
keys: opts.redact === false ? undefined : new Set([...DEFAULT_REDACT_KEYS, ...(opts.redact ?? [])].map(normalizeKey)),
|
|
72
|
+
json: opts.format === 'json',
|
|
73
|
+
stdout: opts.stream === 'stdout',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Um `child()` por requisição custa só este objeto com as bindings: os métodos ficam no protótipo e a
|
|
78
|
+
* configuração (nível, `Set` do redact, formato) é a mesma do logger pai.
|
|
79
|
+
*/
|
|
80
|
+
class ConsoleLogger {
|
|
81
|
+
cfg;
|
|
82
|
+
bindings;
|
|
83
|
+
constructor(cfg, bindings) {
|
|
84
|
+
this.cfg = cfg;
|
|
85
|
+
this.bindings = bindings;
|
|
86
|
+
}
|
|
87
|
+
trace(objOrMsg, msg) {
|
|
88
|
+
this.emit('trace', objOrMsg, msg);
|
|
89
|
+
}
|
|
90
|
+
debug(objOrMsg, msg) {
|
|
91
|
+
this.emit('debug', objOrMsg, msg);
|
|
92
|
+
}
|
|
93
|
+
info(objOrMsg, msg) {
|
|
94
|
+
this.emit('info', objOrMsg, msg);
|
|
95
|
+
}
|
|
96
|
+
warn(objOrMsg, msg) {
|
|
97
|
+
this.emit('warn', objOrMsg, msg);
|
|
98
|
+
}
|
|
99
|
+
error(objOrMsg, msg) {
|
|
100
|
+
this.emit('error', objOrMsg, msg);
|
|
101
|
+
}
|
|
102
|
+
fatal(objOrMsg, msg) {
|
|
103
|
+
this.emit('fatal', objOrMsg, msg);
|
|
104
|
+
}
|
|
105
|
+
child(extra) {
|
|
106
|
+
return new ConsoleLogger(this.cfg, { ...this.bindings, ...extra });
|
|
107
|
+
}
|
|
108
|
+
emit(level, objOrMsg, msg) {
|
|
109
|
+
if (LEVELS[level] < this.cfg.min)
|
|
110
|
+
return;
|
|
111
|
+
const [data, text] = typeof objOrMsg === 'string' ? [{}, objOrMsg] : [objOrMsg, msg ?? ''];
|
|
112
|
+
const merged = { ...this.bindings, ...data };
|
|
113
|
+
const keys = this.cfg.keys;
|
|
114
|
+
const safe = (keys ? redactValue(merged, keys) : merged);
|
|
115
|
+
const out = this.cfg.stdout ? 'log' : CONSOLE_METHOD[level];
|
|
116
|
+
if (this.cfg.json) {
|
|
117
|
+
console[out](toJsonLine({ level, time: new Date().toISOString(), msg: text, ...safe }));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
console[out](`[flowing] ${text}`, safe);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Logger que descarta tudo (`createApp({ logger: false })`). */
|
|
125
|
+
export const silentLogger = {
|
|
126
|
+
trace() { },
|
|
127
|
+
debug() { },
|
|
128
|
+
info() { },
|
|
129
|
+
warn() { },
|
|
130
|
+
error() { },
|
|
131
|
+
fatal() { },
|
|
132
|
+
child: () => silentLogger,
|
|
133
|
+
};
|
|
134
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { FileRules } from './uploads/types.ts';
|
|
2
|
+
import type { Middleware } from './compose.ts';
|
|
3
|
+
import type { Guard } from './guard.ts';
|
|
4
|
+
import { type ScopedHooks } from './hooks.ts';
|
|
5
|
+
export declare const ROUTER_METADATA: unique symbol;
|
|
6
|
+
/**
|
|
7
|
+
* Resposta com tipo de conteúdo declarado (F-31). Sem `contentType`, a entrada é um schema JSON.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* response: { 200: { contentType: ['application/json', 'text/csv'], schema: Users } }
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export interface ResponseContent {
|
|
14
|
+
/** Um tipo ou a lista de tipos oferecidos; com vários, o cliente escolhe pelo `Accept`. */
|
|
15
|
+
contentType: string | readonly string[];
|
|
16
|
+
/** Schema dos dados. Em formatos não JSON, valida e remove campos antes do serializador. */
|
|
17
|
+
schema?: object;
|
|
18
|
+
}
|
|
19
|
+
/** Schema JSON (como sempre) ou `{ contentType, schema? }`. */
|
|
20
|
+
export type ResponseEntry = object | ResponseContent;
|
|
21
|
+
export interface RouteSchemas {
|
|
22
|
+
params?: object;
|
|
23
|
+
body?: object;
|
|
24
|
+
query?: object;
|
|
25
|
+
headers?: object;
|
|
26
|
+
response?: Record<number, ResponseEntry>;
|
|
27
|
+
/** Campos de arquivo (`multipart/form-data`): nome do campo → regras. Os campos de texto vão no `body`. */
|
|
28
|
+
files?: FileRules;
|
|
29
|
+
}
|
|
30
|
+
export declare function isResponseContent(entry: unknown): entry is ResponseContent;
|
|
31
|
+
export interface MethodMetadata {
|
|
32
|
+
method?: string;
|
|
33
|
+
path?: string;
|
|
34
|
+
schemas: RouteSchemas;
|
|
35
|
+
handlerName?: string | symbol;
|
|
36
|
+
/** `@Middlewares` no método (F-01). */
|
|
37
|
+
middlewares: Middleware[];
|
|
38
|
+
/** `@Guards` no método (F-01). */
|
|
39
|
+
guards: Guard[];
|
|
40
|
+
/** `@OnSend`, `@OnResponse` e `@OnError` no método (F-43). */
|
|
41
|
+
hooks: ScopedHooks;
|
|
42
|
+
}
|
|
43
|
+
export interface RouterMetadata {
|
|
44
|
+
/** `true` apenas quando a própria classe recebeu `@Router` (não herda). */
|
|
45
|
+
isRouter: boolean;
|
|
46
|
+
prefix: string;
|
|
47
|
+
methods: Map<string | symbol, MethodMetadata>;
|
|
48
|
+
/** `@Middlewares` na classe: valem para todas as rotas da classe (F-01). */
|
|
49
|
+
middlewares: Middleware[];
|
|
50
|
+
/** `@Guards` na classe (F-01). */
|
|
51
|
+
guards: Guard[];
|
|
52
|
+
/** Hooks da classe (F-43). */
|
|
53
|
+
hooks: ScopedHooks;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Retorna a metadata **própria** da classe.
|
|
57
|
+
*
|
|
58
|
+
* Em subclasses, `context.metadata` herda do pai via protótipo. Ler a chave direto
|
|
59
|
+
* devolveria o objeto do pai, e qualquer escrita o corromperia (B-09). Por isso
|
|
60
|
+
* clonamos a metadata herdada na primeira escrita (copy-on-write): a subclasse
|
|
61
|
+
* herda as rotas do pai, mas nunca altera a classe base.
|
|
62
|
+
*/
|
|
63
|
+
export declare function getOrCreateMetadata(meta: DecoratorMetadataObject): RouterMetadata;
|
|
64
|
+
/** Lê a metadata própria de uma classe já decorada, sem criar nem herdar. */
|
|
65
|
+
export declare function readOwnMetadata(Class: object): RouterMetadata | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Ponto de entrada dos decorators: valida o ambiente e devolve a metadata própria da classe.
|
|
68
|
+
*
|
|
69
|
+
* - R-02: com `experimentalDecorators`, o TypeScript chama o decorator com
|
|
70
|
+
* `(target, propertyKey, descriptor)` em vez de `(value, context)`.
|
|
71
|
+
* - R-01: sem `Symbol.metadata`, o `context.metadata` chega `undefined` e não há onde guardar as rotas.
|
|
72
|
+
*
|
|
73
|
+
* Nos dois casos, falhamos cedo com uma mensagem que diz como resolver.
|
|
74
|
+
*/
|
|
75
|
+
export declare function metadataFor(context: unknown, decorator: string): RouterMetadata;
|
|
76
|
+
/**
|
|
77
|
+
* Junta schemas vindos de `@Get(path, schemas)` e de `@Schema(...)` no mesmo método.
|
|
78
|
+
* Partes diferentes se combinam; a mesma parte declarada duas vezes é erro, para não haver
|
|
79
|
+
* dúvida sobre qual vale.
|
|
80
|
+
*/
|
|
81
|
+
export declare function mergeSchemas(method: MethodMetadata, schemas: RouteSchemas, where: string): void;
|
|
82
|
+
export declare function getOrCreateMethod(meta: RouterMetadata, name: string | symbol): MethodMetadata;
|
|
83
|
+
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/core/metadata.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAA2B,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AACvE,eAAO,MAAM,eAAe,eAA+B,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,2FAA2F;IAC3F,WAAW,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACxC,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,eAAe,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzC,2GAA2G;IAC3G,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAI1E;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,uCAAuC;IACvC,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,kCAAkC;IAClC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;IAC9C,4EAA4E;IAC5E,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,kCAAkC;IAClC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,8BAA8B;IAC9B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,cAAc,CAqBjF;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAKzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc,CAe/E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAW/F;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,cAAc,CAO7F"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { concatHooks, emptyHooks } from './hooks.js';
|
|
2
|
+
export const ROUTER_METADATA = Symbol.for('flowing:router');
|
|
3
|
+
export function isResponseContent(entry) {
|
|
4
|
+
if (typeof entry !== 'object' || entry === null || !('contentType' in entry))
|
|
5
|
+
return false;
|
|
6
|
+
const ct = entry.contentType;
|
|
7
|
+
return typeof ct === 'string' || Array.isArray(ct);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Retorna a metadata **própria** da classe.
|
|
11
|
+
*
|
|
12
|
+
* Em subclasses, `context.metadata` herda do pai via protótipo. Ler a chave direto
|
|
13
|
+
* devolveria o objeto do pai, e qualquer escrita o corromperia (B-09). Por isso
|
|
14
|
+
* clonamos a metadata herdada na primeira escrita (copy-on-write): a subclasse
|
|
15
|
+
* herda as rotas do pai, mas nunca altera a classe base.
|
|
16
|
+
*/
|
|
17
|
+
export function getOrCreateMetadata(meta) {
|
|
18
|
+
if (Object.hasOwn(meta, ROUTER_METADATA)) {
|
|
19
|
+
return meta[ROUTER_METADATA];
|
|
20
|
+
}
|
|
21
|
+
const inherited = meta[ROUTER_METADATA];
|
|
22
|
+
const own = {
|
|
23
|
+
isRouter: false,
|
|
24
|
+
prefix: '',
|
|
25
|
+
methods: new Map([...(inherited?.methods ?? [])].map(([name, m]) => [
|
|
26
|
+
name,
|
|
27
|
+
{ ...m, schemas: { ...m.schemas }, middlewares: [...m.middlewares], guards: [...m.guards], hooks: concatHooks(m.hooks) },
|
|
28
|
+
])),
|
|
29
|
+
// A subclasse herda os middlewares/guards de classe do pai e pode acrescentar os seus.
|
|
30
|
+
middlewares: [...(inherited?.middlewares ?? [])],
|
|
31
|
+
guards: [...(inherited?.guards ?? [])],
|
|
32
|
+
hooks: concatHooks(inherited?.hooks ?? emptyHooks()),
|
|
33
|
+
};
|
|
34
|
+
meta[ROUTER_METADATA] = own;
|
|
35
|
+
return own;
|
|
36
|
+
}
|
|
37
|
+
/** Lê a metadata própria de uma classe já decorada, sem criar nem herdar. */
|
|
38
|
+
export function readOwnMetadata(Class) {
|
|
39
|
+
if (!Object.hasOwn(Class, Symbol.metadata))
|
|
40
|
+
return undefined;
|
|
41
|
+
const meta = Class[Symbol.metadata];
|
|
42
|
+
if (!meta || !Object.hasOwn(meta, ROUTER_METADATA))
|
|
43
|
+
return undefined;
|
|
44
|
+
return meta[ROUTER_METADATA];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Ponto de entrada dos decorators: valida o ambiente e devolve a metadata própria da classe.
|
|
48
|
+
*
|
|
49
|
+
* - R-02: com `experimentalDecorators`, o TypeScript chama o decorator com
|
|
50
|
+
* `(target, propertyKey, descriptor)` em vez de `(value, context)`.
|
|
51
|
+
* - R-01: sem `Symbol.metadata`, o `context.metadata` chega `undefined` e não há onde guardar as rotas.
|
|
52
|
+
*
|
|
53
|
+
* Nos dois casos, falhamos cedo com uma mensagem que diz como resolver.
|
|
54
|
+
*/
|
|
55
|
+
export function metadataFor(context, decorator) {
|
|
56
|
+
if (typeof context !== 'object' || context === null || !('kind' in context)) {
|
|
57
|
+
throw new Error(`[flowing] @${decorator} received legacy decorator arguments. FlowingTS uses standard (TC39) ` +
|
|
58
|
+
`decorators: remove "experimentalDecorators" (and "emitDecoratorMetadata") from your tsconfig.json.`);
|
|
59
|
+
}
|
|
60
|
+
const meta = context.metadata;
|
|
61
|
+
if (!meta) {
|
|
62
|
+
throw new Error(`[flowing] @${decorator}: decorator metadata is unavailable (Symbol.metadata is not defined). ` +
|
|
63
|
+
`Import 'flowingts' before declaring routers, or use TypeScript >= 5.2 / a runtime with decorator metadata.`);
|
|
64
|
+
}
|
|
65
|
+
return getOrCreateMetadata(meta);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Junta schemas vindos de `@Get(path, schemas)` e de `@Schema(...)` no mesmo método.
|
|
69
|
+
* Partes diferentes se combinam; a mesma parte declarada duas vezes é erro, para não haver
|
|
70
|
+
* dúvida sobre qual vale.
|
|
71
|
+
*/
|
|
72
|
+
export function mergeSchemas(method, schemas, where) {
|
|
73
|
+
for (const key of Object.keys(schemas)) {
|
|
74
|
+
if (schemas[key] === undefined)
|
|
75
|
+
continue;
|
|
76
|
+
if (method.schemas[key] !== undefined) {
|
|
77
|
+
throw new Error(`[flowing] ${where}: schema "${key}" is declared twice for ${String(method.handlerName)}. ` +
|
|
78
|
+
`Declare each part either in the HTTP decorator or in @Schema, not both.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
method.schemas = { ...method.schemas, ...schemas };
|
|
82
|
+
}
|
|
83
|
+
export function getOrCreateMethod(meta, name) {
|
|
84
|
+
let m = meta.methods.get(name);
|
|
85
|
+
if (!m) {
|
|
86
|
+
m = { schemas: {}, handlerName: name, middlewares: [], guards: [], hooks: emptyHooks() };
|
|
87
|
+
meta.methods.set(name, m);
|
|
88
|
+
}
|
|
89
|
+
return m;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/core/metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type http from 'node:http';
|
|
2
|
+
import type https from 'node:https';
|
|
3
|
+
import type { TlsOptions } from '../server/tls.ts';
|
|
4
|
+
import type { FlowingApp } from './app.ts';
|
|
5
|
+
import { type GroupOptions, type ManualRouteOptions, type MethodSelector, type MountOptions, type RouteGroup, type RouteScope } from './compiler.ts';
|
|
6
|
+
import type { InjectOptions, InjectResponse } from './inject.ts';
|
|
7
|
+
import type { ListenOptions } from './app.ts';
|
|
8
|
+
import type { Logger } from './logger.ts';
|
|
9
|
+
import type { Middleware } from './compose.ts';
|
|
10
|
+
import type { OnSendHook } from './context.ts';
|
|
11
|
+
import type { OnCloseHook, OnErrorHook, OnRequestHook, OnResponseHook } from './app.ts';
|
|
12
|
+
import type { OpenAPIOptions } from '../openapi/generate.ts';
|
|
13
|
+
import type { HealthOptions } from './health.ts';
|
|
14
|
+
import type { StaticOptions } from '../server/static.ts';
|
|
15
|
+
/**
|
|
16
|
+
* Retorno de `app.mount()` (F-30): permite mapear manualmente métodos do grupo e continuar
|
|
17
|
+
* encadeando chamadas do app.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* app
|
|
21
|
+
* .mount(new UserRoutes(repo))
|
|
22
|
+
* .get('/legacy/:id', (r) => r.getUser, { guards: [isAdmin] })
|
|
23
|
+
* .mount(HealthRoutes);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare class MountedGroup<T extends object> {
|
|
27
|
+
#private;
|
|
28
|
+
readonly app: FlowingApp;
|
|
29
|
+
/** @internal Criado por `app.mount()`. */
|
|
30
|
+
constructor(app: FlowingApp, group: RouteGroup, register: (group: RouteGroup, method: string, path: string, select: MethodSelector<object>, opts?: ManualRouteOptions) => void, scope?: RouteScope);
|
|
31
|
+
/** Mapeia `GET path` (relativo ao prefixo do grupo) para o método selecionado. */
|
|
32
|
+
get(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
33
|
+
post(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
34
|
+
put(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
35
|
+
patch(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
36
|
+
delete(path: string, select: MethodSelector<T>, opts?: ManualRouteOptions): this;
|
|
37
|
+
mount<U extends object>(ref: new () => U, options?: MountOptions<U>): MountedGroup<U>;
|
|
38
|
+
mount<U extends object>(ref: U extends abstract new (...args: never) => unknown ? never : U, options?: MountOptions<U>): MountedGroup<U>;
|
|
39
|
+
/** Arquivos estáticos no mesmo escopo deste `mount()` (o grupo atual, ou o app). */
|
|
40
|
+
static(prefix: string, root: string, opts?: StaticOptions): this;
|
|
41
|
+
/** Grupo aninhado no grupo atual (ou no app, fora de um grupo). */
|
|
42
|
+
group(options: GroupOptions, define: (group: RouteGroupScope) => unknown): this;
|
|
43
|
+
use(mw: Middleware): FlowingApp;
|
|
44
|
+
openapi(opts?: OpenAPIOptions): FlowingApp;
|
|
45
|
+
health(opts?: HealthOptions): FlowingApp;
|
|
46
|
+
openapiDocument(opts?: OpenAPIOptions): Record<string, unknown>;
|
|
47
|
+
onError(h: OnErrorHook): FlowingApp;
|
|
48
|
+
onSend(hook: OnSendHook): FlowingApp;
|
|
49
|
+
onRequest(hook: OnRequestHook): FlowingApp;
|
|
50
|
+
onResponse(hook: OnResponseHook): FlowingApp;
|
|
51
|
+
onClose(hook: OnCloseHook): FlowingApp;
|
|
52
|
+
listen(options: ListenOptions & {
|
|
53
|
+
tls: TlsOptions;
|
|
54
|
+
}): Promise<https.Server>;
|
|
55
|
+
listen(options?: number | ListenOptions): Promise<http.Server>;
|
|
56
|
+
reloadTLS(tls: TlsOptions): void;
|
|
57
|
+
close(graceMs?: number): Promise<void>;
|
|
58
|
+
callback(): (req: http.IncomingMessage, res: http.ServerResponse) => void;
|
|
59
|
+
inject(opts: InjectOptions | string): Promise<InjectResponse>;
|
|
60
|
+
get log(): Logger;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* O `g` de `app.group(opts, (g) => …)`: só registra rotas, todas com o prefixo, os middlewares e os guards
|
|
64
|
+
* do grupo. Middlewares globais e hooks continuam no app (`app.use()`, `app.onError()`…).
|
|
65
|
+
*/
|
|
66
|
+
export declare class RouteGroupScope {
|
|
67
|
+
#private;
|
|
68
|
+
/** @internal Criado por `app.group()`. */
|
|
69
|
+
constructor(app: FlowingApp, scope: RouteScope);
|
|
70
|
+
mount<U extends object>(ref: new () => U, options?: MountOptions<U>): MountedGroup<U>;
|
|
71
|
+
mount<U extends object>(ref: U extends abstract new (...args: never) => unknown ? never : U, options?: MountOptions<U>): MountedGroup<U>;
|
|
72
|
+
/** Arquivos estáticos dentro do grupo: herdam prefixo, host, guards e middlewares. */
|
|
73
|
+
static(prefix: string, root: string, opts?: StaticOptions): this;
|
|
74
|
+
/** Grupo aninhado: prefixos se somam, middlewares e guards se acumulam de fora para dentro. */
|
|
75
|
+
group(options: GroupOptions, define: (group: RouteGroupScope) => unknown): this;
|
|
76
|
+
}
|
|
77
|
+
//# 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,131 @@
|
|
|
1
|
+
import { ROOT_SCOPE, } from './compiler.js';
|
|
2
|
+
/**
|
|
3
|
+
* Retorno de `app.mount()` (F-30): permite mapear manualmente métodos do grupo e continuar
|
|
4
|
+
* encadeando chamadas do app.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* app
|
|
8
|
+
* .mount(new UserRoutes(repo))
|
|
9
|
+
* .get('/legacy/:id', (r) => r.getUser, { guards: [isAdmin] })
|
|
10
|
+
* .mount(HealthRoutes);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export class MountedGroup {
|
|
14
|
+
app;
|
|
15
|
+
#group;
|
|
16
|
+
#register;
|
|
17
|
+
/** @internal Criado por `app.mount()`. */
|
|
18
|
+
constructor(app, group, register, scope = ROOT_SCOPE) {
|
|
19
|
+
this.app = app;
|
|
20
|
+
this.#group = group;
|
|
21
|
+
this.#register = register;
|
|
22
|
+
this.#scope = scope;
|
|
23
|
+
}
|
|
24
|
+
#scope;
|
|
25
|
+
#map(method, path, select, opts) {
|
|
26
|
+
this.#register(this.#group, method, path, select, opts);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
/** Mapeia `GET path` (relativo ao prefixo do grupo) para o método selecionado. */
|
|
30
|
+
get(path, select, opts) {
|
|
31
|
+
return this.#map('GET', path, select, opts);
|
|
32
|
+
}
|
|
33
|
+
post(path, select, opts) {
|
|
34
|
+
return this.#map('POST', path, select, opts);
|
|
35
|
+
}
|
|
36
|
+
put(path, select, opts) {
|
|
37
|
+
return this.#map('PUT', path, select, opts);
|
|
38
|
+
}
|
|
39
|
+
patch(path, select, opts) {
|
|
40
|
+
return this.#map('PATCH', path, select, opts);
|
|
41
|
+
}
|
|
42
|
+
delete(path, select, opts) {
|
|
43
|
+
return this.#map('DELETE', path, select, opts);
|
|
44
|
+
}
|
|
45
|
+
mount(ref, options) {
|
|
46
|
+
// Dentro de um `group()`, o próximo `mount()` continua no mesmo grupo.
|
|
47
|
+
return this.app.mountIn(this.#scope, ref, options);
|
|
48
|
+
}
|
|
49
|
+
/** Arquivos estáticos no mesmo escopo deste `mount()` (o grupo atual, ou o app). */
|
|
50
|
+
static(prefix, root, opts) {
|
|
51
|
+
this.app.staticIn(this.#scope, prefix, root, opts ?? {});
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
/** Grupo aninhado no grupo atual (ou no app, fora de um grupo). */
|
|
55
|
+
group(options, define) {
|
|
56
|
+
this.app.groupIn(this.#scope, options, define);
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
use(mw) {
|
|
60
|
+
return this.app.use(mw);
|
|
61
|
+
}
|
|
62
|
+
openapi(opts) {
|
|
63
|
+
return this.app.openapi(opts);
|
|
64
|
+
}
|
|
65
|
+
health(opts) {
|
|
66
|
+
return this.app.health(opts);
|
|
67
|
+
}
|
|
68
|
+
openapiDocument(opts) {
|
|
69
|
+
return this.app.openapiDocument(opts);
|
|
70
|
+
}
|
|
71
|
+
onError(h) {
|
|
72
|
+
return this.app.onError(h);
|
|
73
|
+
}
|
|
74
|
+
onSend(hook) {
|
|
75
|
+
return this.app.onSend(hook);
|
|
76
|
+
}
|
|
77
|
+
onRequest(hook) {
|
|
78
|
+
return this.app.onRequest(hook);
|
|
79
|
+
}
|
|
80
|
+
onResponse(hook) {
|
|
81
|
+
return this.app.onResponse(hook);
|
|
82
|
+
}
|
|
83
|
+
onClose(hook) {
|
|
84
|
+
return this.app.onClose(hook);
|
|
85
|
+
}
|
|
86
|
+
listen(options) {
|
|
87
|
+
return this.app.listen(options);
|
|
88
|
+
}
|
|
89
|
+
reloadTLS(tls) {
|
|
90
|
+
this.app.reloadTLS(tls);
|
|
91
|
+
}
|
|
92
|
+
close(graceMs) {
|
|
93
|
+
return this.app.close(graceMs);
|
|
94
|
+
}
|
|
95
|
+
callback() {
|
|
96
|
+
return this.app.callback();
|
|
97
|
+
}
|
|
98
|
+
inject(opts) {
|
|
99
|
+
return this.app.inject(opts);
|
|
100
|
+
}
|
|
101
|
+
get log() {
|
|
102
|
+
return this.app.log;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* O `g` de `app.group(opts, (g) => …)`: só registra rotas, todas com o prefixo, os middlewares e os guards
|
|
107
|
+
* do grupo. Middlewares globais e hooks continuam no app (`app.use()`, `app.onError()`…).
|
|
108
|
+
*/
|
|
109
|
+
export class RouteGroupScope {
|
|
110
|
+
#app;
|
|
111
|
+
#scope;
|
|
112
|
+
/** @internal Criado por `app.group()`. */
|
|
113
|
+
constructor(app, scope) {
|
|
114
|
+
this.#app = app;
|
|
115
|
+
this.#scope = scope;
|
|
116
|
+
}
|
|
117
|
+
mount(ref, options) {
|
|
118
|
+
return this.#app.mountIn(this.#scope, ref, options);
|
|
119
|
+
}
|
|
120
|
+
/** Arquivos estáticos dentro do grupo: herdam prefixo, host, guards e middlewares. */
|
|
121
|
+
static(prefix, root, opts) {
|
|
122
|
+
this.#app.staticIn(this.#scope, prefix, root, opts ?? {});
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
/** Grupo aninhado: prefixos se somam, middlewares e guards se acumulam de fora para dentro. */
|
|
126
|
+
group(options, define) {
|
|
127
|
+
this.#app.groupIn(this.#scope, options, define);
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=mounted-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mounted-group.js","sourceRoot":"","sources":["../../src/core/mounted-group.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AppCore } from '../app/core.ts';
|
|
2
|
+
import { type Middleware } from '../compose.ts';
|
|
3
|
+
import type { Context } from '../context.ts';
|
|
4
|
+
import type { HealthConfig } from '../health.ts';
|
|
5
|
+
import { type OpenAPIOptions } from '../../openapi/generate.ts';
|
|
6
|
+
import type { RouteRegistry } from './registry.ts';
|
|
7
|
+
export type OpenAPIConfig = {
|
|
8
|
+
opts: OpenAPIOptions;
|
|
9
|
+
path: string;
|
|
10
|
+
docs: string | false;
|
|
11
|
+
pipeline: Middleware[];
|
|
12
|
+
cache: Map<string, string>;
|
|
13
|
+
};
|
|
14
|
+
/** Rotas servidas pelo próprio app: healthchecks e OpenAPI (documento e página). */
|
|
15
|
+
export declare class FrameworkRoutes {
|
|
16
|
+
private readonly core;
|
|
17
|
+
private readonly registry;
|
|
18
|
+
health: HealthConfig | undefined;
|
|
19
|
+
openapi: OpenAPIConfig | undefined;
|
|
20
|
+
constructor(core: AppCore, registry: RouteRegistry);
|
|
21
|
+
/** Paths servidos pelo próprio app (`health()`, `openapi()`), que encobririam uma rota GET do usuário. */
|
|
22
|
+
reservedPaths(except?: 'health' | 'openapi'): Map<string, string>;
|
|
23
|
+
/** Um path do framework não pode coincidir com uma rota GET/HEAD registrada nem com outro do framework. */
|
|
24
|
+
assertFreePaths(where: string, paths: readonly string[], kind: 'health' | 'openapi'): void;
|
|
25
|
+
/** Se a requisição é para `/openapi.json` ou `/docs` (quando ligados), responde e devolve `true`. */
|
|
26
|
+
serveOpenAPI(ctx: Context): Promise<boolean>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=framework-routes.d.ts.map
|