@fluojs/http 1.0.0-beta.2 → 1.0.0-beta.4
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.ko.md +4 -1
- package/README.md +4 -1
- package/dist/adapter.d.ts +31 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +37 -0
- package/dist/adapters/binding.d.ts +6 -0
- package/dist/adapters/binding.d.ts.map +1 -1
- package/dist/adapters/binding.js +20 -51
- package/dist/adapters/dto-binding-plan.d.ts +19 -0
- package/dist/adapters/dto-binding-plan.d.ts.map +1 -0
- package/dist/adapters/dto-binding-plan.js +54 -0
- package/dist/adapters/dto-validation-adapter.d.ts +3 -0
- package/dist/adapters/dto-validation-adapter.d.ts.map +1 -1
- package/dist/adapters/dto-validation-adapter.js +8 -4
- package/dist/dispatch/dispatch-content-negotiation.d.ts +17 -0
- package/dist/dispatch/dispatch-content-negotiation.d.ts.map +1 -1
- package/dist/dispatch/dispatch-content-negotiation.js +21 -0
- package/dist/dispatch/dispatch-error-policy.d.ts +8 -0
- package/dist/dispatch/dispatch-error-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-error-policy.js +9 -0
- package/dist/dispatch/dispatch-handler-policy.d.ts +11 -1
- package/dist/dispatch/dispatch-handler-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-handler-policy.js +12 -2
- package/dist/dispatch/dispatch-response-policy.d.ts +10 -0
- package/dist/dispatch/dispatch-response-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-response-policy.js +43 -0
- package/dist/dispatch/dispatch-routing-policy.d.ts +13 -0
- package/dist/dispatch/dispatch-routing-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-routing-policy.js +14 -0
- package/dist/dispatch/dispatcher.d.ts +6 -1
- package/dist/dispatch/dispatcher.d.ts.map +1 -1
- package/dist/dispatch/dispatcher.js +171 -28
- package/dist/dispatch/native-route-handoff.d.ts +53 -0
- package/dist/dispatch/native-route-handoff.d.ts.map +1 -0
- package/dist/dispatch/native-route-handoff.js +94 -0
- package/dist/errors.d.ts +3 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -0
- package/dist/guards.d.ts +7 -0
- package/dist/guards.d.ts.map +1 -1
- package/dist/guards.js +11 -0
- package/dist/input-error-detail.d.ts +9 -0
- package/dist/input-error-detail.d.ts.map +1 -1
- package/dist/input-error-detail.js +10 -0
- package/dist/interceptors.d.ts +8 -0
- package/dist/interceptors.d.ts.map +1 -1
- package/dist/interceptors.js +14 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -1
- package/dist/mapping.d.ts +7 -0
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +93 -11
- package/dist/middleware/correlation.d.ts +5 -0
- package/dist/middleware/correlation.d.ts.map +1 -1
- package/dist/middleware/correlation.js +6 -0
- package/dist/middleware/cors.d.ts +9 -0
- package/dist/middleware/cors.d.ts.map +1 -1
- package/dist/middleware/cors.js +11 -0
- package/dist/middleware/middleware.d.ts +34 -0
- package/dist/middleware/middleware.d.ts.map +1 -1
- package/dist/middleware/middleware.js +47 -0
- package/dist/middleware/security-headers.d.ts +9 -0
- package/dist/middleware/security-headers.d.ts.map +1 -1
- package/dist/middleware/security-headers.js +11 -0
- package/dist/route-path.d.ts +41 -0
- package/dist/route-path.d.ts.map +1 -1
- package/dist/route-path.js +50 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -11,6 +11,45 @@ function resolveDefaultSuccessStatus(handler, value) {
|
|
|
11
11
|
return 200;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
function canUseSimpleJsonFastPath(response, value) {
|
|
15
|
+
return isSimpleJsonResponseBody(value) && !isResponseBodyForbidden(response.statusCode) && hasJsonCompatibleContentType(response);
|
|
16
|
+
}
|
|
17
|
+
function hasSimpleJsonResponseWriter(response) {
|
|
18
|
+
return typeof response.sendSimpleJson === 'function';
|
|
19
|
+
}
|
|
20
|
+
function isSimpleJsonResponseBody(value) {
|
|
21
|
+
if (Array.isArray(value)) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return typeof value === 'object' && value !== null && Object.getPrototypeOf(value) === Object.prototype;
|
|
25
|
+
}
|
|
26
|
+
function isResponseBodyForbidden(status) {
|
|
27
|
+
return status === 204 || status === 205 || status === 304;
|
|
28
|
+
}
|
|
29
|
+
function hasJsonCompatibleContentType(response) {
|
|
30
|
+
const contentType = readHeader(response.headers, 'content-type');
|
|
31
|
+
return contentType === undefined || isJsonContentType(contentType);
|
|
32
|
+
}
|
|
33
|
+
function readHeader(headers, name) {
|
|
34
|
+
const lowerName = name.toLowerCase();
|
|
35
|
+
const entry = Object.entries(headers).find(([headerName]) => headerName.toLowerCase() === lowerName);
|
|
36
|
+
const value = entry?.[1];
|
|
37
|
+
return typeof value === 'string' ? value : undefined;
|
|
38
|
+
}
|
|
39
|
+
function isJsonContentType(contentType) {
|
|
40
|
+
return contentType.toLowerCase().includes('application/json') || contentType.toLowerCase().endsWith('+json');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Write success response.
|
|
45
|
+
*
|
|
46
|
+
* @param handler The handler.
|
|
47
|
+
* @param request The request.
|
|
48
|
+
* @param response The response.
|
|
49
|
+
* @param value The value.
|
|
50
|
+
* @param contentNegotiation The content negotiation.
|
|
51
|
+
* @returns The write success response result.
|
|
52
|
+
*/
|
|
14
53
|
export async function writeSuccessResponse(handler, request, response, value, contentNegotiation) {
|
|
15
54
|
if (response.committed) {
|
|
16
55
|
return;
|
|
@@ -39,6 +78,10 @@ export async function writeSuccessResponse(handler, request, response, value, co
|
|
|
39
78
|
} else if (response.statusSet !== true) {
|
|
40
79
|
response.setStatus(resolveDefaultSuccessStatus(handler, value));
|
|
41
80
|
}
|
|
81
|
+
if (!formatter && hasSimpleJsonResponseWriter(response) && canUseSimpleJsonFastPath(response, value)) {
|
|
82
|
+
await response.sendSimpleJson(value);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
42
85
|
const responseBody = formatter ? formatter.format(value) : value;
|
|
43
86
|
await response.send(responseBody);
|
|
44
87
|
}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import type { FrameworkRequest, HandlerMapping, HandlerMatch, RequestContext } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Match handler or throw.
|
|
4
|
+
*
|
|
5
|
+
* @param handlerMapping The handler mapping.
|
|
6
|
+
* @param request The request.
|
|
7
|
+
* @returns The match handler or throw result.
|
|
8
|
+
*/
|
|
2
9
|
export declare function matchHandlerOrThrow(handlerMapping: HandlerMapping, request: FrameworkRequest): HandlerMatch;
|
|
10
|
+
/**
|
|
11
|
+
* Update request params.
|
|
12
|
+
*
|
|
13
|
+
* @param requestContext The request context.
|
|
14
|
+
* @param params The params.
|
|
15
|
+
*/
|
|
3
16
|
export declare function updateRequestParams(requestContext: RequestContext, params: Readonly<Record<string, string>>): void;
|
|
4
17
|
//# sourceMappingURL=dispatch-routing-policy.d.ts.map
|
|
@@ -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,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAQ3G;AAED,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,CAKlH"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { HandlerNotFoundError } from '../errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Match handler or throw.
|
|
4
|
+
*
|
|
5
|
+
* @param handlerMapping The handler mapping.
|
|
6
|
+
* @param request The request.
|
|
7
|
+
* @returns The match handler or throw result.
|
|
8
|
+
*/
|
|
2
9
|
export function matchHandlerOrThrow(handlerMapping, request) {
|
|
3
10
|
const match = handlerMapping.match(request);
|
|
4
11
|
if (!match) {
|
|
@@ -6,6 +13,13 @@ export function matchHandlerOrThrow(handlerMapping, request) {
|
|
|
6
13
|
}
|
|
7
14
|
return match;
|
|
8
15
|
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Update request params.
|
|
19
|
+
*
|
|
20
|
+
* @param requestContext The request context.
|
|
21
|
+
* @param params The params.
|
|
22
|
+
*/
|
|
9
23
|
export function updateRequestParams(requestContext, params) {
|
|
10
24
|
requestContext.request = {
|
|
11
25
|
...requestContext.request,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Container } from '@fluojs/di';
|
|
2
|
-
import type { Binder, ContentNegotiationOptions, Dispatcher, DispatcherLogger, FrameworkRequest, FrameworkResponse, HandlerMapping, InterceptorLike, MiddlewareLike, RequestObserverLike } from '../types.js';
|
|
2
|
+
import type { Binder, ContentNegotiationOptions, ConverterLike, Dispatcher, DispatcherLogger, FrameworkRequest, FrameworkResponse, HandlerMapping, InterceptorLike, MiddlewareLike, RequestObserverLike } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Type definition for a global HTTP error handler function.
|
|
5
5
|
*/
|
|
@@ -22,6 +22,11 @@ export interface CreateDispatcherOptions {
|
|
|
22
22
|
observers?: RequestObserverLike[];
|
|
23
23
|
/** Optional global error handler. */
|
|
24
24
|
onError?: ErrorHandler;
|
|
25
|
+
/** Request-scope optimization hints supplied by runtime bootstrap. */
|
|
26
|
+
requestScope?: {
|
|
27
|
+
/** Global DTO converters used by the default binder. */
|
|
28
|
+
converterDefinitions?: readonly ConverterLike[];
|
|
29
|
+
};
|
|
25
30
|
logger?: DispatcherLogger;
|
|
26
31
|
/** Root DI container for creating request scopes. */
|
|
27
32
|
rootContainer: Container;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,
|
|
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,10 +1,12 @@
|
|
|
1
|
+
import { readFrameworkRequestNativeRouteHandoff } from './native-route-handoff.js';
|
|
1
2
|
import { invokeControllerHandler } from './dispatch-handler-policy.js';
|
|
2
3
|
import { resolveContentNegotiation, writeErrorResponse, writeSuccessResponse } from './dispatch-response-policy.js';
|
|
3
4
|
import { matchHandlerOrThrow, updateRequestParams } from './dispatch-routing-policy.js';
|
|
5
|
+
import { getCompiledDtoBindingPlan } from '../adapters/dto-binding-plan.js';
|
|
4
6
|
import { RequestAbortedError } from '../errors.js';
|
|
5
7
|
import { runGuardChain } from '../guards.js';
|
|
6
8
|
import { runInterceptorChain } from '../interceptors.js';
|
|
7
|
-
import { runMiddlewareChain } from '../middleware/middleware.js';
|
|
9
|
+
import { isMiddlewareRouteConfig, matchRoutePattern, runMiddlewareChain } from '../middleware/middleware.js';
|
|
8
10
|
import { createRequestContext, runWithRequestContext } from '../context/request-context.js';
|
|
9
11
|
import { SseResponse } from '../context/sse.js';
|
|
10
12
|
|
|
@@ -31,20 +33,126 @@ function createDispatchRequest(request) {
|
|
|
31
33
|
}
|
|
32
34
|
};
|
|
33
35
|
}
|
|
36
|
+
function cloneHandlerDescriptor(descriptor) {
|
|
37
|
+
return {
|
|
38
|
+
...descriptor,
|
|
39
|
+
metadata: {
|
|
40
|
+
...descriptor.metadata,
|
|
41
|
+
moduleMiddleware: [...descriptor.metadata.moduleMiddleware],
|
|
42
|
+
pathParams: [...descriptor.metadata.pathParams]
|
|
43
|
+
},
|
|
44
|
+
route: {
|
|
45
|
+
...descriptor.route,
|
|
46
|
+
guards: descriptor.route.guards ? [...descriptor.route.guards] : undefined,
|
|
47
|
+
headers: descriptor.route.headers?.map(header => ({
|
|
48
|
+
...header
|
|
49
|
+
})),
|
|
50
|
+
interceptors: descriptor.route.interceptors ? [...descriptor.route.interceptors] : undefined,
|
|
51
|
+
produces: descriptor.route.produces ? [...descriptor.route.produces] : undefined,
|
|
52
|
+
redirect: descriptor.route.redirect ? {
|
|
53
|
+
...descriptor.route.redirect
|
|
54
|
+
} : undefined
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
34
58
|
function readRequestId(request) {
|
|
35
59
|
const raw = request.headers['x-request-id'] ?? request.headers['X-Request-Id'];
|
|
36
60
|
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
37
61
|
const normalized = value?.trim();
|
|
38
62
|
return normalized ? normalized : undefined;
|
|
39
63
|
}
|
|
40
|
-
function createDispatchContext(request, response,
|
|
41
|
-
|
|
42
|
-
container
|
|
64
|
+
function createDispatchContext(request, response, container, promoteOnContainerAccess) {
|
|
65
|
+
const context = createRequestContext({
|
|
66
|
+
container,
|
|
43
67
|
metadata: {},
|
|
44
68
|
request,
|
|
45
69
|
requestId: readRequestId(request),
|
|
46
70
|
response
|
|
47
71
|
});
|
|
72
|
+
if (!promoteOnContainerAccess) {
|
|
73
|
+
return context;
|
|
74
|
+
}
|
|
75
|
+
let activeContainer = container;
|
|
76
|
+
Object.defineProperty(context, 'container', {
|
|
77
|
+
configurable: true,
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get() {
|
|
80
|
+
activeContainer = promoteOnContainerAccess();
|
|
81
|
+
return activeContainer;
|
|
82
|
+
},
|
|
83
|
+
set(value) {
|
|
84
|
+
activeContainer = value;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
return context;
|
|
88
|
+
}
|
|
89
|
+
function createRootDispatchScope(rootContainer) {
|
|
90
|
+
return {
|
|
91
|
+
container: rootContainer,
|
|
92
|
+
requestScoped: false
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function createRequestDispatchScope(rootContainer) {
|
|
96
|
+
return {
|
|
97
|
+
container: rootContainer.createRequestScope(),
|
|
98
|
+
requestScoped: true
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function activeMiddlewareMayRequireRequestScope(definitions, request) {
|
|
102
|
+
return definitions.some(definition => {
|
|
103
|
+
if (!isMiddlewareRouteConfig(definition)) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return definition.routes.length === 0 || definition.routes.some(route => matchRoutePattern(route, request.path));
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function requestDtoMayRequireRequestScope(handler, options) {
|
|
110
|
+
if (!handler.route.request) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
if ((options.requestScope?.converterDefinitions ?? []).length > 0) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (options.binder) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
const plan = getCompiledDtoBindingPlan(handler.route.request);
|
|
120
|
+
return plan.entries.some(entry => entry.converter !== undefined);
|
|
121
|
+
}
|
|
122
|
+
function handlerMethodMayUseRequestContext(handler) {
|
|
123
|
+
const method = handler.controllerToken.prototype[handler.methodName];
|
|
124
|
+
return typeof method === 'function' && method.length >= 2;
|
|
125
|
+
}
|
|
126
|
+
function hasRequestScopeInspector(container) {
|
|
127
|
+
return typeof container === 'object' && container !== null && 'hasRequestScopedDependency' in container && typeof container.hasRequestScopedDependency === 'function';
|
|
128
|
+
}
|
|
129
|
+
function handlerMayRequireRequestScope(handler, request, options) {
|
|
130
|
+
if (handler.route.guards && handler.route.guards.length > 0) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
if ((options.interceptors ?? []).length > 0 || (handler.route.interceptors ?? []).length > 0) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
if (activeMiddlewareMayRequireRequestScope(handler.metadata.moduleMiddleware, request)) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
if (requestDtoMayRequireRequestScope(handler, options)) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
if (handlerMethodMayUseRequestContext(handler)) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
return hasRequestScopeInspector(options.rootContainer) ? options.rootContainer.hasRequestScopedDependency(handler.controllerToken) : true;
|
|
146
|
+
}
|
|
147
|
+
function dispatchStartMayRequireRequestScope(request, observers, options) {
|
|
148
|
+
return observers.length > 0 || activeMiddlewareMayRequireRequestScope(options.appMiddleware ?? [], request);
|
|
149
|
+
}
|
|
150
|
+
function ensureRequestScope(context) {
|
|
151
|
+
if (context.dispatchScope.requestScoped) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
context.dispatchScope = createRequestDispatchScope(context.options.rootContainer);
|
|
155
|
+
context.requestContext.container = context.dispatchScope.container;
|
|
48
156
|
}
|
|
49
157
|
function ensureRequestNotAborted(request) {
|
|
50
158
|
if (request.signal?.aborted) {
|
|
@@ -71,29 +179,41 @@ async function notifyObservers(observers, requestContext, callback, handler) {
|
|
|
71
179
|
}
|
|
72
180
|
}
|
|
73
181
|
async function notifyObserversSafely(observers, requestContext, callback, logger, handler) {
|
|
182
|
+
if (observers.length === 0) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
74
185
|
try {
|
|
75
186
|
await notifyObservers(observers, requestContext, callback, handler);
|
|
76
187
|
} catch (error) {
|
|
77
188
|
logDispatchFailure(logger, 'Request observer threw an unhandled error.', error);
|
|
78
189
|
}
|
|
79
190
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
191
|
+
function mergeInterceptors(globalInterceptors, routeInterceptors) {
|
|
192
|
+
if (globalInterceptors.length === 0) {
|
|
193
|
+
return routeInterceptors;
|
|
194
|
+
}
|
|
195
|
+
if (routeInterceptors.length === 0) {
|
|
196
|
+
return globalInterceptors;
|
|
197
|
+
}
|
|
198
|
+
return [...globalInterceptors, ...routeInterceptors];
|
|
199
|
+
}
|
|
200
|
+
async function dispatchMatchedHandler(handler, requestContext, controllerContainer, observers, contentNegotiation, binder, globalInterceptors, logger) {
|
|
201
|
+
const routeGuards = handler.route.guards ?? [];
|
|
202
|
+
if (routeGuards.length > 0) {
|
|
203
|
+
const guardContext = {
|
|
204
|
+
handler,
|
|
205
|
+
requestContext
|
|
206
|
+
};
|
|
207
|
+
await runGuardChain(routeGuards, guardContext);
|
|
208
|
+
}
|
|
90
209
|
if (requestContext.response.committed) {
|
|
91
210
|
return;
|
|
92
211
|
}
|
|
93
|
-
const
|
|
94
|
-
const result = await
|
|
95
|
-
|
|
96
|
-
|
|
212
|
+
const routeInterceptors = handler.route.interceptors ?? [];
|
|
213
|
+
const result = globalInterceptors.length === 0 && routeInterceptors.length === 0 ? await invokeControllerHandler(handler, requestContext, binder, controllerContainer) : await runInterceptorChain(mergeInterceptors(globalInterceptors, routeInterceptors), {
|
|
214
|
+
handler,
|
|
215
|
+
requestContext
|
|
216
|
+
}, async () => invokeControllerHandler(handler, requestContext, binder, controllerContainer));
|
|
97
217
|
ensureRequestNotAborted(requestContext.request);
|
|
98
218
|
if (!(result instanceof SseResponse) && !requestContext.response.committed) {
|
|
99
219
|
await writeSuccessResponse(handler, requestContext.request, requestContext.response, result, contentNegotiation);
|
|
@@ -133,8 +253,11 @@ async function runDispatchPipeline(context) {
|
|
|
133
253
|
if (context.response.committed) {
|
|
134
254
|
return;
|
|
135
255
|
}
|
|
136
|
-
const match = matchHandlerOrThrow(context.options.handlerMapping, appMiddlewareContext.request);
|
|
256
|
+
const match = readFrameworkRequestNativeRouteHandoff(appMiddlewareContext.request) ?? matchHandlerOrThrow(context.options.handlerMapping, appMiddlewareContext.request);
|
|
137
257
|
context.matchedHandler = match.descriptor;
|
|
258
|
+
if (handlerMayRequireRequestScope(match.descriptor, appMiddlewareContext.request, context.options)) {
|
|
259
|
+
ensureRequestScope(context);
|
|
260
|
+
}
|
|
138
261
|
updateRequestParams(context.requestContext, match.params);
|
|
139
262
|
await notifyHandlerMatched(context, match.descriptor);
|
|
140
263
|
const moduleMiddlewareContext = {
|
|
@@ -143,7 +266,7 @@ async function runDispatchPipeline(context) {
|
|
|
143
266
|
response: context.response
|
|
144
267
|
};
|
|
145
268
|
await runMiddlewareChain(match.descriptor.metadata.moduleMiddleware ?? [], moduleMiddlewareContext, async () => {
|
|
146
|
-
await dispatchMatchedHandler(match.descriptor, context.requestContext, context.observers, context.contentNegotiation, context.options.binder, context.options.interceptors, context.options.logger);
|
|
269
|
+
await dispatchMatchedHandler(match.descriptor, context.requestContext, context.dispatchScope.container, context.observers, context.contentNegotiation, context.options.binder, context.options.interceptors ?? [], context.options.logger);
|
|
147
270
|
});
|
|
148
271
|
});
|
|
149
272
|
}
|
|
@@ -167,13 +290,29 @@ async function handleDispatchError(context, error) {
|
|
|
167
290
|
*/
|
|
168
291
|
export function createDispatcher(options) {
|
|
169
292
|
const contentNegotiation = resolveContentNegotiation(options.contentNegotiation);
|
|
170
|
-
|
|
293
|
+
const observers = options.observers ?? [];
|
|
294
|
+
const dispatcher = {
|
|
295
|
+
describeRoutes() {
|
|
296
|
+
return options.handlerMapping.descriptors.map(descriptor => cloneHandlerDescriptor(descriptor));
|
|
297
|
+
},
|
|
171
298
|
async dispatch(request, response) {
|
|
172
|
-
const
|
|
299
|
+
const dispatchRequest = createDispatchRequest(request);
|
|
300
|
+
const dispatchScope = dispatchStartMayRequireRequestScope(dispatchRequest, observers, options) ? createRequestDispatchScope(options.rootContainer) : createRootDispatchScope(options.rootContainer);
|
|
301
|
+
let phaseContext;
|
|
302
|
+
let containerPromotionOpen = true;
|
|
303
|
+
const requestContext = createDispatchContext(dispatchRequest, response, dispatchScope.container, () => {
|
|
304
|
+
if (!containerPromotionOpen) {
|
|
305
|
+
return phaseContext.dispatchScope.container;
|
|
306
|
+
}
|
|
307
|
+
ensureRequestScope(phaseContext);
|
|
308
|
+
return phaseContext.dispatchScope.container;
|
|
309
|
+
});
|
|
310
|
+
phaseContext = {
|
|
173
311
|
contentNegotiation,
|
|
174
|
-
|
|
312
|
+
dispatchScope,
|
|
313
|
+
observers,
|
|
175
314
|
options,
|
|
176
|
-
requestContext
|
|
315
|
+
requestContext,
|
|
177
316
|
response
|
|
178
317
|
};
|
|
179
318
|
await runWithRequestContext(phaseContext.requestContext, async () => {
|
|
@@ -184,13 +323,17 @@ export function createDispatcher(options) {
|
|
|
184
323
|
await handleDispatchError(phaseContext, error);
|
|
185
324
|
} finally {
|
|
186
325
|
await notifyRequestFinish(phaseContext);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
326
|
+
containerPromotionOpen = false;
|
|
327
|
+
if (phaseContext.dispatchScope.requestScoped) {
|
|
328
|
+
try {
|
|
329
|
+
await phaseContext.dispatchScope.container.dispose();
|
|
330
|
+
} catch (error) {
|
|
331
|
+
logDispatchFailure(options.logger, 'Request-scoped container dispose threw an error.', error);
|
|
332
|
+
}
|
|
191
333
|
}
|
|
192
334
|
}
|
|
193
335
|
});
|
|
194
336
|
}
|
|
195
337
|
};
|
|
338
|
+
return dispatcher;
|
|
196
339
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { FrameworkRequest, HandlerMatch } from '../types.js';
|
|
2
|
+
/** Internal handoff payload that lets adapters skip duplicate route matching safely. */
|
|
3
|
+
export type NativeRouteHandoff = HandlerMatch;
|
|
4
|
+
/**
|
|
5
|
+
* Associates one adapter-selected route handoff with a raw platform request.
|
|
6
|
+
*
|
|
7
|
+
* Platform adapters call this before translating the native request into a
|
|
8
|
+
* `FrameworkRequest`, allowing the shared dispatcher to reuse the semantically
|
|
9
|
+
* safe native match without changing the public dispatcher surface.
|
|
10
|
+
*
|
|
11
|
+
* @param rawRequest Raw platform request object used as the lookup key.
|
|
12
|
+
* @param handoff Pre-matched descriptor and params selected by the adapter.
|
|
13
|
+
*/
|
|
14
|
+
export declare function bindRawRequestNativeRouteHandoff(rawRequest: object, handoff: NativeRouteHandoff): void;
|
|
15
|
+
/**
|
|
16
|
+
* Reads and clears a native route handoff previously bound to a raw request.
|
|
17
|
+
*
|
|
18
|
+
* Request factories consume this once while constructing `FrameworkRequest`
|
|
19
|
+
* instances so the handoff remains request-local and does not leak across
|
|
20
|
+
* platform object reuse.
|
|
21
|
+
*
|
|
22
|
+
* @param rawRequest Raw platform request object used as the lookup key.
|
|
23
|
+
* @returns The cloned handoff when one was registered for this request.
|
|
24
|
+
*/
|
|
25
|
+
export declare function consumeRawRequestNativeRouteHandoff(rawRequest: unknown): NativeRouteHandoff | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Stores a pre-matched native route handoff on one framework request.
|
|
28
|
+
*
|
|
29
|
+
* @param request Framework request that should carry the adapter-native match.
|
|
30
|
+
* @param handoff Pre-matched descriptor and params selected by the adapter.
|
|
31
|
+
* @returns The same request instance for fluent adapter construction.
|
|
32
|
+
*/
|
|
33
|
+
export declare function attachFrameworkRequestNativeRouteHandoff(request: FrameworkRequest, handoff: NativeRouteHandoff): FrameworkRequest;
|
|
34
|
+
/**
|
|
35
|
+
* Reads a pre-matched native route handoff from one framework request.
|
|
36
|
+
*
|
|
37
|
+
* @param request Framework request being dispatched.
|
|
38
|
+
* @returns The cloned handoff when the adapter supplied one.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readFrameworkRequestNativeRouteHandoff(request: FrameworkRequest): NativeRouteHandoff | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Reports whether a request path depends on fluo's normalization semantics.
|
|
43
|
+
*
|
|
44
|
+
* Duplicate slashes and trailing slashes are intentionally normalized by the
|
|
45
|
+
* shared matcher. Adapters use this helper to keep those requests on the
|
|
46
|
+
* generic dispatcher path when native routing may not preserve identical path
|
|
47
|
+
* selection semantics.
|
|
48
|
+
*
|
|
49
|
+
* @param path Raw framework request path.
|
|
50
|
+
* @returns `true` when normalization would change the incoming path.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isRoutePathNormalizationSensitive(path: string): boolean;
|
|
53
|
+
//# sourceMappingURL=native-route-handoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-route-handoff.d.ts","sourceRoot":"","sources":["../../src/dispatch/native-route-handoff.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAsBlE,wFAAwF;AACxF,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAEtG;AAED;;;;;;;;;GASG;AACH,wBAAgB,mCAAmC,CAAC,UAAU,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CAavG;AAED;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,kBAAkB,GAC1B,gBAAgB,CAYlB;AAED;;;;;GAKG;AACH,wBAAgB,sCAAsC,CACpD,OAAO,EAAE,gBAAgB,GACxB,kBAAkB,GAAG,SAAS,CAWhC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { normalizeRoutePath } from '../route-path.js';
|
|
2
|
+
const FRAMEWORK_REQUEST_NATIVE_ROUTE_HANDOFF = Symbol('fluo.http.nativeRouteHandoff');
|
|
3
|
+
const RAW_REQUEST_NATIVE_ROUTE_HANDOFFS = new WeakMap();
|
|
4
|
+
function cloneNativeRouteHandoff(handoff) {
|
|
5
|
+
return {
|
|
6
|
+
descriptor: handoff.descriptor,
|
|
7
|
+
params: {
|
|
8
|
+
...handoff.params
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Internal handoff payload that lets adapters skip duplicate route matching safely. */
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Associates one adapter-selected route handoff with a raw platform request.
|
|
17
|
+
*
|
|
18
|
+
* Platform adapters call this before translating the native request into a
|
|
19
|
+
* `FrameworkRequest`, allowing the shared dispatcher to reuse the semantically
|
|
20
|
+
* safe native match without changing the public dispatcher surface.
|
|
21
|
+
*
|
|
22
|
+
* @param rawRequest Raw platform request object used as the lookup key.
|
|
23
|
+
* @param handoff Pre-matched descriptor and params selected by the adapter.
|
|
24
|
+
*/
|
|
25
|
+
export function bindRawRequestNativeRouteHandoff(rawRequest, handoff) {
|
|
26
|
+
RAW_REQUEST_NATIVE_ROUTE_HANDOFFS.set(rawRequest, cloneNativeRouteHandoff(handoff));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Reads and clears a native route handoff previously bound to a raw request.
|
|
31
|
+
*
|
|
32
|
+
* Request factories consume this once while constructing `FrameworkRequest`
|
|
33
|
+
* instances so the handoff remains request-local and does not leak across
|
|
34
|
+
* platform object reuse.
|
|
35
|
+
*
|
|
36
|
+
* @param rawRequest Raw platform request object used as the lookup key.
|
|
37
|
+
* @returns The cloned handoff when one was registered for this request.
|
|
38
|
+
*/
|
|
39
|
+
export function consumeRawRequestNativeRouteHandoff(rawRequest) {
|
|
40
|
+
if (typeof rawRequest !== 'object' || rawRequest === null) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
const handoff = RAW_REQUEST_NATIVE_ROUTE_HANDOFFS.get(rawRequest);
|
|
44
|
+
if (!handoff) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
RAW_REQUEST_NATIVE_ROUTE_HANDOFFS.delete(rawRequest);
|
|
48
|
+
return cloneNativeRouteHandoff(handoff);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Stores a pre-matched native route handoff on one framework request.
|
|
53
|
+
*
|
|
54
|
+
* @param request Framework request that should carry the adapter-native match.
|
|
55
|
+
* @param handoff Pre-matched descriptor and params selected by the adapter.
|
|
56
|
+
* @returns The same request instance for fluent adapter construction.
|
|
57
|
+
*/
|
|
58
|
+
export function attachFrameworkRequestNativeRouteHandoff(request, handoff) {
|
|
59
|
+
Reflect.set(request, FRAMEWORK_REQUEST_NATIVE_ROUTE_HANDOFF, {
|
|
60
|
+
handoff: cloneNativeRouteHandoff(handoff),
|
|
61
|
+
method: request.method,
|
|
62
|
+
path: request.path
|
|
63
|
+
});
|
|
64
|
+
return request;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Reads a pre-matched native route handoff from one framework request.
|
|
69
|
+
*
|
|
70
|
+
* @param request Framework request being dispatched.
|
|
71
|
+
* @returns The cloned handoff when the adapter supplied one.
|
|
72
|
+
*/
|
|
73
|
+
export function readFrameworkRequestNativeRouteHandoff(request) {
|
|
74
|
+
const record = Reflect.get(request, FRAMEWORK_REQUEST_NATIVE_ROUTE_HANDOFF);
|
|
75
|
+
if (!record || record.method !== request.method || record.path !== request.path) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
return cloneNativeRouteHandoff(record.handoff);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Reports whether a request path depends on fluo's normalization semantics.
|
|
83
|
+
*
|
|
84
|
+
* Duplicate slashes and trailing slashes are intentionally normalized by the
|
|
85
|
+
* shared matcher. Adapters use this helper to keep those requests on the
|
|
86
|
+
* generic dispatcher path when native routing may not preserve identical path
|
|
87
|
+
* selection semantics.
|
|
88
|
+
*
|
|
89
|
+
* @param path Raw framework request path.
|
|
90
|
+
* @returns `true` when normalization would change the incoming path.
|
|
91
|
+
*/
|
|
92
|
+
export function isRoutePathNormalizationSensitive(path) {
|
|
93
|
+
return normalizeRoutePath(path) !== path;
|
|
94
|
+
}
|
package/dist/errors.d.ts
CHANGED
|
@@ -5,6 +5,9 @@ import { FluoError } from '@fluojs/core';
|
|
|
5
5
|
export declare class RouteConflictError extends FluoError {
|
|
6
6
|
constructor(message: string);
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Represents the invalid route path error.
|
|
10
|
+
*/
|
|
8
11
|
export declare class InvalidRoutePathError extends FluoError {
|
|
9
12
|
constructor(message: string);
|
|
10
13
|
}
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;gBACnC,OAAO,EAAE,MAAM;CAG5B;AAED,qBAAa,qBAAsB,SAAQ,SAAS;gBACtC,OAAO,EAAE,MAAM;CAG5B;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;gBACrC,OAAO,EAAE,MAAM;CAG5B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,SAA4C;CAGhE"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;gBACnC,OAAO,EAAE,MAAM;CAG5B;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;gBACtC,OAAO,EAAE,MAAM;CAG5B;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;gBACrC,OAAO,EAAE,MAAM;CAG5B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,SAA4C;CAGhE"}
|
package/dist/errors.js
CHANGED
package/dist/guards.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import type { GuardContext, GuardLike } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Run guard chain.
|
|
4
|
+
*
|
|
5
|
+
* @param definitions The definitions.
|
|
6
|
+
* @param context The context.
|
|
7
|
+
* @returns The run guard chain result.
|
|
8
|
+
*/
|
|
2
9
|
export declare function runGuardChain(definitions: GuardLike[], context: GuardContext): Promise<void>;
|
|
3
10
|
//# sourceMappingURL=guards.d.ts.map
|
package/dist/guards.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAS,YAAY,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AAcjF,wBAAsB,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAS,YAAY,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AAcjF;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAalG"}
|
package/dist/guards.js
CHANGED
|
@@ -8,7 +8,18 @@ async function resolveGuard(definition, requestContext) {
|
|
|
8
8
|
}
|
|
9
9
|
return requestContext.container.resolve(definition);
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Run guard chain.
|
|
14
|
+
*
|
|
15
|
+
* @param definitions The definitions.
|
|
16
|
+
* @param context The context.
|
|
17
|
+
* @returns The run guard chain result.
|
|
18
|
+
*/
|
|
11
19
|
export async function runGuardChain(definitions, context) {
|
|
20
|
+
if (definitions.length === 0) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
12
23
|
for (const definition of definitions) {
|
|
13
24
|
const guard = await resolveGuard(definition, context.requestContext);
|
|
14
25
|
const result = await guard.canActivate(context);
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import type { MetadataSource } from '@fluojs/core';
|
|
2
2
|
import type { HttpExceptionDetail } from './exceptions.js';
|
|
3
|
+
/**
|
|
4
|
+
* Describes the input error detail contract.
|
|
5
|
+
*/
|
|
3
6
|
export interface InputErrorDetail {
|
|
4
7
|
code: string;
|
|
5
8
|
field?: string;
|
|
6
9
|
message: string;
|
|
7
10
|
source?: MetadataSource;
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* To input error detail.
|
|
14
|
+
*
|
|
15
|
+
* @param detail The detail.
|
|
16
|
+
* @returns The to input error detail result.
|
|
17
|
+
*/
|
|
9
18
|
export declare function toInputErrorDetail(detail: InputErrorDetail): HttpExceptionDetail;
|
|
10
19
|
//# sourceMappingURL=input-error-detail.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-error-detail.d.ts","sourceRoot":"","sources":["../src/input-error-detail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,mBAAmB,CAOhF"}
|
|
1
|
+
{"version":3,"file":"input-error-detail.d.ts","sourceRoot":"","sources":["../src/input-error-detail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,mBAAmB,CAOhF"}
|