@fluojs/http 1.0.0-beta.4 → 1.0.0-beta.6

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 (41) hide show
  1. package/dist/adapters/binding.d.ts.map +1 -1
  2. package/dist/adapters/binding.js +37 -7
  3. package/dist/adapters/dto-binding-plan.d.ts +3 -0
  4. package/dist/adapters/dto-binding-plan.d.ts.map +1 -1
  5. package/dist/adapters/dto-binding-plan.js +34 -2
  6. package/dist/adapters/dto-validation-adapter.d.ts +1 -1
  7. package/dist/adapters/dto-validation-adapter.d.ts.map +1 -1
  8. package/dist/adapters/dto-validation-adapter.js +7 -14
  9. package/dist/dispatch/dispatch-handler-policy.d.ts.map +1 -1
  10. package/dist/dispatch/dispatch-handler-policy.js +5 -3
  11. package/dist/dispatch/dispatch-response-policy.d.ts +1 -1
  12. package/dist/dispatch/dispatch-response-policy.d.ts.map +1 -1
  13. package/dist/dispatch/dispatch-response-policy.js +3 -4
  14. package/dist/dispatch/dispatch-routing-policy.d.ts.map +1 -1
  15. package/dist/dispatch/dispatch-routing-policy.js +6 -4
  16. package/dist/dispatch/dispatcher.d.ts +18 -6
  17. package/dist/dispatch/dispatcher.d.ts.map +1 -1
  18. package/dist/dispatch/dispatcher.js +317 -52
  19. package/dist/dispatch/fast-path/debug-visibility.d.ts +18 -0
  20. package/dist/dispatch/fast-path/debug-visibility.d.ts.map +1 -0
  21. package/dist/dispatch/fast-path/debug-visibility.js +39 -0
  22. package/dist/dispatch/fast-path/eligibility-checker.d.ts +22 -0
  23. package/dist/dispatch/fast-path/eligibility-checker.d.ts.map +1 -0
  24. package/dist/dispatch/fast-path/eligibility-checker.js +110 -0
  25. package/dist/dispatch/fast-path/eligibility.d.ts +61 -0
  26. package/dist/dispatch/fast-path/eligibility.d.ts.map +1 -0
  27. package/dist/dispatch/fast-path/eligibility.js +23 -0
  28. package/dist/dispatch/fast-path/fast-path-executor.d.ts +21 -0
  29. package/dist/dispatch/fast-path/fast-path-executor.d.ts.map +1 -0
  30. package/dist/dispatch/fast-path/fast-path-executor.js +80 -0
  31. package/dist/dispatch/fast-path/index.d.ts +6 -0
  32. package/dist/dispatch/fast-path/index.d.ts.map +1 -0
  33. package/dist/dispatch/fast-path/index.js +4 -0
  34. package/dist/dispatch/native-route-handoff.d.ts.map +1 -1
  35. package/dist/dispatch/native-route-handoff.js +8 -5
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +1 -0
  39. package/dist/types.d.ts +12 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../src/adapters/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,WAAW,EAAc,MAAM,cAAc,CAAC;AAI5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAoB,MAAM,aAAa,CAAC;AAiDhI;;GAEG;AACH,qBAAa,gBAAiB,YAAW,SAAS;IAChD,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO;CAG3D;AAyDD;;GAEG;AACH,qBAAa,aAAc,YAAW,MAAM;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,GAAE,SAAS,aAAa,EAAO;IAEhE,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;CA+DjF"}
