@fluojs/http 1.0.0-beta.2 → 1.0.0-beta.3
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/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 +8 -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 +3 -0
- 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 +8 -0
- package/dist/dispatch/dispatch-handler-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-handler-policy.js +9 -0
- 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 +11 -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.map +1 -1
- package/dist/dispatch/dispatcher.js +55 -16
- 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/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 +3 -3
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes the input error detail contract.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* To input error detail.
|
|
7
|
+
*
|
|
8
|
+
* @param detail The detail.
|
|
9
|
+
* @returns The to input error detail result.
|
|
10
|
+
*/
|
|
1
11
|
export function toInputErrorDetail(detail) {
|
|
2
12
|
return {
|
|
3
13
|
code: detail.code,
|
package/dist/interceptors.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
import type { InterceptorContext, InterceptorLike } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Run interceptor chain.
|
|
4
|
+
*
|
|
5
|
+
* @param definitions The definitions.
|
|
6
|
+
* @param context The context.
|
|
7
|
+
* @param terminal The terminal.
|
|
8
|
+
* @returns The run interceptor chain result.
|
|
9
|
+
*/
|
|
2
10
|
export declare function runInterceptorChain(definitions: InterceptorLike[], context: InterceptorContext, terminal: () => Promise<unknown>): Promise<unknown>;
|
|
3
11
|
//# sourceMappingURL=interceptors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interceptors.d.ts","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,kBAAkB,EAClB,eAAe,EAEhB,MAAM,YAAY,CAAC;AAiBpB,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,eAAe,EAAE,EAC9B,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"interceptors.d.ts","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,kBAAkB,EAClB,eAAe,EAEhB,MAAM,YAAY,CAAC;AAiBpB;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,eAAe,EAAE,EAC9B,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
|
package/dist/interceptors.js
CHANGED
|
@@ -7,11 +7,24 @@ async function resolveInterceptor(definition, requestContext) {
|
|
|
7
7
|
}
|
|
8
8
|
return requestContext.container.resolve(definition);
|
|
9
9
|
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Run interceptor chain.
|
|
13
|
+
*
|
|
14
|
+
* @param definitions The definitions.
|
|
15
|
+
* @param context The context.
|
|
16
|
+
* @param terminal The terminal.
|
|
17
|
+
* @returns The run interceptor chain result.
|
|
18
|
+
*/
|
|
10
19
|
export async function runInterceptorChain(definitions, context, terminal) {
|
|
20
|
+
if (definitions.length === 0) {
|
|
21
|
+
return terminal();
|
|
22
|
+
}
|
|
11
23
|
let next = {
|
|
12
24
|
handle: terminal
|
|
13
25
|
};
|
|
14
|
-
for (
|
|
26
|
+
for (let index = definitions.length - 1; index >= 0; index -= 1) {
|
|
27
|
+
const definition = definitions[index];
|
|
15
28
|
const interceptor = await resolveInterceptor(definition, context.requestContext);
|
|
16
29
|
const previous = next;
|
|
17
30
|
next = {
|
package/dist/mapping.d.ts
CHANGED
|
@@ -2,6 +2,13 @@ import type { HandlerMapping, HandlerSource, VersioningOptions } from './types.j
|
|
|
2
2
|
interface CreateHandlerMappingOptions {
|
|
3
3
|
versioning?: VersioningOptions;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Create handler mapping.
|
|
7
|
+
*
|
|
8
|
+
* @param sources The sources.
|
|
9
|
+
* @param options The options.
|
|
10
|
+
* @returns The create handler mapping result.
|
|
11
|
+
*/
|
|
5
12
|
export declare function createHandlerMapping(sources: HandlerSource[], options?: CreateHandlerMappingOptions): HandlerMapping;
|
|
6
13
|
export {};
|
|
7
14
|
//# sourceMappingURL=mapping.d.ts.map
|
package/dist/mapping.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../src/mapping.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAIV,cAAc,EAEd,aAAa,EAIb,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAOpB,UAAU,2BAA2B;IACnC,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../src/mapping.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAIV,cAAc,EAEd,aAAa,EAIb,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAOpB,UAAU,2BAA2B;IACnC,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AA6VD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE,2BAA2B,GAAG,cAAc,CAuEpH"}
|
package/dist/mapping.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getControllerMetadata, getRouteMetadata } from '@fluojs/core/internal';
|
|
2
2
|
import { getRouteProducesMetadata } from './decorators.js';
|
|
3
3
|
import { RouteConflictError } from './errors.js';
|
|
4
|
-
import { extractRoutePathParams,
|
|
4
|
+
import { extractRoutePathParams, normalizeRoutePath, parseRoutePath } from './route-path.js';
|
|
5
5
|
import { VersioningType } from './types.js';
|
|
6
6
|
function joinPaths(basePath, routePath) {
|
|
7
7
|
return normalizeRoutePath(`${basePath}/${routePath}`);
|
|
@@ -116,19 +116,32 @@ function matchesRouteVersion(descriptor, requestVersion) {
|
|
|
116
116
|
function getControllerMethodNames(controllerToken) {
|
|
117
117
|
return Object.getOwnPropertyNames(controllerToken.prototype).filter(propertyKey => propertyKey !== 'constructor');
|
|
118
118
|
}
|
|
119
|
-
function splitIncomingPathSegments(path) {
|
|
120
|
-
return normalizeRoutePath(path).split('/').filter(Boolean);
|
|
121
|
-
}
|
|
122
119
|
function buildDescriptorIndex(descriptors) {
|
|
123
|
-
const
|
|
120
|
+
const staticIndex = new Map();
|
|
121
|
+
const paramIndex = new Map();
|
|
124
122
|
for (const descriptor of descriptors) {
|
|
125
123
|
const method = descriptor.route.method;
|
|
126
124
|
const segments = parseRoutePath(descriptor.route.path, `Registered ${descriptor.route.method} route path`);
|
|
125
|
+
if (segments.every(segment => segment.kind === 'literal')) {
|
|
126
|
+
let methodMap = staticIndex.get(method);
|
|
127
|
+
if (!methodMap) {
|
|
128
|
+
methodMap = new Map();
|
|
129
|
+
staticIndex.set(method, methodMap);
|
|
130
|
+
}
|
|
131
|
+
const path = descriptor.route.path;
|
|
132
|
+
const bucket = methodMap.get(path);
|
|
133
|
+
if (bucket) {
|
|
134
|
+
bucket.push(descriptor);
|
|
135
|
+
} else {
|
|
136
|
+
methodMap.set(path, [descriptor]);
|
|
137
|
+
}
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
127
140
|
const segmentCount = segments.length;
|
|
128
|
-
let methodMap =
|
|
141
|
+
let methodMap = paramIndex.get(method);
|
|
129
142
|
if (!methodMap) {
|
|
130
143
|
methodMap = new Map();
|
|
131
|
-
|
|
144
|
+
paramIndex.set(method, methodMap);
|
|
132
145
|
}
|
|
133
146
|
let bucket = methodMap.get(segmentCount);
|
|
134
147
|
if (!bucket) {
|
|
@@ -140,7 +153,61 @@ function buildDescriptorIndex(descriptors) {
|
|
|
140
153
|
segments
|
|
141
154
|
});
|
|
142
155
|
}
|
|
143
|
-
return
|
|
156
|
+
return {
|
|
157
|
+
param: paramIndex,
|
|
158
|
+
static: staticIndex
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function findStaticMatch(descriptorBuckets, requestVersion, versioning) {
|
|
162
|
+
let firstUnversionedMatch;
|
|
163
|
+
for (const descriptors of descriptorBuckets) {
|
|
164
|
+
if (!descriptors || descriptors.length === 0) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
for (const descriptor of descriptors) {
|
|
168
|
+
if (versioning.type === VersioningType.URI) {
|
|
169
|
+
return {
|
|
170
|
+
descriptor,
|
|
171
|
+
params: {}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (matchesRouteVersion(descriptor, requestVersion)) {
|
|
175
|
+
return {
|
|
176
|
+
descriptor,
|
|
177
|
+
params: {}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (descriptor.route.version === undefined && !firstUnversionedMatch) {
|
|
181
|
+
firstUnversionedMatch = {
|
|
182
|
+
descriptor,
|
|
183
|
+
params: {}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return firstUnversionedMatch;
|
|
189
|
+
}
|
|
190
|
+
function matchParameterizedRoute(candidate, incomingSegments) {
|
|
191
|
+
const {
|
|
192
|
+
segments
|
|
193
|
+
} = candidate;
|
|
194
|
+
if (segments.length !== incomingSegments.length) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
198
|
+
const segment = segments[index];
|
|
199
|
+
if (segment.kind === 'literal' && segment.value !== incomingSegments[index]) {
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const params = {};
|
|
204
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
205
|
+
const segment = segments[index];
|
|
206
|
+
if (segment.kind === 'param') {
|
|
207
|
+
params[segment.name] = incomingSegments[index];
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return params;
|
|
144
211
|
}
|
|
145
212
|
function createHandlerDescriptors(source, versioning) {
|
|
146
213
|
const controllerMetadata = getControllerMetadata(source.controllerToken) ?? {
|
|
@@ -194,6 +261,14 @@ function buildDescriptorList(sources, versioning) {
|
|
|
194
261
|
}
|
|
195
262
|
return descriptors;
|
|
196
263
|
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Create handler mapping.
|
|
267
|
+
*
|
|
268
|
+
* @param sources The sources.
|
|
269
|
+
* @param options The options.
|
|
270
|
+
* @returns The create handler mapping result.
|
|
271
|
+
*/
|
|
197
272
|
export function createHandlerMapping(sources, options) {
|
|
198
273
|
const versioning = resolveVersioning(options);
|
|
199
274
|
const descriptors = buildDescriptorList(sources, versioning);
|
|
@@ -203,11 +278,18 @@ export function createHandlerMapping(sources, options) {
|
|
|
203
278
|
match(request) {
|
|
204
279
|
const method = request.method.toUpperCase();
|
|
205
280
|
const requestVersion = versioning.type === VersioningType.URI ? undefined : resolveRequestVersion(request, versioning);
|
|
206
|
-
const
|
|
207
|
-
const
|
|
281
|
+
const normalizedPath = normalizeRoutePath(request.path);
|
|
282
|
+
const methodStaticDescriptors = descriptorIndex.static.get(method)?.get(normalizedPath);
|
|
283
|
+
const allStaticDescriptors = descriptorIndex.static.get('ALL')?.get(normalizedPath);
|
|
284
|
+
const directStaticMatch = findStaticMatch([methodStaticDescriptors, allStaticDescriptors], requestVersion, versioning);
|
|
285
|
+
if (directStaticMatch) {
|
|
286
|
+
return directStaticMatch;
|
|
287
|
+
}
|
|
288
|
+
const incomingSegments = normalizedPath.split('/').filter(Boolean);
|
|
289
|
+
const candidates = [...(descriptorIndex.param.get(method)?.get(incomingSegments.length) ?? []), ...(descriptorIndex.param.get('ALL')?.get(incomingSegments.length) ?? [])];
|
|
208
290
|
let firstUnversionedMatch;
|
|
209
291
|
for (const candidate of candidates) {
|
|
210
|
-
const params =
|
|
292
|
+
const params = matchParameterizedRoute(candidate, incomingSegments);
|
|
211
293
|
if (!params) {
|
|
212
294
|
continue;
|
|
213
295
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"correlation.d.ts","sourceRoot":"","sources":["../../src/middleware/correlation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAY9C,wBAAgB,2BAA2B,IAAI,UAAU,CAYxD"}
|
|
1
|
+
{"version":3,"file":"correlation.d.ts","sourceRoot":"","sources":["../../src/middleware/correlation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAY9C;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,UAAU,CAYxD"}
|
|
@@ -6,6 +6,12 @@ function resolveInboundRequestId(headers) {
|
|
|
6
6
|
const value = Array.isArray(requestId) ? requestId[0] : requestId;
|
|
7
7
|
return value ?? randomUUID();
|
|
8
8
|
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create correlation middleware.
|
|
12
|
+
*
|
|
13
|
+
* @returns The create correlation middleware result.
|
|
14
|
+
*/
|
|
9
15
|
export function createCorrelationMiddleware() {
|
|
10
16
|
return {
|
|
11
17
|
async handle(context, next) {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { Middleware } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Describes the cors options contract.
|
|
4
|
+
*/
|
|
2
5
|
export interface CorsOptions {
|
|
3
6
|
allowCredentials?: boolean;
|
|
4
7
|
allowHeaders?: string[];
|
|
@@ -7,5 +10,11 @@ export interface CorsOptions {
|
|
|
7
10
|
exposeHeaders?: string[];
|
|
8
11
|
maxAge?: number;
|
|
9
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Create cors middleware.
|
|
15
|
+
*
|
|
16
|
+
* @param options The options.
|
|
17
|
+
* @returns The create cors middleware result.
|
|
18
|
+
*/
|
|
10
19
|
export declare function createCorsMiddleware(options?: CorsOptions): Middleware;
|
|
11
20
|
//# sourceMappingURL=cors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IACvF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA4BD,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,WAAgB,GAAG,UAAU,CA0D1E"}
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IACvF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA4BD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,WAAgB,GAAG,UAAU,CA0D1E"}
|
package/dist/middleware/cors.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes the cors options contract.
|
|
3
|
+
*/
|
|
4
|
+
|
|
1
5
|
function resolveOrigin(options, requestOrigin) {
|
|
2
6
|
if (typeof options.allowOrigin === 'function') {
|
|
3
7
|
return options.allowOrigin(requestOrigin);
|
|
@@ -15,6 +19,13 @@ function setHeaderIfValue(response, name, value) {
|
|
|
15
19
|
response.setHeader(name, value);
|
|
16
20
|
}
|
|
17
21
|
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create cors middleware.
|
|
25
|
+
*
|
|
26
|
+
* @param options The options.
|
|
27
|
+
* @returns The create cors middleware result.
|
|
28
|
+
*/
|
|
18
29
|
export function createCorsMiddleware(options = {}) {
|
|
19
30
|
if (options.allowCredentials === true) {
|
|
20
31
|
if (options.allowOrigin === '*' || options.allowOrigin === undefined) {
|
|
@@ -1,8 +1,42 @@
|
|
|
1
1
|
import type { Constructor } from '@fluojs/core';
|
|
2
2
|
import type { Middleware, MiddlewareContext, MiddlewareLike, MiddlewareRouteConfig, Next } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Is middleware route config.
|
|
5
|
+
*
|
|
6
|
+
* @param value The value.
|
|
7
|
+
* @returns The is middleware route config result.
|
|
8
|
+
*/
|
|
3
9
|
export declare function isMiddlewareRouteConfig(value: MiddlewareLike): value is MiddlewareRouteConfig;
|
|
10
|
+
/**
|
|
11
|
+
* Normalize route pattern.
|
|
12
|
+
*
|
|
13
|
+
* @param path The path.
|
|
14
|
+
* @returns The normalize route pattern result.
|
|
15
|
+
*/
|
|
4
16
|
export declare function normalizeRoutePattern(path: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Match route pattern.
|
|
19
|
+
*
|
|
20
|
+
* @param pattern The pattern.
|
|
21
|
+
* @param path The path.
|
|
22
|
+
* @returns The match route pattern result.
|
|
23
|
+
*/
|
|
5
24
|
export declare function matchRoutePattern(pattern: string, path: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* For routes.
|
|
27
|
+
*
|
|
28
|
+
* @param middlewareClass The middleware class.
|
|
29
|
+
* @param routes The routes.
|
|
30
|
+
* @returns The for routes result.
|
|
31
|
+
*/
|
|
6
32
|
export declare function forRoutes<T extends Constructor<Middleware>>(middlewareClass: T, ...routes: string[]): MiddlewareRouteConfig;
|
|
33
|
+
/**
|
|
34
|
+
* Run middleware chain.
|
|
35
|
+
*
|
|
36
|
+
* @param definitions The definitions.
|
|
37
|
+
* @param context The context.
|
|
38
|
+
* @param terminal The terminal.
|
|
39
|
+
* @returns The run middleware chain result.
|
|
40
|
+
*/
|
|
7
41
|
export declare function runMiddlewareChain(definitions: MiddlewareLike[], context: MiddlewareContext, terminal: Next): Promise<void>;
|
|
8
42
|
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAS,MAAM,cAAc,CAAC;AAGvD,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,IAAI,EAAkB,MAAM,aAAa,CAAC;AAM9H,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,KAAK,IAAI,qBAAqB,CAE7F;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAUxE;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,WAAW,CAAC,UAAU,CAAC,EACzD,eAAe,EAAE,CAAC,EAClB,GAAG,MAAM,EAAE,MAAM,EAAE,GAClB,qBAAqB,CAEvB;AA2CD,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,cAAc,EAAE,EAC7B,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,IAAI,GACb,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAS,MAAM,cAAc,CAAC;AAGvD,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,IAAI,EAAkB,MAAM,aAAa,CAAC;AAM9H;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,KAAK,IAAI,qBAAqB,CAE7F;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAUxE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,WAAW,CAAC,UAAU,CAAC,EACzD,eAAe,EAAE,CAAC,EAClB,GAAG,MAAM,EAAE,MAAM,EAAE,GAClB,qBAAqB,CAEvB;AA2CD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,cAAc,EAAE,EAC7B,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,IAAI,GACb,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -2,15 +2,37 @@ import { normalizeRoutePath } from '../route-path.js';
|
|
|
2
2
|
function isMiddleware(value) {
|
|
3
3
|
return typeof value === 'object' && value !== null && 'handle' in value;
|
|
4
4
|
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Is middleware route config.
|
|
8
|
+
*
|
|
9
|
+
* @param value The value.
|
|
10
|
+
* @returns The is middleware route config result.
|
|
11
|
+
*/
|
|
5
12
|
export function isMiddlewareRouteConfig(value) {
|
|
6
13
|
return typeof value === 'object' && value !== null && 'middleware' in value && 'routes' in value;
|
|
7
14
|
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Normalize route pattern.
|
|
18
|
+
*
|
|
19
|
+
* @param path The path.
|
|
20
|
+
* @returns The normalize route pattern result.
|
|
21
|
+
*/
|
|
8
22
|
export function normalizeRoutePattern(path) {
|
|
9
23
|
if (path.endsWith('/*')) {
|
|
10
24
|
return `${normalizeRoutePattern(path.slice(0, -2))}/*`;
|
|
11
25
|
}
|
|
12
26
|
return normalizeRoutePath(path);
|
|
13
27
|
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Match route pattern.
|
|
31
|
+
*
|
|
32
|
+
* @param pattern The pattern.
|
|
33
|
+
* @param path The path.
|
|
34
|
+
* @returns The match route pattern result.
|
|
35
|
+
*/
|
|
14
36
|
export function matchRoutePattern(pattern, path) {
|
|
15
37
|
const normalizedPath = normalizeRoutePattern(path);
|
|
16
38
|
const normalizedPattern = normalizeRoutePattern(pattern);
|
|
@@ -20,6 +42,14 @@ export function matchRoutePattern(pattern, path) {
|
|
|
20
42
|
}
|
|
21
43
|
return normalizedPath === normalizedPattern;
|
|
22
44
|
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* For routes.
|
|
48
|
+
*
|
|
49
|
+
* @param middlewareClass The middleware class.
|
|
50
|
+
* @param routes The routes.
|
|
51
|
+
* @returns The for routes result.
|
|
52
|
+
*/
|
|
23
53
|
export function forRoutes(middlewareClass, ...routes) {
|
|
24
54
|
return {
|
|
25
55
|
middleware: middlewareClass,
|
|
@@ -55,8 +85,25 @@ function deferNext(next) {
|
|
|
55
85
|
await next();
|
|
56
86
|
};
|
|
57
87
|
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Run middleware chain.
|
|
91
|
+
*
|
|
92
|
+
* @param definitions The definitions.
|
|
93
|
+
* @param context The context.
|
|
94
|
+
* @param terminal The terminal.
|
|
95
|
+
* @returns The run middleware chain result.
|
|
96
|
+
*/
|
|
58
97
|
export async function runMiddlewareChain(definitions, context, terminal) {
|
|
98
|
+
if (definitions.length === 0) {
|
|
99
|
+
await terminal();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
59
102
|
const middlewareChain = await resolveActiveMiddlewareDefinitions(definitions, context);
|
|
103
|
+
if (middlewareChain.length === 0) {
|
|
104
|
+
await terminal();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
60
107
|
const composed = middlewareChain.reduceRight((next, middleware) => deferNext(async () => {
|
|
61
108
|
await middleware.handle(context, next);
|
|
62
109
|
}), deferNext(terminal));
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { Middleware } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Describes the security headers options contract.
|
|
4
|
+
*/
|
|
2
5
|
export interface SecurityHeadersOptions {
|
|
3
6
|
contentSecurityPolicy?: string | false;
|
|
4
7
|
crossOriginOpenerPolicy?: string | false;
|
|
@@ -8,5 +11,11 @@ export interface SecurityHeadersOptions {
|
|
|
8
11
|
xFrameOptions?: string | false;
|
|
9
12
|
xXssProtection?: string | false;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Create security headers middleware.
|
|
16
|
+
*
|
|
17
|
+
* @param options The options.
|
|
18
|
+
* @returns The create security headers middleware result.
|
|
19
|
+
*/
|
|
11
20
|
export declare function createSecurityHeadersMiddleware(options?: SecurityHeadersOptions): Middleware;
|
|
12
21
|
//# sourceMappingURL=security-headers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../../src/middleware/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,sBAAsB;IACrC,qBAAqB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzC,mBAAmB,CAAC,EAAE,KAAK,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CACjC;AAYD,wBAAgB,+BAA+B,CAAC,OAAO,GAAE,sBAA2B,GAAG,UAAU,CA6ChG"}
|
|
1
|
+
{"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../../src/middleware/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,qBAAqB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzC,mBAAmB,CAAC,EAAE,KAAK,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CACjC;AAYD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,GAAE,sBAA2B,GAAG,UAAU,CA6ChG"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes the security headers options contract.
|
|
3
|
+
*/
|
|
4
|
+
|
|
1
5
|
const DEFAULTS = {
|
|
2
6
|
contentSecurityPolicy: "default-src 'self'",
|
|
3
7
|
crossOriginOpenerPolicy: 'same-origin',
|
|
@@ -7,6 +11,13 @@ const DEFAULTS = {
|
|
|
7
11
|
xFrameOptions: 'SAMEORIGIN',
|
|
8
12
|
xXssProtection: '0'
|
|
9
13
|
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create security headers middleware.
|
|
17
|
+
*
|
|
18
|
+
* @param options The options.
|
|
19
|
+
* @returns The create security headers middleware result.
|
|
20
|
+
*/
|
|
10
21
|
export function createSecurityHeadersMiddleware(options = {}) {
|
|
11
22
|
const csp = 'contentSecurityPolicy' in options ? options.contentSecurityPolicy : DEFAULTS.contentSecurityPolicy;
|
|
12
23
|
const coop = 'crossOriginOpenerPolicy' in options ? options.crossOriginOpenerPolicy : DEFAULTS.crossOriginOpenerPolicy;
|
package/dist/route-path.d.ts
CHANGED
|
@@ -1,15 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes the route path literal segment contract.
|
|
3
|
+
*/
|
|
1
4
|
export interface RoutePathLiteralSegment {
|
|
2
5
|
kind: 'literal';
|
|
3
6
|
value: string;
|
|
4
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Describes the route path param segment contract.
|
|
10
|
+
*/
|
|
5
11
|
export interface RoutePathParamSegment {
|
|
6
12
|
kind: 'param';
|
|
7
13
|
name: string;
|
|
8
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Defines the route path segment type.
|
|
17
|
+
*/
|
|
9
18
|
export type RoutePathSegment = RoutePathLiteralSegment | RoutePathParamSegment;
|
|
19
|
+
/**
|
|
20
|
+
* Normalize route path.
|
|
21
|
+
*
|
|
22
|
+
* @param path The path.
|
|
23
|
+
* @returns The normalize route path result.
|
|
24
|
+
*/
|
|
10
25
|
export declare function normalizeRoutePath(path: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Parse route path.
|
|
28
|
+
*
|
|
29
|
+
* @param path The path.
|
|
30
|
+
* @param label The label.
|
|
31
|
+
* @returns The parse route path result.
|
|
32
|
+
*/
|
|
11
33
|
export declare function parseRoutePath(path: string, label?: string): RoutePathSegment[];
|
|
34
|
+
/**
|
|
35
|
+
* Validate route path.
|
|
36
|
+
*
|
|
37
|
+
* @param path The path.
|
|
38
|
+
* @param label The label.
|
|
39
|
+
*/
|
|
12
40
|
export declare function validateRoutePath(path: string, label?: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Extract route path params.
|
|
43
|
+
*
|
|
44
|
+
* @param path The path.
|
|
45
|
+
* @returns The extract route path params result.
|
|
46
|
+
*/
|
|
13
47
|
export declare function extractRoutePathParams(path: string): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Match route path.
|
|
50
|
+
*
|
|
51
|
+
* @param registeredSegments The registered segments.
|
|
52
|
+
* @param incomingSegments The incoming segments.
|
|
53
|
+
* @returns The match route path result.
|
|
54
|
+
*/
|
|
14
55
|
export declare function matchRoutePath(registeredSegments: readonly RoutePathSegment[], incomingSegments: readonly string[]): Readonly<Record<string, string>> | undefined;
|
|
15
56
|
//# sourceMappingURL=route-path.d.ts.map
|
package/dist/route-path.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-path.d.ts","sourceRoot":"","sources":["../src/route-path.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,GAAG,qBAAqB,CAAC;AAsD/E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAK/E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAEpE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAE7D;AAED,wBAAgB,cAAc,CAC5B,kBAAkB,EAAE,SAAS,gBAAgB,EAAE,EAC/C,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAqB9C"}
|
|
1
|
+
{"version":3,"file":"route-path.d.ts","sourceRoot":"","sources":["../src/route-path.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,GAAG,qBAAqB,CAAC;AAsD/E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAK/E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAE7D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,kBAAkB,EAAE,SAAS,gBAAgB,EAAE,EAC/C,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAqB9C"}
|
package/dist/route-path.js
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { InvalidRoutePathError } from './errors.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Describes the route path literal segment contract.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Describes the route path param segment contract.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Defines the route path segment type.
|
|
13
|
+
*/
|
|
14
|
+
|
|
2
15
|
const routeParamNamePattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
3
16
|
const unsupportedLiteralTokenPattern = /[*?+()[\]{}\\]/;
|
|
4
17
|
const supportedRouteSyntaxDescription = 'Only literal segments and full-segment ":param" placeholders are supported.';
|
|
@@ -34,22 +47,59 @@ function parseRoutePathSegment(segment, path, label) {
|
|
|
34
47
|
value: segment
|
|
35
48
|
};
|
|
36
49
|
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Normalize route path.
|
|
53
|
+
*
|
|
54
|
+
* @param path The path.
|
|
55
|
+
* @returns The normalize route path result.
|
|
56
|
+
*/
|
|
37
57
|
export function normalizeRoutePath(path) {
|
|
38
58
|
const segments = path.split('/').filter(Boolean);
|
|
39
59
|
const normalized = `/${segments.join('/')}`;
|
|
40
60
|
return normalized === '' ? '/' : normalized;
|
|
41
61
|
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Parse route path.
|
|
65
|
+
*
|
|
66
|
+
* @param path The path.
|
|
67
|
+
* @param label The label.
|
|
68
|
+
* @returns The parse route path result.
|
|
69
|
+
*/
|
|
42
70
|
export function parseRoutePath(path, label) {
|
|
43
71
|
const normalizedPath = normalizeRoutePath(path);
|
|
44
72
|
const segments = normalizedPath.split('/').filter(Boolean);
|
|
45
73
|
return segments.map(segment => parseRoutePathSegment(segment, path, label));
|
|
46
74
|
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate route path.
|
|
78
|
+
*
|
|
79
|
+
* @param path The path.
|
|
80
|
+
* @param label The label.
|
|
81
|
+
*/
|
|
47
82
|
export function validateRoutePath(path, label) {
|
|
48
83
|
void parseRoutePath(path, label);
|
|
49
84
|
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Extract route path params.
|
|
88
|
+
*
|
|
89
|
+
* @param path The path.
|
|
90
|
+
* @returns The extract route path params result.
|
|
91
|
+
*/
|
|
50
92
|
export function extractRoutePathParams(path) {
|
|
51
93
|
return parseRoutePath(path).flatMap(segment => segment.kind === 'param' ? [segment.name] : []);
|
|
52
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Match route path.
|
|
98
|
+
*
|
|
99
|
+
* @param registeredSegments The registered segments.
|
|
100
|
+
* @param incomingSegments The incoming segments.
|
|
101
|
+
* @returns The match route path result.
|
|
102
|
+
*/
|
|
53
103
|
export function matchRoutePath(registeredSegments, incomingSegments) {
|
|
54
104
|
if (registeredSegments.length !== incomingSegments.length) {
|
|
55
105
|
return undefined;
|
package/dist/types.d.ts
CHANGED
|
@@ -182,6 +182,11 @@ export type VersioningOptions = {
|
|
|
182
182
|
/** Runtime dispatcher that executes the full HTTP request lifecycle. */
|
|
183
183
|
export interface Dispatcher {
|
|
184
184
|
dispatch(request: FrameworkRequest, response: FrameworkResponse): Promise<void>;
|
|
185
|
+
/**
|
|
186
|
+
* Returns the mapped route descriptors known to this dispatcher when the
|
|
187
|
+
* implementation can expose them without changing dispatch behavior.
|
|
188
|
+
*/
|
|
189
|
+
describeRoutes?(): readonly HandlerDescriptor[];
|
|
185
190
|
}
|
|
186
191
|
/** Logger seam used by the dispatcher for non-fatal internal failure reporting. */
|
|
187
192
|
export interface DispatcherLogger {
|