@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.
- package/dist/adapters/binding.d.ts.map +1 -1
- package/dist/adapters/binding.js +37 -7
- package/dist/adapters/dto-binding-plan.d.ts +3 -0
- package/dist/adapters/dto-binding-plan.d.ts.map +1 -1
- package/dist/adapters/dto-binding-plan.js +34 -2
- package/dist/adapters/dto-validation-adapter.d.ts +1 -1
- package/dist/adapters/dto-validation-adapter.d.ts.map +1 -1
- package/dist/adapters/dto-validation-adapter.js +7 -14
- package/dist/dispatch/dispatch-handler-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-handler-policy.js +5 -3
- package/dist/dispatch/dispatch-response-policy.d.ts +1 -1
- package/dist/dispatch/dispatch-response-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-response-policy.js +3 -4
- package/dist/dispatch/dispatch-routing-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-routing-policy.js +6 -4
- package/dist/dispatch/dispatcher.d.ts +18 -6
- package/dist/dispatch/dispatcher.d.ts.map +1 -1
- package/dist/dispatch/dispatcher.js +317 -52
- package/dist/dispatch/fast-path/debug-visibility.d.ts +18 -0
- package/dist/dispatch/fast-path/debug-visibility.d.ts.map +1 -0
- package/dist/dispatch/fast-path/debug-visibility.js +39 -0
- package/dist/dispatch/fast-path/eligibility-checker.d.ts +22 -0
- package/dist/dispatch/fast-path/eligibility-checker.d.ts.map +1 -0
- package/dist/dispatch/fast-path/eligibility-checker.js +110 -0
- package/dist/dispatch/fast-path/eligibility.d.ts +61 -0
- package/dist/dispatch/fast-path/eligibility.d.ts.map +1 -0
- package/dist/dispatch/fast-path/eligibility.js +23 -0
- package/dist/dispatch/fast-path/fast-path-executor.d.ts +21 -0
- package/dist/dispatch/fast-path/fast-path-executor.d.ts.map +1 -0
- package/dist/dispatch/fast-path/fast-path-executor.js +80 -0
- package/dist/dispatch/fast-path/index.d.ts +6 -0
- package/dist/dispatch/fast-path/index.d.ts.map +1 -0
- package/dist/dispatch/fast-path/index.js +4 -0
- package/dist/dispatch/native-route-handoff.d.ts.map +1 -1
- package/dist/dispatch/native-route-handoff.js +8 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- 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;
|
|
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"}
|
package/dist/adapters/binding.js
CHANGED
|
@@ -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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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(
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
17
|
-
|
|
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
|
|
32
|
-
|
|
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;
|
|
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
|
|
27
|
-
|
|
28
|
-
|
|
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):
|
|
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,
|
|
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
|
|
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
|
-
|
|
83
|
-
return;
|
|
82
|
+
return response.sendSimpleJson(value);
|
|
84
83
|
}
|
|
85
84
|
const responseBody = formatter ? formatter.format(value) : value;
|
|
86
|
-
|
|
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,
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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;
|
|
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"}
|