@carno.js/core 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/Carno.d.ts +10 -8
  2. package/dist/Carno.js +31 -33
  3. package/dist/commons/decorators/index.d.ts +1 -0
  4. package/dist/commons/decorators/index.js +1 -0
  5. package/dist/commons/decorators/validation.decorator.d.ts +32 -0
  6. package/dist/commons/decorators/validation.decorator.js +40 -0
  7. package/dist/constants.d.ts +1 -0
  8. package/dist/constants.js +2 -1
  9. package/dist/container/InjectorService.d.ts +3 -1
  10. package/dist/container/InjectorService.js +4 -3
  11. package/dist/container/MethodInvoker.d.ts +3 -2
  12. package/dist/container/MethodInvoker.js +4 -17
  13. package/dist/container/middleware.resolver.js +6 -6
  14. package/dist/domain/BaseContext.d.ts +15 -0
  15. package/dist/domain/Context.d.ts +45 -24
  16. package/dist/domain/Context.js +110 -89
  17. package/dist/domain/FastContext.d.ts +34 -0
  18. package/dist/domain/FastContext.js +59 -0
  19. package/dist/domain/cors-headers-cache.d.ts +2 -0
  20. package/dist/domain/cors-headers-cache.js +44 -0
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.js +1 -0
  23. package/dist/route/FastPathExecutor.d.ts +10 -2
  24. package/dist/route/FastPathExecutor.js +43 -12
  25. package/dist/route/JITCompiler.d.ts +25 -1
  26. package/dist/route/JITCompiler.js +205 -98
  27. package/dist/route/ParamResolverFactory.d.ts +0 -5
  28. package/dist/route/ParamResolverFactory.js +0 -40
  29. package/dist/route/RouteCompiler.d.ts +3 -4
  30. package/dist/route/RouteCompiler.js +2 -54
  31. package/dist/route/RouteExecutor.js +18 -1
  32. package/dist/route/memoirist.d.ts +3 -0
  33. package/dist/route/memoirist.js +33 -3
  34. package/dist/utils/ValidationCache.d.ts +2 -0
  35. package/dist/utils/ValidationCache.js +10 -2
  36. package/dist/utils/index.d.ts +0 -1
  37. package/dist/utils/index.js +0 -1
  38. package/dist/validation/ValidatorAdapter.d.ts +66 -0
  39. package/dist/validation/ValidatorAdapter.js +20 -0
  40. package/dist/validation/adapters/ClassValidatorAdapter.d.ts +23 -0
  41. package/dist/validation/adapters/ClassValidatorAdapter.js +47 -0
  42. package/dist/validation/adapters/ZodAdapter.d.ts +14 -0
  43. package/dist/validation/adapters/ZodAdapter.js +56 -0
  44. package/dist/validation/adapters/index.d.ts +4 -0
  45. package/dist/validation/adapters/index.js +7 -0
  46. package/dist/validation/index.d.ts +3 -0
  47. package/dist/validation/index.js +20 -0
  48. package/package.json +17 -6
  49. package/dist/Cheetah.d.ts +0 -65
  50. package/dist/Cheetah.js +0 -307
  51. package/dist/default-routes-cheetah.d.ts +0 -3
  52. package/dist/default-routes-cheetah.js +0 -29
  53. package/dist/domain/CheetahClosure.d.ts +0 -1
  54. package/dist/domain/CheetahMiddleware.d.ts +0 -5
  55. package/dist/domain/CheetahMiddleware.js +0 -2
  56. package/dist/services/request-logger.service.d.ts +0 -15
  57. package/dist/services/request-logger.service.js +0 -50
  58. package/dist/utils/isClassValidator.d.ts +0 -6
  59. package/dist/utils/isClassValidator.js +0 -13
  60. /package/dist/domain/{CheetahClosure.js → BaseContext.js} +0 -0
@@ -15,144 +15,165 @@ const http_code_enum_1 = require("../commons/http-code.enum");
15
15
  const Injectable_decorator_1 = require("../commons/decorators/Injectable.decorator");
16
16
  const HttpException_1 = require("../exceptions/HttpException");
17
17
  const provider_scope_1 = require("./provider-scope");
