sashiko 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -27
- package/dist/core/app.d.ts +30 -6
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +73 -18
- package/dist/core/app.js.map +1 -1
- package/dist/core/compiler.d.ts +34 -10
- package/dist/core/compiler.d.ts.map +1 -1
- package/dist/core/compiler.js +60 -36
- package/dist/core/compiler.js.map +1 -1
- package/dist/core/context.d.ts +43 -7
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +41 -11
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +6 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/infer.d.ts +9 -1
- package/dist/core/infer.d.ts.map +1 -1
- package/dist/core/metadata.d.ts +21 -5
- package/dist/core/metadata.d.ts.map +1 -1
- package/dist/core/metadata.js +6 -0
- package/dist/core/metadata.js.map +1 -1
- 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/response.d.ts +22 -8
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +93 -15
- package/dist/core/response.js.map +1 -1
- package/dist/core/shutdown.d.ts +36 -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/decorators/index.d.ts +1 -1
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +1 -1
- package/dist/decorators/index.js.map +1 -1
- 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/middlewares/index.d.ts +1 -1
- package/dist/middlewares/index.d.ts.map +1 -1
- package/dist/middlewares/index.js.map +1 -1
- package/dist/middlewares/security-headers.d.ts +4 -2
- package/dist/middlewares/security-headers.d.ts.map +1 -1
- package/dist/middlewares/security-headers.js +10 -2
- package/dist/middlewares/security-headers.js.map +1 -1
- package/dist/schema/validation.d.ts +11 -0
- package/dist/schema/validation.d.ts.map +1 -1
- package/dist/schema/validation.js +18 -0
- package/dist/schema/validation.js.map +1 -1
- package/dist/utils/content-type.d.ts +8 -0
- package/dist/utils/content-type.d.ts.map +1 -1
- package/dist/utils/content-type.js +42 -0
- package/dist/utils/content-type.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/decorators/use.d.ts +0 -26
- package/dist/decorators/use.d.ts.map +0 -1
- package/dist/decorators/use.js +0 -38
- package/dist/decorators/use.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/core/compiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/core/compiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kFAAkF;AAClF,MAAM,MAAM,SAAS,GAAG,CAAC,UAAU,MAAM,CAAC,GAAG,MAAM,CAAC;AAEpD,KAAK,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC;AAE/C,2EAA2E;AAC3E,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,CAAC;AACzD,qEAAqE;AACrE,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,SAAS,EAAE,CAAC;AAErE,8EAA8E;AAC9E,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM;IACtC,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC1B,uDAAuD;IACvD,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5B,sGAAsG;IACtG,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0FAA0F;IAC1F,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACpC,gFAAgF;IAChF,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;CAC3B;AAED,iGAAiG;AACjG,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACpC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;CAC3B;AAED,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,GAAE,YAAiB,GAAG,UAAU,CAgBlF;AAED,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,EAAE,CAiBpE;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,EAChC,OAAO,GAAE,kBAAuB,GAC/B,aAAa,CAGf"}
|
package/dist/core/compiler.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readOwnMetadata } from './metadata.js';
|
|
2
2
|
import { joinPaths } from '../utils/path.js';
|
|
3
|
-
export function
|
|
3
|
+
export function createGroup(ref, options = {}) {
|
|
4
4
|
const isClass = typeof ref === 'function';
|
|
5
5
|
const Class = (isClass ? ref : ref.constructor);
|
|
6
6
|
const meta = readOwnMetadata(Class);
|
|
@@ -8,43 +8,67 @@ export function compileRoutes(ref, opts = {}) {
|
|
|
8
8
|
throw new Error(`[sashiko] Class ${Class.name} is not decorated with @Router('/prefix'). ` +
|
|
9
9
|
`Add it to register the class with app.mount().`);
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if (options.only && options.except) {
|
|
12
|
+
throw new Error(`[sashiko] app.mount(${Class.name}): use either "only" or "except", not both.`);
|
|
13
|
+
}
|
|
13
14
|
// Instâncias permitem injetar dependências pelo construtor: app.mount(new UserRoutes(repo))
|
|
14
15
|
const instance = isClass ? new Class() : ref;
|
|
15
|
-
|
|
16
|
-
const routes = [];
|
|
17
|
-
for (const [name, methodMeta] of meta.methods) {
|
|
18
|
-
if (!methodMeta.method || !methodMeta.path || !selected.has(String(name)))
|
|
19
|
-
continue;
|
|
20
|
-
const fn = instance[name];
|
|
21
|
-
if (typeof fn !== 'function')
|
|
22
|
-
continue;
|
|
23
|
-
routes.push({
|
|
24
|
-
method: methodMeta.method,
|
|
25
|
-
path: joinPaths(prefix, methodMeta.path),
|
|
26
|
-
handler: (ctx) => fn.call(instance, ctx),
|
|
27
|
-
schemas: methodMeta.schemas,
|
|
28
|
-
// Ordem: composição (app.mount) → classe → método (F-01, F-28)
|
|
29
|
-
middlewares: [...(opts.middlewares ?? []), ...meta.middlewares, ...methodMeta.middlewares],
|
|
30
|
-
guards: [...(opts.guards ?? []), ...meta.guards, ...methodMeta.guards],
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
return routes;
|
|
16
|
+
return { name: Class.name, instance, meta, prefix: options.prefix ?? meta.prefix, options };
|
|
34
17
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
18
|
+
/** Rotas declaradas na classe (`@Get`, `@Post`…), filtradas por `only`/`except` e `auto`. */
|
|
19
|
+
export function compileAutoRoutes(group) {
|
|
20
|
+
const { meta, options } = group;
|
|
21
|
+
if (options.auto === false)
|
|
22
|
+
return [];
|
|
23
|
+
const declared = [...meta.methods].filter(([, m]) => m.method && m.path).map(([name]) => name);
|
|
24
|
+
const pick = (selector, label) => new Set(selector(group.instance).map((fn) => resolveMethod(group, fn, label, declared)));
|
|
25
|
+
const excluded = options.except ? pick(options.except, 'except') : new Set();
|
|
26
|
+
const selected = options.only ? pick(options.only, 'only') : new Set(declared.filter((n) => !excluded.has(n)));
|
|
27
|
+
return declared
|
|
28
|
+
.filter((name) => selected.has(name))
|
|
29
|
+
.map((name) => {
|
|
30
|
+
const m = meta.methods.get(name);
|
|
31
|
+
return buildRoute(group, name, m, m.method, m.path);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/** Rota mapeada no app: `.get('/legacy/:id', (r) => r.getUser, opts)` (F-30). */
|
|
35
|
+
export function compileManualRoute(group, httpMethod, path, selector, options = {}) {
|
|
36
|
+
const name = resolveMethod(group, selector(group.instance), `.${httpMethod.toLowerCase()}('${path}')`);
|
|
37
|
+
return buildRoute(group, name, group.meta.methods.get(name), httpMethod, path, options);
|
|
38
|
+
}
|
|
39
|
+
function buildRoute(group, name, methodMeta, httpMethod, path, manual = {}) {
|
|
40
|
+
const fn = group.instance[name];
|
|
41
|
+
const { meta, options, instance } = group;
|
|
42
|
+
return {
|
|
43
|
+
method: httpMethod,
|
|
44
|
+
path: joinPaths(group.prefix, path),
|
|
45
|
+
handler: (ctx) => fn.call(instance, ctx),
|
|
46
|
+
schemas: methodMeta.schemas,
|
|
47
|
+
// Ordem: mount → classe → método → rota manual (F-01, F-28, F-30)
|
|
48
|
+
middlewares: [...(options.middlewares ?? []), ...meta.middlewares, ...methodMeta.middlewares, ...(manual.middlewares ?? [])],
|
|
49
|
+
guards: [...(options.guards ?? []), ...meta.guards, ...methodMeta.guards, ...(manual.guards ?? [])],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Descobre o nome do método a partir da função devolvida pelo seletor.
|
|
54
|
+
* Só aceita métodos com algum decorator do Sashiko (a "permissão" no nível do método).
|
|
55
|
+
*/
|
|
56
|
+
function resolveMethod(group, fn, where, allowed = [...group.meta.methods.keys()]) {
|
|
57
|
+
const target = group.instance;
|
|
58
|
+
const name = typeof fn === 'function' ? allowed.find((n) => target[n] === fn) : undefined;
|
|
59
|
+
if (name !== undefined)
|
|
60
|
+
return name;
|
|
61
|
+
const label = typeof fn === 'function' && fn.name ? `"${fn.name}"` : 'the selected value';
|
|
62
|
+
const available = allowed.map(String).join(', ') || '(none)';
|
|
63
|
+
const decorated = typeof fn === 'function' && [...group.meta.methods.keys()].some((n) => target[n] === fn);
|
|
64
|
+
const isMethod = typeof fn === 'function'
|
|
65
|
+
&& Object.values(Object.getOwnPropertyDescriptors(Object.getPrototypeOf(target))).some((d) => d.value === fn);
|
|
66
|
+
const reason = decorated
|
|
67
|
+
? `${label} has no HTTP verb decorator, so it is not an automatic route; map it manually with .get()/.post()…`
|
|
68
|
+
: isMethod
|
|
69
|
+
? `${label} has no Sashiko decorator (@Get, @Schema, @Middlewares, @Guards…), so it cannot be exposed`
|
|
70
|
+
: `${label} is not a method of ${group.name}`;
|
|
71
|
+
const at = where.startsWith('.') ? where : ` ${where}`;
|
|
72
|
+
throw new Error(`[sashiko] app.mount(${group.name})${at}: ${reason}. Available: ${available}.`);
|
|
49
73
|
}
|
|
50
74
|
//# sourceMappingURL=compiler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/core/compiler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/core/compiler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAA4C,MAAM,eAAe,CAAC;AAE1F,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAkD7C,MAAM,UAAU,WAAW,CAAC,GAAc,EAAE,OAAO,GAAiB,EAAE;IACpE,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,UAAU,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAqB,CAAC;IACpE,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,mBAAmB,KAAK,CAAC,IAAI,6CAA6C;YAC1E,gDAAgD,CACjD,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,uBAAuB,KAAK,CAAC,IAAI,6CAA6C,CAAC,CAAC;IAClG,CAAC;IACD,4FAA4F;IAC5F,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AAC9F,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IACjD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAChC,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtC,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IAC/F,MAAM,IAAI,GAAG,CAAC,QAAiC,EAAE,KAAa,EAAE,EAAE,CAChE,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE3F,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAmB,CAAC;IAC9F,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/G,OAAO,QAAQ;SACZ,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;SACpC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;QAClC,OAAO,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,MAAO,EAAE,CAAC,CAAC,IAAK,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACP,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,kBAAkB,CAChC,KAAiB,EACjB,UAAkB,EAClB,IAAY,EACZ,QAAgC,EAChC,OAAO,GAAuB,EAAE;IAEhC,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,UAAU,CAAC,WAAW,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC;IACvG,OAAO,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,UAAU,CACjB,KAAiB,EACjB,IAAqB,EACrB,UAA0B,EAC1B,UAAkB,EAClB,IAAY,EACZ,MAAM,GAAuB,EAAE;IAE/B,MAAM,EAAE,GAAI,KAAK,CAAC,QAA6C,CAAC,IAAI,CAA8B,CAAC;IACnG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC1C,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC;QACnC,OAAO,EAAE,CAAC,GAAY,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;QACjD,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,kEAAkE;QAClE,WAAW,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QAC5H,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;KACpG,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CACpB,KAAiB,EACjB,EAAW,EACX,KAAa,EACb,OAAO,GAAiC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAEtE,MAAM,MAAM,GAAG,KAAK,CAAC,QAA4C,CAAC;IAClE,MAAM,IAAI,GAAG,OAAO,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1F,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,UAAU,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAC1F,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;IAC7D,MAAM,SAAS,GAAG,OAAO,EAAE,KAAK,UAAU,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3G,MAAM,QAAQ,GAAG,OAAO,EAAE,KAAK,UAAU;WACpC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAChH,MAAM,MAAM,GAAG,SAAS;QACtB,CAAC,CAAC,GAAG,KAAK,oGAAoG;QAC9G,CAAC,CAAC,QAAQ;YACR,CAAC,CAAC,GAAG,KAAK,4FAA4F;YACtG,CAAC,CAAC,GAAG,KAAK,uBAAuB,KAAK,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;IACvD,MAAM,IAAI,KAAK,CAAC,uBAAuB,KAAK,CAAC,IAAI,IAAI,EAAE,KAAK,MAAM,gBAAgB,SAAS,GAAG,CAAC,CAAC;AAClG,CAAC"}
|
package/dist/core/context.d.ts
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
import type { IncomingMessage, OutgoingHttpHeader, ServerResponse } from 'node:http';
|
|
2
2
|
import { Readable } from 'node:stream';
|
|
3
3
|
import { type Logger } from './logger.ts';
|
|
4
|
-
import type { InferBody, InferParams, InferQuery } from './infer.ts';
|
|
4
|
+
import type { InferBody, InferParams, InferQuery, InferResponse } from './infer.ts';
|
|
5
5
|
import type { RouteSchemas } from './metadata.ts';
|
|
6
|
+
import { type Serializer } from './response.ts';
|
|
7
|
+
/** @internal Envio cru, sem pipeline: usado pelo próprio pipeline, por erros e por 404/405. */
|
|
8
|
+
export declare const kRawSend: unique symbol;
|
|
9
|
+
/** @internal Liga o contexto aos schemas de resposta da rota, antes do handler (F-32). */
|
|
10
|
+
export declare const kBindResponse: unique symbol;
|
|
11
|
+
type RawBody = string | Uint8Array | Readable;
|
|
12
|
+
/** Status aceitos por `ctx.status()`: os declarados no schema de resposta, ou qualquer um sem schema (F-32). */
|
|
13
|
+
export type DeclaredStatus<S extends RouteSchemas> = S['response'] extends Record<number, unknown> ? keyof S['response'] & number : number;
|
|
14
|
+
/** Corpo esperado para o status `St`: o do schema, ou qualquer valor sem schema (F-32). */
|
|
15
|
+
export type BodyFor<S extends RouteSchemas, St extends number> = S['response'] extends Record<number, unknown> ? InferResponse<S, St> : unknown;
|
|
16
|
+
/**
|
|
17
|
+
* Contexto depois de `ctx.status(St)`: `json()` e `send()` exigem o corpo do status escolhido (F-32).
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* return ctx.status(202).json({ jobId }); // o TypeScript confere o corpo contra o schema do 202
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export type StatusContext<S extends RouteSchemas, St extends number> = Omit<Context<S>, 'json' | 'send'> & {
|
|
24
|
+
json(body: BodyFor<S, St>): Context<S>;
|
|
25
|
+
send(body: BodyFor<S, St> | RawBody, contentType?: string): Context<S>;
|
|
26
|
+
};
|
|
6
27
|
/**
|
|
7
28
|
* Estado por requisição, compartilhado entre middlewares, guards e handlers.
|
|
8
29
|
* Estenda com declaration merging para ter tipos (F-01):
|
|
@@ -52,10 +73,15 @@ export declare class Context<S extends RouteSchemas = RouteSchemas> {
|
|
|
52
73
|
/** `true` quando o handler chamou `ctx.status()`. Usado para escolher o schema de resposta (B-05). */
|
|
53
74
|
statusExplicit: boolean;
|
|
54
75
|
private streaming;
|
|
76
|
+
private bound;
|
|
55
77
|
constructor(req: IncomingMessage, res: ServerResponse, opts?: ContextOptions);
|
|
56
78
|
/** IP do cliente conforme o socket. Sem `trustProxy`, `X-Forwarded-For` é ignorado (S-09). */
|
|
57
79
|
get ip(): string;
|
|
58
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Define o status. Com schemas de resposta, aceita só os status declarados e o encadeamento tipa o
|
|
82
|
+
* corpo: `ctx.status(202).json({ jobId })` (F-32).
|
|
83
|
+
*/
|
|
84
|
+
status<const St extends DeclaredStatus<S>>(code: St): StatusContext<S, St>;
|
|
59
85
|
/**
|
|
60
86
|
* `true` quando a resposta já foi enviada (ou está sendo, no caso de streams).
|
|
61
87
|
* Depois disso o framework não escreve mais nada na resposta.
|
|
@@ -65,15 +91,24 @@ export declare class Context<S extends RouteSchemas = RouteSchemas> {
|
|
|
65
91
|
get(name: string): string | undefined;
|
|
66
92
|
/** Define um header da resposta. */
|
|
67
93
|
header(name: string, value: OutgoingHttpHeader): this;
|
|
94
|
+
/**
|
|
95
|
+
* Envia JSON. No handler, passa pelo mesmo pipeline do `return`: schema do status, remoção de
|
|
96
|
+
* campos não declarados e status padrão (F-32).
|
|
97
|
+
*/
|
|
68
98
|
json(data: unknown): this;
|
|
69
|
-
/** Resposta em texto puro (`text/plain; charset=utf-8`)
|
|
99
|
+
/** Resposta em texto puro (`text/plain; charset=utf-8`), pelo mesmo pipeline do `return`. */
|
|
70
100
|
text(data: string): this;
|
|
71
101
|
/**
|
|
72
|
-
* Envia
|
|
73
|
-
* `
|
|
74
|
-
* dinâmico antes: o framework não faz isso por você (S-02).
|
|
102
|
+
* Envia o corpo pelo mesmo pipeline do `return` (F-32): com `contentType` informado, usa esse tipo;
|
|
103
|
+
* senão, a negociação do `Accept` ou o tipo do valor (string, Buffer, stream, objeto → JSON).
|
|
104
|
+
* Para HTML, faça o escape do conteúdo dinâmico antes: o framework não faz isso por você (S-02).
|
|
75
105
|
*/
|
|
76
|
-
send(body:
|
|
106
|
+
send(body: unknown, contentType?: string): this;
|
|
107
|
+
private dispatch;
|
|
108
|
+
/** @internal Liga os schemas de resposta da rota (o app chama antes do handler). */
|
|
109
|
+
[kBindResponse](response: RouteSchemas['response'], serializers: ReadonlyMap<string, Serializer>): void;
|
|
110
|
+
/** @internal Envio cru, sem schema: string, bytes ou stream. */
|
|
111
|
+
[kRawSend](body: RawBody, contentType?: string): this;
|
|
77
112
|
/**
|
|
78
113
|
* Redireciona (padrão 302). Não use `url` vinda do usuário sem validar: isso abre um
|
|
79
114
|
* open redirect. Prefira caminhos relativos ou uma lista de destinos permitidos.
|
|
@@ -81,4 +116,5 @@ export declare class Context<S extends RouteSchemas = RouteSchemas> {
|
|
|
81
116
|
redirect(url: string, status?: 301 | 302 | 303 | 307 | 308): this;
|
|
82
117
|
throw(status: number, message: string, code?: string): never;
|
|
83
118
|
}
|
|
119
|
+
export {};
|
|
84
120
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
|
package/dist/core/context.js
CHANGED
|
@@ -3,6 +3,11 @@ import { pipeline } from 'node:stream/promises';
|
|
|
3
3
|
import { HttpError } from './errors.js';
|
|
4
4
|
import { parseQuery } from '../utils/query.js';
|
|
5
5
|
import { silentLogger } from './logger.js';
|
|
6
|
+
import { sendResult } from './response.js';
|
|
7
|
+
/** @internal Envio cru, sem pipeline: usado pelo próprio pipeline, por erros e por 404/405. */
|
|
8
|
+
export const kRawSend = Symbol('sashiko.rawSend');
|
|
9
|
+
/** @internal Liga o contexto aos schemas de resposta da rota, antes do handler (F-32). */
|
|
10
|
+
export const kBindResponse = Symbol('sashiko.bindResponse');
|
|
6
11
|
/**
|
|
7
12
|
* Contexto da requisição. Passe os schemas da rota no genérico para tipar
|
|
8
13
|
* `params`, `query` e `body` a partir do `@Schema` (F-02):
|
|
@@ -32,6 +37,7 @@ export class Context {
|
|
|
32
37
|
/** `true` quando o handler chamou `ctx.status()`. Usado para escolher o schema de resposta (B-05). */
|
|
33
38
|
statusExplicit = false;
|
|
34
39
|
streaming = false;
|
|
40
|
+
bound;
|
|
35
41
|
constructor(req, res, opts = {}) {
|
|
36
42
|
this.req = req;
|
|
37
43
|
this.res = res;
|
|
@@ -46,6 +52,10 @@ export class Context {
|
|
|
46
52
|
get ip() {
|
|
47
53
|
return this.req.socket.remoteAddress ?? '';
|
|
48
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Define o status. Com schemas de resposta, aceita só os status declarados e o encadeamento tipa o
|
|
57
|
+
* corpo: `ctx.status(202).json({ jobId })` (F-32).
|
|
58
|
+
*/
|
|
49
59
|
status(code) {
|
|
50
60
|
this.res.statusCode = code;
|
|
51
61
|
this.statusExplicit = true;
|
|
@@ -68,23 +78,42 @@ export class Context {
|
|
|
68
78
|
this.res.setHeader(name, value);
|
|
69
79
|
return this;
|
|
70
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Envia JSON. No handler, passa pelo mesmo pipeline do `return`: schema do status, remoção de
|
|
83
|
+
* campos não declarados e status padrão (F-32).
|
|
84
|
+
*/
|
|
71
85
|
json(data) {
|
|
72
|
-
|
|
73
|
-
return this;
|
|
74
|
-
this.res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
75
|
-
this.res.end(JSON.stringify(data));
|
|
76
|
-
return this;
|
|
86
|
+
return this.dispatch(data, 'json');
|
|
77
87
|
}
|
|
78
|
-
/** Resposta em texto puro (`text/plain; charset=utf-8`)
|
|
88
|
+
/** Resposta em texto puro (`text/plain; charset=utf-8`), pelo mesmo pipeline do `return`. */
|
|
79
89
|
text(data) {
|
|
80
|
-
return this.
|
|
90
|
+
return this.dispatch(data, 'text');
|
|
81
91
|
}
|
|
82
92
|
/**
|
|
83
|
-
* Envia
|
|
84
|
-
* `
|
|
85
|
-
* dinâmico antes: o framework não faz isso por você (S-02).
|
|
93
|
+
* Envia o corpo pelo mesmo pipeline do `return` (F-32): com `contentType` informado, usa esse tipo;
|
|
94
|
+
* senão, a negociação do `Accept` ou o tipo do valor (string, Buffer, stream, objeto → JSON).
|
|
95
|
+
* Para HTML, faça o escape do conteúdo dinâmico antes: o framework não faz isso por você (S-02).
|
|
86
96
|
*/
|
|
87
97
|
send(body, contentType) {
|
|
98
|
+
if (this.sent)
|
|
99
|
+
return this;
|
|
100
|
+
if (contentType)
|
|
101
|
+
this.res.setHeader('Content-Type', contentType);
|
|
102
|
+
return this.dispatch(body, 'auto');
|
|
103
|
+
}
|
|
104
|
+
dispatch(body, mode) {
|
|
105
|
+
if (this.sent)
|
|
106
|
+
return this;
|
|
107
|
+
// Antes do handler (middlewares, guards) não há schema ligado: vale só o tipo do conteúdo.
|
|
108
|
+
sendResult(this, this.bound?.response, body, this.bound?.serializers, mode);
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
/** @internal Liga os schemas de resposta da rota (o app chama antes do handler). */
|
|
112
|
+
[kBindResponse](response, serializers) {
|
|
113
|
+
this.bound = { response, serializers };
|
|
114
|
+
}
|
|
115
|
+
/** @internal Envio cru, sem schema: string, bytes ou stream. */
|
|
116
|
+
[kRawSend](body, contentType) {
|
|
88
117
|
if (this.sent)
|
|
89
118
|
return this;
|
|
90
119
|
if (contentType)
|
|
@@ -109,7 +138,8 @@ export class Context {
|
|
|
109
138
|
redirect(url, status = 302) {
|
|
110
139
|
if (this.sent)
|
|
111
140
|
return this;
|
|
112
|
-
this.status
|
|
141
|
+
this.res.statusCode = status;
|
|
142
|
+
this.statusExplicit = true;
|
|
113
143
|
this.res.setHeader('Location', url);
|
|
114
144
|
this.res.end();
|
|
115
145
|
return this;
|
package/dist/core/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAe,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import '../shims/symbol-metadata.ts';
|
|
2
2
|
export { createApp, SashikoApp, type AppOptions, type ListenOptions, type RequestIdOptions, type ServerTimeouts } from './app.ts';
|
|
3
3
|
export type { InjectOptions, InjectResponse } from './inject.ts';
|
|
4
|
-
export type {
|
|
4
|
+
export type { ManualRouteOptions, MethodSelector, MethodsSelector, MountOptions, RouterRef } from './compiler.ts';
|
|
5
|
+
export { MountedGroup } from './mounted-group.ts';
|
|
5
6
|
export type { Middleware } from './compose.ts';
|
|
6
7
|
export type { Guard } from './guard.ts';
|
|
7
8
|
export type { InferBody, InferHeaders, InferParams, InferQuery, InferResponse, InferSchema } from './infer.ts';
|
|
9
|
+
export type { ShutdownOptions } from './shutdown.ts';
|
|
10
|
+
export type { Serializer } from './response.ts';
|
|
8
11
|
export { consoleLogger, silentLogger, type ConsoleLoggerOptions, type Logger, type LogLevel } from './logger.ts';
|
|
9
|
-
export { Context, type ContextOptions, type ContextState } from './context.ts';
|
|
12
|
+
export { Context, type BodyFor, type ContextOptions, type ContextState, type DeclaredStatus, type StatusContext } from './context.ts';
|
|
10
13
|
export { badRequest, forbidden, HttpError, internal, isHttpError, notFound, unauthorized, type HttpErrorOptions } from './errors.ts';
|
|
11
|
-
export { ROUTER_METADATA, readOwnMetadata, type RouterMetadata, type MethodMetadata, type RouteSchemas } from './metadata.ts';
|
|
14
|
+
export { isResponseContent, ROUTER_METADATA, readOwnMetadata, type ResponseContent, type ResponseEntry, type RouterMetadata, type MethodMetadata, type RouteSchemas } from './metadata.ts';
|
|
12
15
|
export type { Handler } from './route-table.ts';
|
|
13
16
|
export type { ValidationIssue, ValidationTarget } from '../schema/validation.ts';
|
|
14
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAClI,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAClI,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAClH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/G,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,oBAAoB,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACtI,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3L,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/core/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import '../shims/symbol-metadata.js';
|
|
2
2
|
export { createApp, SashikoApp } from './app.js';
|
|
3
|
+
export { MountedGroup } from './mounted-group.js';
|
|
3
4
|
export { consoleLogger, silentLogger } from './logger.js';
|
|
4
5
|
export { Context } from './context.js';
|
|
5
6
|
export { badRequest, forbidden, HttpError, internal, isHttpError, notFound, unauthorized } from './errors.js';
|
|
6
|
-
export { ROUTER_METADATA, readOwnMetadata } from './metadata.js';
|
|
7
|
+
export { isResponseContent, ROUTER_METADATA, readOwnMetadata } from './metadata.js';
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAmF,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAmF,MAAM,UAAU,CAAC;AAGlI,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMlD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAyD,MAAM,aAAa,CAAC;AACjH,OAAO,EAAE,OAAO,EAAiG,MAAM,cAAc,CAAC;AACtI,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAyB,MAAM,aAAa,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAyG,MAAM,eAAe,CAAC"}
|
package/dist/core/infer.d.ts
CHANGED
|
@@ -31,6 +31,14 @@ export type InferHeaders<S extends RouteSchemas> = InferSchema<S['headers'], Rec
|
|
|
31
31
|
* Útil para anotar o retorno do handler: `create(ctx): InferResponse<typeof create, 201>`.
|
|
32
32
|
*/
|
|
33
33
|
export type InferResponse<S extends RouteSchemas, Status extends number = number> = S['response'] extends Record<number, unknown> ? {
|
|
34
|
-
[K in keyof S['response'] & Status]: InferSchema<S['response'][K]
|
|
34
|
+
[K in keyof S['response'] & Status]: InferSchema<UnwrapResponse<S['response'][K]>>;
|
|
35
35
|
}[keyof S['response'] & Status] : unknown;
|
|
36
|
+
/** `{ contentType, schema }` → `schema`; um schema JSON direto continua como está (F-31). */
|
|
37
|
+
type UnwrapResponse<E> = E extends {
|
|
38
|
+
contentType: unknown;
|
|
39
|
+
schema: infer S;
|
|
40
|
+
} ? S : E extends {
|
|
41
|
+
contentType: unknown;
|
|
42
|
+
} ? undefined : E;
|
|
43
|
+
export {};
|
|
36
44
|
//# sourceMappingURL=infer.d.ts.map
|
package/dist/core/infer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infer.d.ts","sourceRoot":"","sources":["../../src/core/infer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,IAC3C;IAAC,WAAW,CAAC,CAAC,CAAC;CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,QAAQ,GACzC,WAAW,CAAC,CAAC,CAAC,SAAS;IAAE,WAAW,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,GAAG,SAAS,CAAA;KAAE,CAAA;CAAE,GAAG,CAAC,GACvF,WAAW,CAAC,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG;IAAE,MAAM,EAAE,EAAE,CAAA;CAAE,CAAC,CAAC,QAAQ,CAAC,GACxF,QAAQ,CAAC;AAEb,gDAAgD;AAChD,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,YAAY,IAAI,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AACnG,+CAA+C;AAC/C,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,YAAY,IAAI,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;AAC5G,8CAA8C;AAC9C,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,YAAY,IAAI,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AAChF,sDAAsD;AACtD,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,YAAY,IAAI,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;AAE5H;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,YAAY,EAAE,MAAM,SAAS,MAAM,GAAG,MAAM,IAC9E,CAAC,CAAC,UAAU,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACzC;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"infer.d.ts","sourceRoot":"","sources":["../../src/core/infer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,IAC3C;IAAC,WAAW,CAAC,CAAC,CAAC;CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,QAAQ,GACzC,WAAW,CAAC,CAAC,CAAC,SAAS;IAAE,WAAW,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,GAAG,SAAS,CAAA;KAAE,CAAA;CAAE,GAAG,CAAC,GACvF,WAAW,CAAC,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG;IAAE,MAAM,EAAE,EAAE,CAAA;CAAE,CAAC,CAAC,QAAQ,CAAC,GACxF,QAAQ,CAAC;AAEb,gDAAgD;AAChD,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,YAAY,IAAI,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AACnG,+CAA+C;AAC/C,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,YAAY,IAAI,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;AAC5G,8CAA8C;AAC9C,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,YAAY,IAAI,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;AAChF,sDAAsD;AACtD,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,YAAY,IAAI,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;AAE5H;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,YAAY,EAAE,MAAM,SAAS,MAAM,GAAG,MAAM,IAC9E,CAAC,CAAC,UAAU,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACzC;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,GACpH,OAAO,CAAC;AAEd,6FAA6F;AAC7F,KAAK,cAAc,CAAC,CAAC,IACnB,CAAC,SAAS;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,CAAC,GACrD,CAAC,SAAS;IAAE,WAAW,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,GAC9C,CAAC,CAAC"}
|
package/dist/core/metadata.d.ts
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
import type { Middleware } from './compose.ts';
|
|
2
2
|
import type { Guard } from './guard.ts';
|
|
3
3
|
export declare const ROUTER_METADATA: unique symbol;
|
|
4
|
+
/**
|
|
5
|
+
* Resposta com tipo de conteúdo declarado (F-31). Sem `contentType`, a entrada é um schema JSON.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* response: { 200: { contentType: ['application/json', 'text/csv'], schema: Users } }
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export interface ResponseContent {
|
|
12
|
+
/** Um tipo ou a lista de tipos oferecidos; com vários, o cliente escolhe pelo `Accept`. */
|
|
13
|
+
contentType: string | readonly string[];
|
|
14
|
+
/** Schema dos dados. Em formatos não JSON, valida e remove campos antes do serializador. */
|
|
15
|
+
schema?: object;
|
|
16
|
+
}
|
|
17
|
+
/** Schema JSON (como sempre) ou `{ contentType, schema? }`. */
|
|
18
|
+
export type ResponseEntry = object | ResponseContent;
|
|
4
19
|
export interface RouteSchemas {
|
|
5
20
|
params?: object;
|
|
6
21
|
body?: object;
|
|
7
22
|
query?: object;
|
|
8
23
|
headers?: object;
|
|
9
|
-
response?: Record<number,
|
|
24
|
+
response?: Record<number, ResponseEntry>;
|
|
10
25
|
}
|
|
26
|
+
export declare function isResponseContent(entry: unknown): entry is ResponseContent;
|
|
11
27
|
export interface MethodMetadata {
|
|
12
28
|
method?: string;
|
|
13
29
|
path?: string;
|
|
14
30
|
schemas: RouteSchemas;
|
|
15
31
|
handlerName?: string | symbol;
|
|
16
|
-
/** `@
|
|
32
|
+
/** `@Middlewares` no método (F-01). */
|
|
17
33
|
middlewares: Middleware[];
|
|
18
|
-
/** `@
|
|
34
|
+
/** `@Guards` no método (F-01). */
|
|
19
35
|
guards: Guard[];
|
|
20
36
|
}
|
|
21
37
|
export interface RouterMetadata {
|
|
@@ -23,9 +39,9 @@ export interface RouterMetadata {
|
|
|
23
39
|
isRouter: boolean;
|
|
24
40
|
prefix: string;
|
|
25
41
|
methods: Map<string | symbol, MethodMetadata>;
|
|
26
|
-
/** `@
|
|
42
|
+
/** `@Middlewares` na classe: valem para todas as rotas da classe (F-01). */
|
|
27
43
|
middlewares: Middleware[];
|
|
28
|
-
/** `@
|
|
44
|
+
/** `@Guards` na classe (F-01). */
|
|
29
45
|
guards: Guard[];
|
|
30
46
|
}
|
|
31
47
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/core/metadata.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,eAAO,MAAM,eAAe,eAA+B,CAAC;AAE5D,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,
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/core/metadata.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,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;CAC1C;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;CACjB;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;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,cAAc,CAoBjF;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"}
|
package/dist/core/metadata.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
export const ROUTER_METADATA = Symbol.for('sashiko:router');
|
|
2
|
+
export function isResponseContent(entry) {
|
|
3
|
+
if (typeof entry !== 'object' || entry === null || !('contentType' in entry))
|
|
4
|
+
return false;
|
|
5
|
+
const ct = entry.contentType;
|
|
6
|
+
return typeof ct === 'string' || Array.isArray(ct);
|
|
7
|
+
}
|
|
2
8
|
/**
|
|
3
9
|
* Retorna a metadata **própria** da classe.
|
|
4
10
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/core/metadata.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/core/metadata.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AA2B5D,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3F,MAAM,EAAE,GAAI,KAAkC,CAAC,WAAW,CAAC;IAC3D,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC;AAwBD;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA6B;IAC/D,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC,eAAe,CAAmB,CAAC;IACjD,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAA+B,CAAC;IACtE,MAAM,GAAG,GAAmB;QAC1B,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,IAAI,GAAG,CACd,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;YACjD,IAAI;YACJ,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE;SAC5F,CAAC,CACH;QACD,uFAAuF;QACvF,WAAW,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;KACvC,CAAC;IACF,IAAI,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC;IAC5B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7D,MAAM,IAAI,GAAI,KAAgE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChG,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC;QAAE,OAAO,SAAS,CAAC;IACrE,OAAO,IAAI,CAAC,eAAe,CAAmB,CAAC;AACjD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB,EAAE,SAAiB;IAC7D,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CACb,cAAc,SAAS,qEAAqE;YAC5F,oGAAoG,CACrG,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAI,OAAyD,CAAC,QAAQ,CAAC;IACjF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,cAAc,SAAS,wEAAwE;YAC/F,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IACD,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAAsB,EAAE,OAAqB,EAAE,KAAa;IACvF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAA2B,EAAE,CAAC;QACjE,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,SAAS;QACzC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CACb,aAAa,KAAK,aAAa,GAAG,2BAA2B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI;gBAC3F,yEAAyE,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,CAAC,OAAO,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAoB,EAAE,IAAqB;IAC3E,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACpE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -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":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM;;IACxC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IAIzB,0CAA0C;IAC1C,YACE,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,kBAAkB,KAAK,IAAI,EAK/H;IAOD,kFAAkF;IAClF,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAiD;IAC9H,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAkD;IAChI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAiD;IAC9H,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAmD;IAClI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAoD;IAGpI,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IACtF,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,GAAG,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAIzI,GAAG,CAAC,EAAE,EAAE,UAAU,GAAG,UAAU,CAA6B;IAC5D,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAgC;IAC5G,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAqC;IACnG,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAoC;IAC1E,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CAAgC;IACzG,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAkC;IAC/F,IAAI,GAAG,IAAI,MAAM,CAAyB;CAC3C"}
|