1
+ {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../src/adapters/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,WAAW,EAAc,MAAM,cAAc,CAAC;AAI5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAoB,MAAM,aAAa,CAAC;AAkDhI;;GAEG;AACH,qBAAa,gBAAiB,YAAW,SAAS;IAChD,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO;CAG3D;AAyDD;;GAEG;AACH,qBAAa,aAAc,YAAW,MAAM;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,GAAE,SAAS,aAAa,EAAO;IAEhE,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;CAuGjF"}
@@ -3,6 +3,7 @@ import { BadRequestException } from '../exceptions.js';
3
3
  import { toInputErrorDetail } from '../input-error-detail.js';
4
4
  import { getCompiledDtoBindingPlan } from './dto-binding-plan.js';
5
5
  const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
6
+ const NO_CONVERTERS = [];
6
7
  function isPlainObject(value) {
7
8
  if (typeof value !== 'object' || value === null) {
8
9
  return false;
@@ -107,13 +108,40 @@ export class DefaultBinder {
107
108
  }
108
109
  async bind(dto, context) {
109
110
  const plan = getCompiledDtoBindingPlan(dto);
111
+ const request = context.requestContext.request;
110
112
  const value = new dto();
111
- const converterCache = new Map();
112
- const globalConverters = (await Promise.all(this.converters.map(converter => resolveConverter(converter, context, converterCache)))).filter(converter => Boolean(converter));
113
- validateBodyKeys(context.requestContext.request, plan.bodyKeys);
113
+ if (request.body !== undefined && request.body !== null) {
114
+ validateBodyKeys(request, plan.bodyKeys);
115
+ }
114
116
  const details = [];
117
+ if (this.converters.length === 0 && !plan.hasFieldConverters) {
118
+ for (const entry of plan.entries) {
119
+ const rawValue = entry.read(request);
120
+ if (rawValue === undefined) {
121
+ if (entry.optional) {
122
+ continue;
123
+ }
124
+ details.push(toInputErrorDetail({
125
+ code: 'MISSING_FIELD',
126
+ field: entry.fieldName,
127
+ message: `Missing required ${entry.source} field ${entry.sourceKey}.`,
128
+ source: entry.source
129
+ }));
130
+ continue;
131
+ }
132
+ value[entry.propertyKey] = rawValue;
133
+ }
134
+ if (details.length > 0) {
135
+ throw new BadRequestException('Request binding failed.', {
136
+ details
137
+ });
138
+ }
139
+ return value;
140
+ }
141
+ const converterCache = new Map();
142
+ const globalConverters = this.converters.length === 0 ? NO_CONVERTERS : (await Promise.all(this.converters.map(converter => resolveConverter(converter, context, converterCache)))).filter(converter => Boolean(converter));
115
143
  for (const entry of plan.entries) {
116
- const rawValue = entry.read(context.requestContext.request);
144
+ const rawValue = entry.read(request);
117
145
  if (rawValue === undefined) {
118
146
  if (entry.optional) {
119
147
  continue;
@@ -138,9 +166,11 @@ export class DefaultBinder {
138
166
  for (const converter of globalConverters) {
139
167
  convertedValue = await converter.convert(convertedValue, target);
140
168
  }
141
- const fieldConverter = await resolveConverter(entry.converter, context, converterCache);
142
- if (fieldConverter) {
143
- convertedValue = await fieldConverter.convert(convertedValue, target);
169
+ if (entry.converter !== undefined) {
170
+ const fieldConverter = await resolveConverter(entry.converter, context, converterCache);
171
+ if (fieldConverter) {
172
+ convertedValue = await fieldConverter.convert(convertedValue, target);
173
+ }
144
174
  }
145
175
  value[entry.propertyKey] = convertedValue;
146
176
  }
@@ -13,7 +13,10 @@ export interface CompiledDtoBindingPlanEntry {
13
13
  export interface CompiledDtoBindingPlan {
14
14
  readonly bodyKeys: ReadonlySet<string>;
15
15
  readonly entries: readonly CompiledDtoBindingPlanEntry[];
16
+ readonly hasFieldConverters: boolean;
17
+ readonly needsValidation: boolean;
16
18
  readonly propertyKeys: readonly MetadataPropertyKey[];
19
+ readonly toValidationValue: (value: unknown) => unknown;
17
20
  }
18
21
  export declare function getCompiledDtoBindingPlan(dto: Constructor): CompiledDtoBindingPlan;
19
22
  //# sourceMappingURL=dto-binding-plan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dto-binding-plan.d.ts","sourceRoot":"","sources":["../../src/adapters/dto-binding-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/F,OAAO,EAAmD,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEtH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAcpD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,uBAAuB,CAAC,WAAW,CAAC,CAAC;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC;IACtD,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,2BAA2B,EAAE,CAAC;IACzD,QAAQ,CAAC,YAAY,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACvD;AAqBD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,WAAW,GAAG,sBAAsB,CA4BlF"}
1
+ {"version":3,"file":"dto-binding-plan.d.ts","sourceRoot":"","sources":["../../src/adapters/dto-binding-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/F,OAAO,EAKL,KAAK,uBAAuB,EAE7B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAcpD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,uBAAuB,CAAC,WAAW,CAAC,CAAC;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC;IACtD,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,2BAA2B,EAAE,CAAC;IACzD,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtD,QAAQ,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;CACzD;AAkDD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,WAAW,GAAG,sBAAsB,CA4ClF"}
@@ -1,4 +1,4 @@
1
- import { getDtoBindingSchema } from '@fluojs/core/internal';
1
+ import { getClassValidationRules, getDtoBindingSchema, getDtoValidationSchema } from '@fluojs/core/internal';
2
2
  function toFieldName(propertyKey) {
3
3
  return typeof propertyKey === 'string' ? propertyKey : String(propertyKey);
4
4
  }
@@ -25,6 +25,27 @@ function createSourceReader(source, sourceKey) {
25
25
  return () => undefined;
26
26
  }
27
27
  }
28
+ function identityValidationValue(value) {
29
+ return value;
30
+ }
31
+ function createValidationValueFilter(propertyKeys) {
32
+ return value => {
33
+ if (typeof value !== 'object' || value === null) {
34
+ return value;
35
+ }
36
+ const source = value;
37
+ const filtered = Object.create(Object.getPrototypeOf(value));
38
+ for (const propertyKey of propertyKeys) {
39
+ if (Object.hasOwn(source, propertyKey)) {
40
+ filtered[propertyKey] = source[propertyKey];
41
+ }
42
+ }
43
+ return filtered;
44
+ };
45
+ }
46
+ function isDtoAwareValidationRule(rule) {
47
+ return rule.kind === 'custom' || rule.kind === 'validateIf';
48
+ }
28
49
  export function getCompiledDtoBindingPlan(dto) {
29
50
  const cached = dtoBindingPlanCache.get(dto);
30
51
  if (cached) {
@@ -44,10 +65,21 @@ export function getCompiledDtoBindingPlan(dto) {
44
65
  sourceKey
45
66
  };
46
67
  });
68
+ const propertyKeys = entries.map(entry => entry.propertyKey);
69
+ const boundPropertyKeys = new Set(propertyKeys);
70
+ const validationSchema = getDtoValidationSchema(dto);
71
+ const validationPropertyKeys = validationSchema.map(entry => entry.propertyKey);
72
+ const hasClassValidationRules = getClassValidationRules(dto).length > 0;
73
+ const hasDtoAwareValidationRules = validationSchema.some(entry => entry.rules.some(rule => isDtoAwareValidationRule(rule)));
74
+ const needsValidation = hasClassValidationRules || validationPropertyKeys.length > 0;
75
+ const requiresValidationFilter = hasClassValidationRules || hasDtoAwareValidationRules || validationPropertyKeys.some(propertyKey => !boundPropertyKeys.has(propertyKey));
47
76
  const next = {
48
77
  bodyKeys: new Set(entries.filter(entry => entry.source === 'body').map(entry => entry.sourceKey)),
49
78
  entries,
50
- propertyKeys: entries.map(entry => entry.propertyKey)
79
+ hasFieldConverters: entries.some(entry => entry.converter !== undefined),
80
+ needsValidation,
81
+ propertyKeys,
82
+ toValidationValue: requiresValidationFilter ? createValidationValueFilter(propertyKeys) : identityValidationValue
51
83
  };
52
84
  dtoBindingPlanCache.set(dto, next);
53
85
  return next;
@@ -6,7 +6,7 @@ import type { Validator } from '../types.js';
6
6
  export declare class HttpDtoValidationAdapter implements Validator {
7
7
  private readonly validator;
8
8
  private throwBadRequestForValidationError;
9
- private filterUnboundRequestDtoFields;
9
+ private getValidationValue;
10
10
  validate(value: unknown, target: Constructor): Promise<void>;
11
11
  materialize<T>(value: unknown, target: Constructor<T>): Promise<T>;
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dto-validation-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/dto-validation-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD,OAAO,KAAK,EAAmB,SAAS,EAAE,MAAM,aAAa,CAAC;AAG9D;;GAEG;AACH,qBAAa,wBAAyB,YAAW,SAAS;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IAExD,OAAO,CAAC,iCAAiC;IAMzC,OAAO,CAAC,6BAA6B;IAiB/B,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5D,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAWzE"}
1
+ {"version":3,"file":"dto-validation-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/dto-validation-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD,OAAO,KAAK,EAAmB,SAAS,EAAE,MAAM,aAAa,CAAC;AAG9D;;GAEG;AACH,qBAAa,wBAAyB,YAAW,SAAS;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IAExD,OAAO,CAAC,iCAAiC;IAMzC,OAAO,CAAC,kBAAkB;IAIpB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5D,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAWzE"}
@@ -13,23 +13,16 @@ export class HttpDtoValidationAdapter {
13
13
  details: error.issues.map(issue => toInputErrorDetail(issue))
14
14
  });
15
15
  }
16
- filterUnboundRequestDtoFields(value, target) {
17
- if (typeof value !== 'object' || value === null) {
18
- return value;
19
- }
20
- const source = value;
21
- const filtered = Object.create(Object.getPrototypeOf(value));
22
- for (const propertyKey of getCompiledDtoBindingPlan(target).propertyKeys) {
23
- if (Object.hasOwn(source, propertyKey)) {
24
- filtered[propertyKey] = source[propertyKey];
25
- }
26
- }
27
- return filtered;
16
+ getValidationValue(value, target) {
17
+ return getCompiledDtoBindingPlan(target).toValidationValue(value);
28
18
  }
29
19
  async validate(value, target) {
30
20
  try {
31
- const filteredValue = this.filterUnboundRequestDtoFields(value, target);
32
- await this.validator.validate(filteredValue, target);
21
+ const plan = getCompiledDtoBindingPlan(target);
22
+ if (!plan.needsValidation) {
23
+ return;
24
+ }
25
+ await this.validator.validate(this.getValidationValue(value, target), target);
33
26
  } catch (error) {
34
27
  if (error instanceof DtoValidationError) {
35
28
  this.throwBadRequestForValidationError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch-handler-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-handler-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAIxD,OAAO,KAAK,EAA2B,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKtG;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,cAAc,EAAE,cAAc,EAC9B,MAAM,GAAE,MAAsB,EAC9B,mBAAmB,GAAE,qBAAgD,GACpE,OAAO,CAAC,OAAO,CAAC,CAuBlB"}
1
+ {"version":3,"file":"dispatch-handler-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-handler-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAKxD,OAAO,KAAK,EAA2B,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKtG;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,cAAc,EAAE,cAAc,EAC9B,MAAM,GAAE,MAAsB,EAC9B,mBAAmB,GAAE,qBAAgD,GACpE,OAAO,CAAC,OAAO,CAAC,CAwBlB"}
@@ -1,5 +1,6 @@
1
1
  import { InvariantError } from '@fluojs/core';
2
2
  import { DefaultBinder } from '../adapters/binding.js';
3
+ import { getCompiledDtoBindingPlan } from '../adapters/dto-binding-plan.js';
3
4
  import { HttpDtoValidationAdapter } from '../adapters/dto-validation-adapter.js';
4
5
  const defaultBinder = new DefaultBinder();
5
6
  const defaultValidator = new HttpDtoValidationAdapter();
@@ -23,9 +24,10 @@ export async function invokeControllerHandler(handler, requestContext, binder =
23
24
  handler,
24
25
  requestContext
25
26
  };
26
- const input = handler.route.request ? await binder.bind(handler.route.request, argumentResolverContext) : undefined;
27
- if (handler.route.request) {
28
- await defaultValidator.validate(input, handler.route.request);
27
+ const requestDto = handler.route.request;
28
+ const input = requestDto ? await binder.bind(requestDto, argumentResolverContext) : undefined;
29
+ if (requestDto && getCompiledDtoBindingPlan(requestDto).needsValidation) {
30
+ await defaultValidator.validate(input, requestDto);
29
31
  }
30
32
  return method.call(controller, input, requestContext);
31
33
  }
@@ -11,7 +11,7 @@ import type { FrameworkRequest, FrameworkResponse, HandlerDescriptor } from '../
11
11
  * @param contentNegotiation The content negotiation.
12
12
  * @returns The write success response result.
13
13
  */
14
- export declare function writeSuccessResponse(handler: HandlerDescriptor, request: FrameworkRequest, response: FrameworkResponse, value: unknown, contentNegotiation: ResolvedContentNegotiation | undefined): Promise<void>;
14
+ export declare function writeSuccessResponse(handler: HandlerDescriptor, request: FrameworkRequest, response: FrameworkResponse, value: unknown, contentNegotiation: ResolvedContentNegotiation | undefined): ReturnType<FrameworkResponse['send']> | void;
15
15
  export { resolveContentNegotiation, writeErrorResponse };
16
16
  export type { ResolvedContentNegotiation };
17
17
  //# sourceMappingURL=dispatch-response-policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch-response-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-response-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EAEzB,KAAK,0BAA0B,EAChC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAgErB;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,OAAO,EACd,kBAAkB,EAAE,0BAA0B,GAAG,SAAS,GACzD,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,CAAC;AACzD,YAAY,EAAE,0BAA0B,EAAE,CAAC"}
1
+ {"version":3,"file":"dispatch-response-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-response-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EAEzB,KAAK,0BAA0B,EAChC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAgErB;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,OAAO,EACd,kBAAkB,EAAE,0BAA0B,GAAG,SAAS,GACzD,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAwC9C;AAED,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,CAAC;AACzD,YAAY,EAAE,0BAA0B,EAAE,CAAC"}
@@ -50,7 +50,7 @@ function isJsonContentType(contentType) {
50
50
  * @param contentNegotiation The content negotiation.
51
51
  * @returns The write success response result.
52
52
  */
53
- export async function writeSuccessResponse(handler, request, response, value, contentNegotiation) {
53
+ export function writeSuccessResponse(handler, request, response, value, contentNegotiation) {
54
54
  if (response.committed) {
55
55
  return;
56
56
  }
@@ -79,10 +79,9 @@ export async function writeSuccessResponse(handler, request, response, value, co
79
79
  response.setStatus(resolveDefaultSuccessStatus(handler, value));
80
80
  }
81
81
  if (!formatter && hasSimpleJsonResponseWriter(response) && canUseSimpleJsonFastPath(response, value)) {
82
- await response.sendSimpleJson(value);
83
- return;
82
+ return response.sendSimpleJson(value);
84
83
  }
85
84
  const responseBody = formatter ? formatter.format(value) : value;
86
- await response.send(responseBody);
85
+ return response.send(responseBody);
87
86
  }
88
87
  export { resolveContentNegotiation, writeErrorResponse };
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch-routing-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-routing-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElG;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAQ3G;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAKlH"}
1
+ {"version":3,"file":"dispatch-routing-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-routing-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElG;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAQ3G;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAOlH"}
@@ -21,8 +21,10 @@ export function matchHandlerOrThrow(handlerMapping, request) {
21
21
  * @param params The params.
22
22
  */
23
23
  export function updateRequestParams(requestContext, params) {
24
- requestContext.request = {
25
- ...requestContext.request,
26
- params
27
- };
24
+ Object.defineProperty(requestContext.request, 'params', {
25
+ configurable: true,
26
+ enumerable: true,
27
+ value: params,
28
+ writable: true
29
+ });
28
30
  }
@@ -1,12 +1,11 @@
1
1
  import type { Container } from '@fluojs/di';
2
2
  import type { Binder, ContentNegotiationOptions, ConverterLike, Dispatcher, DispatcherLogger, FrameworkRequest, FrameworkResponse, HandlerMapping, InterceptorLike, MiddlewareLike, RequestObserverLike } from '../types.js';
3
- /**
4
- * Type definition for a global HTTP error handler function.
5
- */
3
+ import { type FastPathStats } from './fast-path/index.js';
4
+ export type { FastPathEligibility, FastPathStats } from './fast-path/index.js';
5
+ export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL } from './fast-path/index.js';
6
+ /** Type definition for a global HTTP error handler function. */
6
7
  export type ErrorHandler = (error: unknown, request: FrameworkRequest, response: FrameworkResponse, requestId?: string) => Promise<boolean | void> | boolean | void;
7
- /**
8
- * Options for creating an HTTP {@link Dispatcher}.
9
- */
8
+ /** Options for creating an HTTP {@link Dispatcher}. */
10
9
  export interface CreateDispatcherOptions {
11
10
  /** Global middleware applied to all requests. */
12
11
  appMiddleware?: MiddlewareLike[];
@@ -20,6 +19,8 @@ export interface CreateDispatcherOptions {
20
19
  interceptors?: InterceptorLike[];
21
20
  /** Global request observers for telemetry and logging. */
22
21
  observers?: RequestObserverLike[];
22
+ /** Emits per-response fast-path debug headers when enabled. */
23
+ fastPathDebugHeaders?: boolean;
23
24
  /** Optional global error handler. */
24
25
  onError?: ErrorHandler;
25
26
  /** Request-scope optimization hints supplied by runtime bootstrap. */
@@ -27,9 +28,12 @@ export interface CreateDispatcherOptions {
27
28
  /** Global DTO converters used by the default binder. */
28
29
  converterDefinitions?: readonly ConverterLike[];
29
30
  };
31
+ /** Logger used for non-fatal dispatcher failures. */
30
32
  logger?: DispatcherLogger;
31
33
  /** Root DI container for creating request scopes. */
32
34
  rootContainer: Container;
35
+ /** Human-readable adapter label included in fast-path observability output. */
36
+ adapter?: string;
33
37
  }
34
38
  /**
35
39
  * Creates an HTTP dispatcher instance for processing requests.
@@ -38,4 +42,12 @@ export interface CreateDispatcherOptions {
38
42
  * @returns A {@link Dispatcher} capable of routing {@link FrameworkRequest}s.
39
43
  */
40
44
  export declare function createDispatcher(options: CreateDispatcherOptions): Dispatcher;
45
+ /**
46
+ * Reads automatic fast-path eligibility statistics attached to a dispatcher.
47
+ *
48
+ * @param dispatcher Dispatcher returned by {@link createDispatcher}.
49
+ * @returns Fast-path statistics when available.
50
+ */
51
+ export declare function getDispatcherFastPathStats(dispatcher: Dispatcher): FastPathStats | undefined;
52
+ export { formatFastPathStats } from './fast-path/index.js';
41
53
  //# sourceMappingURL=dispatcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAyB,MAAM,YAAY,CAAC;AAanE,OAAO,KAAK,EACV,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EAGjB,cAAc,EACd,eAAe,EAEf,cAAc,EAId,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;AAEpK;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,aAAa,CAAC,EAAE,cAAc,EAAE,CAAC;IACjC,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IAC/C,sDAAsD;IACtD,cAAc,EAAE,cAAc,CAAC;IAC/B,2DAA2D;IAC3D,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,0DAA0D;IAC1D,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,qCAAqC;IACrC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,sEAAsE;IACtE,YAAY,CAAC,EAAE;QACb,wDAAwD;QACxD,oBAAoB,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;KACjD,CAAC;IACF,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,qDAAqD;IACrD,aAAa,EAAE,SAAS,CAAC;CAC1B;AA8bD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,UAAU,CAuD7E"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAyB,MAAM,YAAY,CAAC;AAQnE,OAAO,KAAK,EACV,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EAIjB,cAAc,EAEd,eAAe,EAEf,cAAc,EAId,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAKL,KAAK,aAAa,EAOnB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE5F,gEAAgE;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;AAEpK,uDAAuD;AACvD,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,aAAa,CAAC,EAAE,cAAc,EAAE,CAAC;IACjC,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IAC/C,sDAAsD;IACtD,cAAc,EAAE,cAAc,CAAC;IAC/B,2DAA2D;IAC3D,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,0DAA0D;IAC1D,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,+DAA+D;IAC/D,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qCAAqC;IACrC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,sEAAsE;IACtE,YAAY,CAAC,EAAE;QACb,wDAAwD;QACxD,oBAAoB,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;KACjD,CAAC;IACF,qDAAqD;IACrD,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,qDAAqD;IACrD,aAAa,EAAE,SAAS,CAAC;IACzB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA2xBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,UAAU,CAuF7E;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,GAAG,SAAS,CAE5F;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}