18
+ /**
19
+ * Context otimizado com shape mínimo e lazy loading.
20
+ *
21
+ * Shape fixo mínimo (sempre alocado):
22
+ * - req: Request
23
+ * - param: Record<string, string>
24
+ * - status: number
25
+ *
26
+ * Lazy loading (só aloca quando usado):
27
+ * - query: Record<string, string> (getter lazy)
28
+ * - headers: Headers (getter que retorna req.headers)
29
+ * - body: Record<string, any> (getter lazy)
30
+ * - locals: Record<string, any> (getter lazy)
31
+ * - rawBody: ArrayBuffer (lazy)
32
+ *
33
+ * V8/JSC otimiza shape consistente. Propriedades lazy não quebram
34
+ * monomorfismo porque são getters, não props dinâmicas.
35
+ */
18
36
  let Context = Context_1 = class Context {
19
37
  constructor() {
20
- this.query = {};
21
- this._body = {};
22
- this.param = {};
23
- this.headers = new Headers();
24
- this.locals = {};
25
- this._pendingRequest = null;
38
+ this._query = null;
39
+ this._locals = null;
40
+ this._body = null;
41
+ this._rawBody = null;
26
42
  this._bodyParsed = false;
43
+ this.req = undefined;
44
+ this.param = {};
45
+ this.status = 200;
46
+ }
47
+ get headers() {
48
+ return this.req.headers;
49
+ }
50
+ get query() {
51
+ if (this._query === null) {
52
+ this._query = this.parseQueryString();
53
+ }
54
+ return this._query;
55
+ }
56
+ set query(value) {
57
+ this._query = value;
58
+ }
59
+ get locals() {
60
+ if (this._locals === null) {
61
+ this._locals = {};
62
+ }
63
+ return this._locals;
64
+ }
65
+ set locals(value) {
66
+ this._locals = value;
27
67
  }
28
68
  get body() {
69
+ if (this._body === null) {
70
+ return {};
71
+ }
29
72
  return this._body;
30
73
  }
31
74
  set body(value) {
32
75
  this._body = value;
33
76
  this._bodyParsed = true;
34
77
  }
78
+ get rawBody() {
79
+ return this._rawBody ?? undefined;
80
+ }
81
+ set rawBody(value) {
82
+ this._rawBody = value ?? null;
83
+ }
35
84
  async getBody() {
36
- if (!this._bodyParsed && this._pendingRequest) {
37
- await this.resolveBody(this._pendingRequest);
38
- this._pendingRequest = null;
39
- this._bodyParsed = true;
85
+ if (!this._bodyParsed) {
86
+ await this.parseBody();
40
87
  }
41
- return this._body;
88
+ return this._body ?? {};
42
89
  }
43
90
  isBodyParsed() {
44
91
  return this._bodyParsed;
45
92
  }
46
- static async createFromRequest(url, request, server) {
47
- const context = Context_1.createFromRequestSync(url, request, server);
48
- if (context._pendingRequest) {
49
- await context.getBody();
50
- }
51
- return context;
93
+ setResponseStatus(status) {
94
+ this.status = status;
95
+ }
96
+ getResponseStatus() {
97
+ return this.status;
98
+ }
99
+ setParam(param) {
100
+ this.param = param;
52
101
  }
53
102
  static createFromRequestSync(url, request, server) {
54
- const context = new Context_1();
55
- context.setQuery(url);
56
- context.setReq(request);
57
- // @ts-ignore
58
- context.setHeaders(request.headers);
59
- if (request.method !== 'GET' && request.method !== 'HEAD') {
60
- context._pendingRequest = request;
103
+ const ctx = new Context_1();
104
+ ctx.req = request;
105
+ ctx.param = {};
106
+ ctx._queryString = url.query;
107
+ const method = request.method;
108
+ if (method !== 'GET' && method !== 'HEAD') {
109
+ ctx._bodyParsed = false;
61
110
  }
62
111
  else {
63
- context._bodyParsed = true;
112
+ ctx._bodyParsed = true;
64
113
  }
65
- return context;
114
+ return ctx;
66
115
  }
67
- static async createFromRequestWithBody(url, request, server) {
68
- const context = Context_1.createFromRequestSync(url, request, server);
69
- if (context._pendingRequest) {
70
- await context.getBody();
116
+ static async createFromRequest(url, request, server) {
117
+ const ctx = Context_1.createFromRequestSync(url, request, server);
118
+ if (!ctx._bodyParsed) {
119
+ await ctx.getBody();
71
120
  }
72
- return context;
121
+ return ctx;
73
122
  }
74
123
  static createFromJob(job) {
75
- const context = new Context_1();
76
- return context;
77
- }
78
- // @ts-ignore
79
- setQuery({ query }) {
80
- this.query = this.buildQueryObject(query);
124
+ return new Context_1();
81
125
  }
82
- setBody(body) {
83
- for (const [key, value] of body.entries()) {
84
- this._body[key] = value;
126
+ parseQueryString() {
127
+ if (!this._queryString) {
128
+ return {};
85
129
  }
130
+ return Object.fromEntries(new URLSearchParams(this._queryString));
86
131
  }
87
- setReq(req) {
88
- this.req = req;
89
- }
90
- setHeaders(headers) {
91
- this.headers = headers;
92
- }
93
- setParam(param) {
94
- this.param = param;
95
- }
96
- setResponseStatus(status) {
97
- this.resultStatus = status;
98
- }
99
- getResponseStatus() {
100
- return this.resultStatus;
101
- }
102
- buildQueryObject(query) {
103
- return query ? Object.fromEntries(new URLSearchParams(query)) : {};
104
- }
105
- async resolveBody(request) {
106
- const contentType = request.headers.get('content-type') || '';
107
- // Clone request once - preserve original request untouched
108
- const clonedRequest = request.clone();
109
- // FormData multipart requires consuming as formData
110
- if (contentType.includes('multipart/form-data')) {
111
- // Need separate clone for rawBody since formData() consumes the body
112
- this.rawBody = await request.clone().arrayBuffer();
113
- this.setBody(await clonedRequest.formData());
132
+ async parseBody() {
133
+ this._bodyParsed = true;
134
+ const contentType = this.req.headers.get('content-type') ?? '';
135
+ if (contentType.includes('application/json')) {
136
+ this._body = await this.parseJsonBody();
114
137
  return;
115
138
  }
116
- // For all other content types, consume body once as ArrayBuffer from clone
117
- this.rawBody = await clonedRequest.arrayBuffer();
118
- if (contentType.includes('application/json')) {
119
- this._body = this.parseJsonFromBuffer(this.rawBody);
139
+ if (contentType.includes('multipart/form-data')) {
140
+ this._body = await this.parseFormDataBody();
120
141
  return;
121
142
  }
122
143
  if (contentType.includes('application/x-www-form-urlencoded')) {
123
- this._body = this.parseUrlEncodedFromBuffer(this.rawBody);
144
+ this._body = await this.parseUrlEncodedBody();
124
145
  return;
125
146
  }
126
- // Plain text or unknown content type
127
- this._body = { body: this.decodeBuffer(this.rawBody) };
147
+ this._body = {};
128
148
  }
129
- parseJsonFromBuffer(buffer) {
130
- if (this.isEmptyBuffer(buffer)) {
149
+ async parseJsonBody() {
150
+ const contentLength = this.req.headers.get('content-length');
151
+ if (contentLength === '0') {
131
152
  return {};
132
153
  }
133
- return this.parseJsonText(this.decodeBuffer(buffer));
134
- }
135
- parseJsonText(text) {
136
154
  try {
137
- return JSON.parse(text);
155
+ const payload = await this.req.json();
156
+ return payload;
138
157
  }
139
158
  catch {
140
- throw new HttpException_1.HttpException("Invalid JSON body", http_code_enum_1.HttpCode.BAD_REQUEST);
159
+ throw new HttpException_1.HttpException('Invalid JSON body', http_code_enum_1.HttpCode.BAD_REQUEST);
141
160
  }
142
161
  }
143
- isEmptyBuffer(buffer) {
144
- return buffer.byteLength === 0;
162
+ async parseFormDataBody() {
163
+ const formData = await this.req.formData();
164
+ const result = {};
165
+ for (const [key, value] of formData.entries()) {
166
+ result[key] = value;
167
+ }
168
+ return result;
145
169
  }
146
- parseUrlEncodedFromBuffer(buffer) {
147
- if (buffer.byteLength === 0) {
170
+ async parseUrlEncodedBody() {
171
+ const text = await this.req.text();
172
+ if (!text) {
148
173
  return {};
149
174
  }
150
- const text = this.decodeBuffer(buffer);
151
175
  return Object.fromEntries(new URLSearchParams(text));
152
176
  }
153
- decodeBuffer(buffer) {
154
- return new TextDecoder().decode(buffer);
155
- }
156
177
  };
157
178
  exports.Context = Context;
158
179
  exports.Context = Context = Context_1 = __decorate([
@@ -0,0 +1,34 @@
1
+ import type { BaseContext } from './BaseContext';
2
+ /**
3
+ * FastContext - Contexto mínimo monomórfico para fast path.
4
+ *
5
+ * Shape fixo otimizado para V8/JSC JIT:
6
+ * - Apenas 3 propriedades diretas: req, param, status
7
+ * - Lazy getters para headers e query (zero alocação se não usados)
8
+ * - Sem locals, sem body, sem flags extras
9
+ * - Monomórfico: sempre mesmo shape, JIT otimiza agressivamente
10
+ *
11
+ * Usado quando:
12
+ * - Rota SIMPLE (RouteType.SIMPLE)
13
+ * - Sem middlewares
14
+ * - Sem DI
15
+ * - Sem body parsing
16
+ */
17
+ export declare class FastContext implements BaseContext {
18
+ readonly req: Request;
19
+ param: Record<string, string>;
20
+ status: number;
21
+ private _query;
22
+ private _queryString;
23
+ constructor(req: Request, param: Record<string, string>, queryString: string | undefined);
24
+ get headers(): Headers;
25
+ get query(): Record<string, string>;
26
+ setResponseStatus(status: number): void;
27
+ getResponseStatus(): number;
28
+ private parseQueryString;
29
+ }
30
+ /**
31
+ * Factory otimizado para criar FastContext.
32
+ * Extrai queryString inline sem overhead de parseUrl.
33
+ */
34
+ export declare function createFastContext(req: Request, param: Record<string, string>, url: string): FastContext;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FastContext = void 0;
4
+ exports.createFastContext = createFastContext;
5
+ /**
6
+ * FastContext - Contexto mínimo monomórfico para fast path.
7
+ *
8
+ * Shape fixo otimizado para V8/JSC JIT:
9
+ * - Apenas 3 propriedades diretas: req, param, status
10
+ * - Lazy getters para headers e query (zero alocação se não usados)
11
+ * - Sem locals, sem body, sem flags extras
12
+ * - Monomórfico: sempre mesmo shape, JIT otimiza agressivamente
13
+ *
14
+ * Usado quando:
15
+ * - Rota SIMPLE (RouteType.SIMPLE)
16
+ * - Sem middlewares
17
+ * - Sem DI
18
+ * - Sem body parsing
19
+ */
20
+ class FastContext {
21
+ constructor(req, param, queryString) {
22
+ this.req = req;
23
+ this.param = param;
24
+ this.status = 200;
25
+ this._query = null;
26
+ this._queryString = queryString;
27
+ }
28
+ get headers() {
29
+ return this.req.headers;
30
+ }
31
+ get query() {
32
+ if (this._query === null) {
33
+ this._query = this.parseQueryString();
34
+ }
35
+ return this._query;
36
+ }
37
+ setResponseStatus(status) {
38
+ this.status = status;
39
+ }
40
+ getResponseStatus() {
41
+ return this.status;
42
+ }
43
+ parseQueryString() {
44
+ if (!this._queryString) {
45
+ return {};
46
+ }
47
+ return Object.fromEntries(new URLSearchParams(this._queryString));
48
+ }
49
+ }
50
+ exports.FastContext = FastContext;
51
+ /**
52
+ * Factory otimizado para criar FastContext.
53
+ * Extrai queryString inline sem overhead de parseUrl.
54
+ */
55
+ function createFastContext(req, param, url) {
56
+ const queryIdx = url.indexOf('?');
57
+ const queryString = queryIdx !== -1 ? url.slice(queryIdx + 1) : undefined;
58
+ return new FastContext(req, param, queryString);
59
+ }
@@ -8,8 +8,10 @@ export declare class CorsHeadersCache {
8
8
  private readonly maxAgeString;
9
9
  private readonly hasCredentials;
10
10
  private readonly isWildcard;
11
+ private readonly originAllowed;
11
12
  constructor(config: CorsConfig);
12
13
  get(origin: string): Record<string, string>;
13
14
  private buildHeaders;
14
15
  applyToResponse(response: Response, origin: string): Response;
16
+ isOriginAllowed(origin: string): boolean;
15
17
  }
@@ -2,6 +2,46 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CorsHeadersCache = void 0;
4
4
  const cors_config_1 = require("./cors-config");
5
+ const allowAnyOrigin = () => {
6
+ return true;
7
+ };
8
+ const denyAnyOrigin = () => {
9
+ return false;
10
+ };
11
+ function buildOriginAllowed(origins) {
12
+ if (origins === '*') {
13
+ return allowAnyOrigin;
14
+ }
15
+ if (typeof origins === 'string') {
16
+ return createExactOriginMatcher(origins);
17
+ }
18
+ if (Array.isArray(origins)) {
19
+ return createSetOriginMatcher(origins);
20
+ }
21
+ if (origins instanceof RegExp) {
22
+ return createRegexOriginMatcher(origins);
23
+ }
24
+ if (typeof origins === 'function') {
25
+ return origins;
26
+ }
27
+ return denyAnyOrigin;
28
+ }
29
+ function createExactOriginMatcher(origin) {
30
+ return (value) => {
31
+ return value === origin;
32
+ };
33
+ }
34
+ function createSetOriginMatcher(origins) {
35
+ const originSet = new Set(origins);
36
+ return (value) => {
37
+ return originSet.has(value);
38
+ };
39
+ }
40
+ function createRegexOriginMatcher(origins) {
41
+ return (value) => {
42
+ return origins.test(value);
43
+ };
44
+ }
5
45
  class CorsHeadersCache {
6
46
  constructor(config) {
7
47
  this.config = config;
@@ -18,6 +58,7 @@ class CorsHeadersCache {
18
58
  : null;
19
59
  this.hasCredentials = !!config.credentials;
20
60
  this.isWildcard = config.origins === '*';
61
+ this.originAllowed = buildOriginAllowed(config.origins);
21
62
  }
22
63
  get(origin) {
23
64
  const cacheKey = this.isWildcard ? '*' : origin;
@@ -53,5 +94,8 @@ class CorsHeadersCache {
53
94
  }
54
95
  return response;
55
96
  }
97
+ isOriginAllowed(origin) {
98
+ return this.originAllowed(origin);
99
+ }
56
100
  }
57
101
  exports.CorsHeadersCache = CorsHeadersCache;
package/dist/index.d.ts CHANGED
@@ -13,3 +13,4 @@ export * from "./services/logger.service";
13
13
  export * from "./cache/cache.service";
14
14
  export * from "./cache/bento-cache.driver";
15
15
  export * from "./testing";
16
+ export * from "./validation";
package/dist/index.js CHANGED
@@ -29,3 +29,4 @@ __exportStar(require("./services/logger.service"), exports);
29
29
  __exportStar(require("./cache/cache.service"), exports);
30
30
  __exportStar(require("./cache/bento-cache.driver"), exports);
31
31
  __exportStar(require("./testing"), exports);
32
+ __exportStar(require("./validation"), exports);
@@ -1,4 +1,12 @@
1
1
  import type { Context } from '../domain/Context';
2
2
  import type { CompiledRoute } from './CompiledRoute';
3
- export declare function executeSimpleRoute(compiled: CompiledRoute, context: Context): Promise<any>;
4
- export declare function executeSimpleRouteSync(compiled: CompiledRoute, context: Context): any;
3
+ /**
4
+ * Fast path executor completo - executa handler e monta response inline.
5
+ * Máximo 2 type checks no fast path.
6
+ */
7
+ export declare function executeFastPath(compiled: CompiledRoute, context: Context): Promise<Response>;
8
+ /**
9
+ * Fast path executor síncrono - para handlers que não retornam Promise.
10
+ * Elimina overhead de async/await quando handler é síncrono.
11
+ */
12
+ export declare function executeFastPathSync(compiled: CompiledRoute, context: Context): Response;
@@ -1,19 +1,50 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.executeSimpleRoute = executeSimpleRoute;
4
- exports.executeSimpleRouteSync = executeSimpleRouteSync;
5
- async function executeSimpleRoute(compiled, context) {
6
- if (!compiled.boundHandler) {
7
- throw new Error('Simple route must have a bound handler');
3
+ exports.executeFastPath = executeFastPath;
4
+ exports.executeFastPathSync = executeFastPathSync;
5
+ /**
6
+ * Frozen header objects - V8 otimiza acesso a objetos frozen.
7
+ * Criados uma vez no startup, reutilizados em todas requests.
8
+ */
9
+ const JSON_HEADERS = Object.freeze({
10
+ 'Content-Type': 'application/json'
11
+ });
12
+ const TEXT_HEADERS = Object.freeze({
13
+ 'Content-Type': 'text/html'
14
+ });
15
+ /**
16
+ * Fast path executor completo - executa handler e monta response inline.
17
+ * Máximo 2 type checks no fast path.
18
+ */
19
+ async function executeFastPath(compiled, context) {
20
+ const result = await compiled.boundHandler(context);
21
+ const status = context.getResponseStatus() || 200;
22
+ if (typeof result === 'string') {
23
+ return new Response(result, { status, headers: TEXT_HEADERS });
8
24
  }
9
- if (compiled.isAsync) {
10
- return compiled.boundHandler(context);
25
+ if (result instanceof Response) {
26
+ return result;
11
27
  }
12
- return compiled.boundHandler(context);
28
+ if (result === null || result === undefined) {
29
+ return new Response('', { status, headers: TEXT_HEADERS });
30
+ }
31
+ return new Response(JSON.stringify(result), { status, headers: JSON_HEADERS });
13
32
  }
14
- function executeSimpleRouteSync(compiled, context) {
15
- if (!compiled.boundHandler) {
16
- throw new Error('Simple route must have a bound handler');
33
+ /**
34
+ * Fast path executor síncrono - para handlers que não retornam Promise.
35
+ * Elimina overhead de async/await quando handler é síncrono.
36
+ */
37
+ function executeFastPathSync(compiled, context) {
38
+ const result = compiled.boundHandler(context);
39
+ const status = context.getResponseStatus() || 200;
40
+ if (typeof result === 'string') {
41
+ return new Response(result, { status, headers: TEXT_HEADERS });
42
+ }
43
+ if (result instanceof Response) {
44
+ return result;
45
+ }
46
+ if (result === null || result === undefined) {
47
+ return new Response('', { status, headers: TEXT_HEADERS });
17
48
  }
18
- return compiled.boundHandler(context);
49
+ return new Response(JSON.stringify(result), { status, headers: JSON_HEADERS });
19
50
  }
@@ -1,4 +1,28 @@
1
1
  import type { ParamInfo } from './ParamResolverFactory';
2
2
  import type { CompiledHandler, AsyncCompiledHandler } from './CompiledRoute';
3
+ /**
4
+ * Compila route handler em função otimizada.
5
+ *
6
+ * Estratégias de otimização:
7
+ * - Inline de acesso a parâmetros
8
+ * - Bind do handler no compile time
9
+ * - Código gerado monomórfico
10
+ * - Sem overhead de resolvers array
11
+ */
12
+ /**
13
+ * Compila route handler em função otimizada que retorna Response inline.
14
+ *
15
+ * Estratégias de otimização:
16
+ * - Inline de acesso a parâmetros
17
+ * - Inline de response building (elimina executeFastPath)
18
+ * - Bind do handler no compile time
19
+ * - Código gerado monomórfico
20
+ * - Headers pré-frozen para otimização V8
21
+ */
3
22
  export declare function compileRouteHandler(instance: any, methodName: string, paramInfos: ParamInfo[]): CompiledHandler | AsyncCompiledHandler;
4
- export declare function compileValidatedHandler(instance: any, methodName: string, paramInfos: ParamInfo[], validators: ((value: any) => any)[]): CompiledHandler | AsyncCompiledHandler;
23
+ /**
24
+ * Compila handler com validação inline.
25
+ */
26
+ export declare function compileValidatedHandler(instance: any, methodName: string, paramInfos: ParamInfo[], validatorAdapter: {
27
+ validateAndTransform: (token: any, value: any) => any;
28
+ }): CompiledHandler | AsyncCompiledHandler;