@fluojs/http 2.0.1 → 3.0.0
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 +417 -16
- package/README.md +424 -16
- package/dist/access-log-observer.d.ts +77 -0
- package/dist/access-log-observer.d.ts.map +1 -0
- package/dist/access-log-observer.js +171 -0
- package/dist/adapter.d.ts +9 -0
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +15 -1
- package/dist/adapters/binding.d.ts.map +1 -1
- package/dist/adapters/binding.js +18 -16
- package/dist/adapters/dto-binding-plan.d.ts +2 -2
- package/dist/adapters/dto-binding-plan.d.ts.map +1 -1
- package/dist/adapters/dto-binding-plan.js +13 -4
- package/dist/adapters/dto-validation-adapter.d.ts +2 -1
- package/dist/adapters/dto-validation-adapter.d.ts.map +1 -1
- package/dist/adapters/dto-validation-adapter.js +2 -2
- package/dist/byte-range-response.d.ts +71 -0
- package/dist/byte-range-response.d.ts.map +1 -0
- package/dist/byte-range-response.js +347 -0
- package/dist/client-identity.d.ts +8 -4
- package/dist/client-identity.d.ts.map +1 -1
- package/dist/client-identity.js +12 -93
- package/dist/compiled-route-identity.d.ts +17 -0
- package/dist/compiled-route-identity.d.ts.map +1 -0
- package/dist/compiled-route-identity.js +29 -0
- package/dist/connection.d.ts +67 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +480 -0
- package/dist/context/request-context-node-store.d.ts +6 -0
- package/dist/context/request-context-node-store.d.ts.map +1 -1
- package/dist/context/request-context-node-store.js +14 -0
- package/dist/context/request-context.d.ts +5 -5
- package/dist/context/request-context.d.ts.map +1 -1
- package/dist/context/request-context.js +8 -83
- package/dist/context/request-id.d.ts +10 -0
- package/dist/context/request-id.d.ts.map +1 -0
- package/dist/context/request-id.js +27 -0
- package/dist/context/sse.d.ts +13 -0
- package/dist/context/sse.d.ts.map +1 -1
- package/dist/context/sse.js +36 -6
- package/dist/cookie-helpers.d.ts +47 -0
- package/dist/cookie-helpers.d.ts.map +1 -0
- package/dist/cookie-helpers.js +166 -0
- package/dist/decorators.d.ts +52 -19
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +57 -10
- package/dist/dispatch/conditional-request-policy.d.ts +67 -0
- package/dist/dispatch/conditional-request-policy.d.ts.map +1 -0
- package/dist/dispatch/conditional-request-policy.js +297 -0
- package/dist/dispatch/dispatch-content-negotiation.d.ts +8 -0
- package/dist/dispatch/dispatch-content-negotiation.d.ts.map +1 -1
- package/dist/dispatch/dispatch-content-negotiation.js +89 -42
- package/dist/dispatch/dispatch-error-negotiation.d.ts +26 -0
- package/dist/dispatch/dispatch-error-negotiation.d.ts.map +1 -0
- package/dist/dispatch/dispatch-error-negotiation.js +110 -0
- package/dist/dispatch/dispatch-error-policy.d.ts +1 -10
- package/dist/dispatch/dispatch-error-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-error-policy.js +1 -33
- package/dist/dispatch/dispatch-error-representation.d.ts +18 -0
- package/dist/dispatch/dispatch-error-representation.d.ts.map +1 -0
- package/dist/dispatch/dispatch-error-representation.js +125 -0
- package/dist/dispatch/dispatch-response-metadata.d.ts +10 -0
- package/dist/dispatch/dispatch-response-metadata.d.ts.map +1 -0
- package/dist/dispatch/dispatch-response-metadata.js +12 -0
- package/dist/dispatch/dispatch-response-policy.d.ts +30 -3
- package/dist/dispatch/dispatch-response-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-response-policy.js +104 -15
- package/dist/dispatch/dispatcher.d.ts +5 -1
- package/dist/dispatch/dispatcher.d.ts.map +1 -1
- package/dist/dispatch/dispatcher.js +140 -100
- package/dist/dispatch/fast-path/debug-visibility.d.ts.map +1 -1
- package/dist/dispatch/fast-path/debug-visibility.js +6 -3
- package/dist/dispatch/fast-path/dispatcher-state.d.ts +10 -0
- package/dist/dispatch/fast-path/dispatcher-state.d.ts.map +1 -0
- package/dist/dispatch/fast-path/dispatcher-state.js +52 -0
- package/dist/dispatch/fast-path/eligibility-checker.d.ts.map +1 -1
- package/dist/dispatch/fast-path/eligibility-checker.js +27 -15
- package/dist/dispatch/fast-path/eligibility.d.ts +16 -10
- package/dist/dispatch/fast-path/eligibility.d.ts.map +1 -1
- package/dist/dispatch/fast-path/eligibility.js +10 -4
- package/dist/dispatch/fast-path/fast-path-executor.d.ts +1 -1
- package/dist/dispatch/fast-path/fast-path-executor.d.ts.map +1 -1
- package/dist/dispatch/fast-path/fast-path-executor.js +8 -5
- package/dist/dispatch/request-abort.d.ts +22 -0
- package/dist/dispatch/request-abort.d.ts.map +1 -0
- package/dist/dispatch/request-abort.js +30 -0
- package/dist/dispatch/response-integration.d.ts +55 -0
- package/dist/dispatch/response-integration.d.ts.map +1 -0
- package/dist/dispatch/response-integration.js +57 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +19 -0
- package/dist/guards.d.ts +1 -1
- package/dist/guards.d.ts.map +1 -1
- package/dist/header-helpers.d.ts +59 -0
- package/dist/header-helpers.d.ts.map +1 -0
- package/dist/header-helpers.js +185 -0
- package/dist/index.d.ts +1 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -15
- package/dist/index.portable.d.ts +25 -0
- package/dist/index.portable.d.ts.map +1 -0
- package/dist/index.portable.js +21 -0
- package/dist/internal.d.ts +3 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -0
- package/dist/mapping.d.ts.map +1 -1
- package/dist/mapping.js +100 -15
- package/dist/middleware/correlation.d.ts +9 -1
- package/dist/middleware/correlation.d.ts.map +1 -1
- package/dist/middleware/correlation.js +25 -14
- package/dist/middleware/cors.d.ts.map +1 -1
- package/dist/middleware/cors.js +5 -8
- package/dist/middleware/middleware.d.ts +3 -3
- package/dist/middleware/middleware.d.ts.map +1 -1
- package/dist/middleware/rate-limit.d.ts +13 -2
- package/dist/middleware/rate-limit.d.ts.map +1 -1
- package/dist/middleware/rate-limit.js +1 -0
- package/dist/static-assets.d.ts +77 -0
- package/dist/static-assets.d.ts.map +1 -0
- package/dist/static-assets.js +270 -0
- package/dist/types.d.ts +209 -16
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +69 -1
- package/package.json +19 -9
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
export * from './dispatch/dispatcher.js';
|
|
6
|
-
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL, formatFastPathStats, getDispatcherFastPathStats } from './dispatch/dispatcher.js';
|
|
7
|
-
export * from './errors.js';
|
|
8
|
-
export * from './exceptions.js';
|
|
9
|
-
export * from './mapping.js';
|
|
10
|
-
export { forRoutes, isMiddlewareRouteConfig, matchRoutePattern, normalizeRoutePattern } from './middleware/middleware.js';
|
|
11
|
-
export * from './middleware/rate-limit.js';
|
|
12
|
-
export * from './context/request-context.js';
|
|
13
|
-
export * from './middleware/security-headers.js';
|
|
14
|
-
export * from './context/sse.js';
|
|
15
|
-
export * from './types.js';
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { registerImmediateAsyncLocalStorageConstructor } from './context/request-context-node-store.js';
|
|
3
|
+
registerImmediateAsyncLocalStorageConstructor(AsyncLocalStorage);
|
|
4
|
+
export * from './index.portable.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export * from './adapter.js';
|
|
2
|
+
export * from './access-log-observer.js';
|
|
3
|
+
export { createByteRangeResponse, } from './byte-range-response.js';
|
|
4
|
+
export type { ByteRangeResponseOptions, ByteRangeResponseSource, } from './byte-range-response.js';
|
|
5
|
+
export { createStaticAssetsMiddleware, } from './static-assets.js';
|
|
6
|
+
export type { StaticAsset, StaticAssetAcceptedEncoding, StaticAssetContentEncoding, StaticAssetNotAcceptable, StaticAssetResolveContext, StaticAssetResolution, StaticAssetSource, StaticAssetsMiddleware, StaticAssetsMiddlewareOptions, } from './static-assets.js';
|
|
7
|
+
export * from './context/request-context.js';
|
|
8
|
+
export * from './context/sse.js';
|
|
9
|
+
export * from './connection.js';
|
|
10
|
+
export * from './cookie-helpers.js';
|
|
11
|
+
export { All, Controller, Convert, Delete, FromBody, FromCookie, FromFiles, FromHeader, FromPath, FromQuery, Get, Head, Header, HttpCode, Optional, Options, Patch, Post, Produces, Put, Query, Redirect, RequestDto, Route, Sse, UseGuards, UseInterceptors, Version, } from './decorators.js';
|
|
12
|
+
export * from './dispatch/dispatcher.js';
|
|
13
|
+
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL, formatFastPathStats, getDispatcherFastPathStats, } from './dispatch/dispatcher.js';
|
|
14
|
+
export type { FastPathEligibility, FastPathStats } from './dispatch/fast-path/index.js';
|
|
15
|
+
export * from './errors.js';
|
|
16
|
+
export * from './exceptions.js';
|
|
17
|
+
export { appendVaryHeader, buildContentDisposition, getRequestHeader, getResponseHeader, hasResponseHeader, } from './header-helpers.js';
|
|
18
|
+
export * from './mapping.js';
|
|
19
|
+
export * from './middleware/correlation.js';
|
|
20
|
+
export * from './middleware/cors.js';
|
|
21
|
+
export { forRoutes, isMiddlewareRouteConfig, matchRoutePattern, normalizeRoutePattern, } from './middleware/middleware.js';
|
|
22
|
+
export * from './middleware/rate-limit.js';
|
|
23
|
+
export * from './middleware/security-headers.js';
|
|
24
|
+
export * from './types.js';
|
|
25
|
+
//# sourceMappingURL=index.portable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.portable.d.ts","sourceRoot":"","sources":["../src/index.portable.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,OAAO,EACL,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,WAAW,EACX,2BAA2B,EAC3B,0BAA0B,EAC1B,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAC5B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EACL,GAAG,EACH,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,EACV,QAAQ,EACR,SAAS,EACT,GAAG,EACH,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,KAAK,EACL,QAAQ,EACR,UAAU,EACV,KAAK,EACL,GAAG,EACH,SAAS,EACT,eAAe,EACf,OAAO,GACR,MAAM,iBAAiB,CAAC;AACzB,cAAc,0BAA0B,CAAC;AACzC,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACxF,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from './adapter.js';
|
|
2
|
+
export * from './access-log-observer.js';
|
|
3
|
+
export { createByteRangeResponse } from './byte-range-response.js';
|
|
4
|
+
export { createStaticAssetsMiddleware } from './static-assets.js';
|
|
5
|
+
export * from './context/request-context.js';
|
|
6
|
+
export * from './context/sse.js';
|
|
7
|
+
export * from './connection.js';
|
|
8
|
+
export * from './cookie-helpers.js';
|
|
9
|
+
export { All, Controller, Convert, Delete, FromBody, FromCookie, FromFiles, FromHeader, FromPath, FromQuery, Get, Head, Header, HttpCode, Optional, Options, Patch, Post, Produces, Put, Query, Redirect, RequestDto, Route, Sse, UseGuards, UseInterceptors, Version } from './decorators.js';
|
|
10
|
+
export * from './dispatch/dispatcher.js';
|
|
11
|
+
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL, formatFastPathStats, getDispatcherFastPathStats } from './dispatch/dispatcher.js';
|
|
12
|
+
export * from './errors.js';
|
|
13
|
+
export * from './exceptions.js';
|
|
14
|
+
export { appendVaryHeader, buildContentDisposition, getRequestHeader, getResponseHeader, hasResponseHeader } from './header-helpers.js';
|
|
15
|
+
export * from './mapping.js';
|
|
16
|
+
export * from './middleware/correlation.js';
|
|
17
|
+
export * from './middleware/cors.js';
|
|
18
|
+
export { forRoutes, isMiddlewareRouteConfig, matchRoutePattern, normalizeRoutePattern } from './middleware/middleware.js';
|
|
19
|
+
export * from './middleware/rate-limit.js';
|
|
20
|
+
export * from './middleware/security-headers.js';
|
|
21
|
+
export * from './types.js';
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { createFetchStyleHttpAdapterRealtimeCapability, type HttpApplicationAdapter, } from './adapter.js';
|
|
2
2
|
export { DefaultBinder } from './adapters/binding.js';
|
|
3
3
|
export { resolveClientIdentity } from './client-identity.js';
|
|
4
|
+
export { getCompiledRouteIdentity } from './compiled-route-identity.js';
|
|
5
|
+
export { FRAMEWORK_RESPONSE_VALUE_FINALIZER, FRAMEWORK_RESPONSE_WRITER, registerFrameworkResponseValueFinalizer, registerFrameworkResponseWriter, type FrameworkResponseValueFinalizer, type FrameworkResponseValueFinalizerContext, type FrameworkResponseWriter, type FrameworkResponseWriterContext, } from './dispatch/response-integration.js';
|
|
6
|
+
export { attachFrameworkRequestNativeRouteHandoff, bindRawRequestNativeRouteHandoff, consumeRawRequestNativeRouteHandoff, isRoutePathNormalizationSensitive, type NativeRouteHandoff, readFrameworkRequestNativeRouteHandoff, } from './dispatch/native-route-handoff.js';
|
|
4
7
|
export type { Dispatcher } from './types.js';
|
|
5
|
-
export { attachFrameworkRequestNativeRouteHandoff, bindRawRequestNativeRouteHandoff, consumeRawRequestNativeRouteHandoff, isRoutePathNormalizationSensitive, readFrameworkRequestNativeRouteHandoff, type NativeRouteHandoff, } from './dispatch/native-route-handoff.js';
|
|
6
8
|
//# sourceMappingURL=internal.d.ts.map
|
package/dist/internal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6CAA6C,EAC7C,KAAK,sBAAsB,GAC5B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6CAA6C,EAC7C,KAAK,sBAAsB,GAC5B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,kCAAkC,EAClC,yBAAyB,EACzB,uCAAuC,EACvC,+BAA+B,EAC/B,KAAK,+BAA+B,EACpC,KAAK,sCAAsC,EAC3C,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,GACpC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,wCAAwC,EACxC,gCAAgC,EAChC,mCAAmC,EACnC,iCAAiC,EACjC,KAAK,kBAAkB,EACvB,sCAAsC,GACvC,MAAM,oCAAoC,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/internal.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { createFetchStyleHttpAdapterRealtimeCapability } from './adapter.js';
|
|
2
2
|
export { DefaultBinder } from './adapters/binding.js';
|
|
3
3
|
export { resolveClientIdentity } from './client-identity.js';
|
|
4
|
+
export { getCompiledRouteIdentity } from './compiled-route-identity.js';
|
|
5
|
+
export { FRAMEWORK_RESPONSE_VALUE_FINALIZER, FRAMEWORK_RESPONSE_WRITER, registerFrameworkResponseValueFinalizer, registerFrameworkResponseWriter } from './dispatch/response-integration.js';
|
|
4
6
|
export { attachFrameworkRequestNativeRouteHandoff, bindRawRequestNativeRouteHandoff, consumeRawRequestNativeRouteHandoff, isRoutePathNormalizationSensitive, readFrameworkRequestNativeRouteHandoff } from './dispatch/native-route-handoff.js';
|
package/dist/mapping.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../src/mapping.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../src/mapping.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAIV,cAAc,EAId,aAAa,EAOb,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAQpB,UAAU,2BAA2B;IACnC,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAycD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE,2BAA2B,GAAG,cAAc,CA8EpH"}
|
package/dist/mapping.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getControllerMetadata, getRouteMetadata } from '@fluojs/core/internal';
|
|
2
|
+
import { attachCompiledRouteIdentity } from './compiled-route-identity.js';
|
|
2
3
|
import { getRouteProducesMetadata } from './decorators.js';
|
|
3
4
|
import { RouteConflictError } from './errors.js';
|
|
5
|
+
import { isMiddlewareRouteConfig } from './middleware/middleware.js';
|
|
4
6
|
import { extractRoutePathParams, normalizeRoutePath, parseRoutePath } from './route-path.js';
|
|
5
7
|
import { VersioningType } from './types.js';
|
|
6
8
|
function joinPaths(basePath, routePath) {
|
|
@@ -19,16 +21,27 @@ function applyVersionPrefix(path, version) {
|
|
|
19
21
|
function normalizeVersionValue(version) {
|
|
20
22
|
return version.trim().replace(/^v/i, '');
|
|
21
23
|
}
|
|
22
|
-
function
|
|
23
|
-
const
|
|
24
|
+
function normalizeHeaderName(headerName) {
|
|
25
|
+
const normalized = headerName.trim().toLowerCase();
|
|
26
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
27
|
+
}
|
|
28
|
+
function getMatchingRequestHeaderValues(request, headerName) {
|
|
29
|
+
const normalizedHeaderName = normalizeHeaderName(headerName);
|
|
24
30
|
if (!normalizedHeaderName) {
|
|
25
|
-
return
|
|
31
|
+
return [];
|
|
26
32
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
const matches = [];
|
|
34
|
+
for (const [name, value] of Object.entries(request.headers)) {
|
|
35
|
+
if (name.toLowerCase() === normalizedHeaderName) {
|
|
36
|
+
matches.push(value);
|
|
30
37
|
}
|
|
31
|
-
|
|
38
|
+
}
|
|
39
|
+
return matches;
|
|
40
|
+
}
|
|
41
|
+
function readHeaderValue(request, headerName) {
|
|
42
|
+
const matches = getMatchingRequestHeaderValues(request, headerName);
|
|
43
|
+
for (const match of matches) {
|
|
44
|
+
const values = Array.isArray(match) ? match : [match];
|
|
32
45
|
for (const value of values) {
|
|
33
46
|
const normalized = value?.trim();
|
|
34
47
|
if (normalized) {
|
|
@@ -38,11 +51,25 @@ function readHeaderValue(request, headerName) {
|
|
|
38
51
|
}
|
|
39
52
|
return undefined;
|
|
40
53
|
}
|
|
54
|
+
function readCombinedHeaderValue(request, headerName) {
|
|
55
|
+
const matches = getMatchingRequestHeaderValues(request, headerName);
|
|
56
|
+
const values = [];
|
|
57
|
+
for (const match of matches) {
|
|
58
|
+
const entries = Array.isArray(match) ? match : [match];
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
const normalized = entry?.trim();
|
|
61
|
+
if (normalized) {
|
|
62
|
+
values.push(normalized);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return values.length > 0 ? values.join(',') : undefined;
|
|
67
|
+
}
|
|
41
68
|
function escapeRegExp(value) {
|
|
42
69
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
43
70
|
}
|
|
44
71
|
function extractVersionFromMediaType(request, key) {
|
|
45
|
-
const accept =
|
|
72
|
+
const accept = readCombinedHeaderValue(request, 'accept');
|
|
46
73
|
if (!accept) {
|
|
47
74
|
return undefined;
|
|
48
75
|
}
|
|
@@ -209,12 +236,12 @@ function matchParameterizedRoute(candidate, incomingSegments) {
|
|
|
209
236
|
}
|
|
210
237
|
return params;
|
|
211
238
|
}
|
|
212
|
-
function createHandlerDescriptors(source, versioning) {
|
|
239
|
+
function createHandlerDescriptors(source, versioning, sourceIndex) {
|
|
213
240
|
const controllerMetadata = getControllerMetadata(source.controllerToken) ?? {
|
|
214
241
|
basePath: ''
|
|
215
242
|
};
|
|
216
243
|
const descriptors = [];
|
|
217
|
-
for (const propertyKey of getControllerMethodNames(source.controllerToken)) {
|
|
244
|
+
for (const [methodIndex, propertyKey] of getControllerMethodNames(source.controllerToken).entries()) {
|
|
218
245
|
const routeMetadata = getRouteMetadata(source.controllerToken.prototype, propertyKey);
|
|
219
246
|
if (!routeMetadata) {
|
|
220
247
|
continue;
|
|
@@ -223,7 +250,7 @@ function createHandlerDescriptors(source, versioning) {
|
|
|
223
250
|
const routePath = joinPaths(controllerMetadata.basePath, routeMetadata.path);
|
|
224
251
|
const effectivePath = versioning.type === VersioningType.URI ? applyVersionPrefix(routePath, effectiveVersion) : routePath;
|
|
225
252
|
const produces = getRouteProducesMetadata(source.controllerToken, propertyKey);
|
|
226
|
-
descriptors.push({
|
|
253
|
+
descriptors.push(attachCompiledRouteIdentity({
|
|
227
254
|
controllerToken: source.controllerToken,
|
|
228
255
|
metadata: {
|
|
229
256
|
controllerPath: controllerMetadata.basePath,
|
|
@@ -244,12 +271,12 @@ function createHandlerDescriptors(source, versioning) {
|
|
|
244
271
|
path: effectivePath,
|
|
245
272
|
version: effectiveVersion
|
|
246
273
|
}
|
|
247
|
-
});
|
|
274
|
+
}, `v1:${sourceIndex}:${methodIndex}`));
|
|
248
275
|
}
|
|
249
276
|
return descriptors;
|
|
250
277
|
}
|
|
251
278
|
function buildDescriptorList(sources, versioning) {
|
|
252
|
-
const descriptors = sources.flatMap(source => createHandlerDescriptors(source, versioning));
|
|
279
|
+
const descriptors = sources.flatMap((source, sourceIndex) => createHandlerDescriptors(source, versioning, sourceIndex));
|
|
253
280
|
const seen = new Set();
|
|
254
281
|
for (const descriptor of descriptors) {
|
|
255
282
|
const routeVersion = descriptor.route.version === undefined ? '<none>' : normalizeVersionValue(descriptor.route.version);
|
|
@@ -261,6 +288,59 @@ function buildDescriptorList(sources, versioning) {
|
|
|
261
288
|
}
|
|
262
289
|
return descriptors;
|
|
263
290
|
}
|
|
291
|
+
function freezeDescriptorSnapshot(descriptors) {
|
|
292
|
+
const snapshot = descriptors.map(descriptor => {
|
|
293
|
+
const {
|
|
294
|
+
metadata,
|
|
295
|
+
route
|
|
296
|
+
} = descriptor;
|
|
297
|
+
const frozenMetadata = Object.freeze({
|
|
298
|
+
...metadata,
|
|
299
|
+
moduleMiddleware: freezeModuleMiddlewareSnapshot(metadata.moduleMiddleware),
|
|
300
|
+
pathParams: Object.freeze([...metadata.pathParams])
|
|
301
|
+
});
|
|
302
|
+
const frozenRoute = Object.freeze({
|
|
303
|
+
...route,
|
|
304
|
+
...(route.guards ? {
|
|
305
|
+
guards: Object.freeze([...route.guards])
|
|
306
|
+
} : {}),
|
|
307
|
+
...(route.headers ? {
|
|
308
|
+
headers: Object.freeze(route.headers.map(header => Object.freeze({
|
|
309
|
+
...header
|
|
310
|
+
})))
|
|
311
|
+
} : {}),
|
|
312
|
+
...(route.interceptors ? {
|
|
313
|
+
interceptors: Object.freeze([...route.interceptors])
|
|
314
|
+
} : {}),
|
|
315
|
+
...(route.produces ? {
|
|
316
|
+
produces: Object.freeze([...route.produces])
|
|
317
|
+
} : {}),
|
|
318
|
+
...(route.redirect ? {
|
|
319
|
+
redirect: Object.freeze({
|
|
320
|
+
...route.redirect
|
|
321
|
+
})
|
|
322
|
+
} : {})
|
|
323
|
+
});
|
|
324
|
+
return Object.freeze({
|
|
325
|
+
...descriptor,
|
|
326
|
+
metadata: frozenMetadata,
|
|
327
|
+
route: frozenRoute
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
return Object.freeze(snapshot);
|
|
331
|
+
}
|
|
332
|
+
function freezeModuleMiddlewareSnapshot(definitions) {
|
|
333
|
+
const snapshot = definitions.map(definition => {
|
|
334
|
+
if (!isMiddlewareRouteConfig(definition)) {
|
|
335
|
+
return definition;
|
|
336
|
+
}
|
|
337
|
+
return Object.freeze({
|
|
338
|
+
middleware: definition.middleware,
|
|
339
|
+
routes: Object.freeze([...definition.routes])
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
return Object.freeze(snapshot);
|
|
343
|
+
}
|
|
264
344
|
|
|
265
345
|
/**
|
|
266
346
|
* Create handler mapping.
|
|
@@ -271,9 +351,9 @@ function buildDescriptorList(sources, versioning) {
|
|
|
271
351
|
*/
|
|
272
352
|
export function createHandlerMapping(sources, options) {
|
|
273
353
|
const versioning = resolveVersioning(options);
|
|
274
|
-
const descriptors = buildDescriptorList(sources, versioning);
|
|
354
|
+
const descriptors = freezeDescriptorSnapshot(buildDescriptorList(sources, versioning));
|
|
275
355
|
const descriptorIndex = buildDescriptorIndex(descriptors);
|
|
276
|
-
|
|
356
|
+
const mapping = {
|
|
277
357
|
descriptors,
|
|
278
358
|
match(request) {
|
|
279
359
|
const method = request.method.toUpperCase();
|
|
@@ -323,4 +403,9 @@ export function createHandlerMapping(sources, options) {
|
|
|
323
403
|
return undefined;
|
|
324
404
|
}
|
|
325
405
|
};
|
|
406
|
+
Object.defineProperty(mapping, 'descriptors', {
|
|
407
|
+
configurable: false,
|
|
408
|
+
writable: false
|
|
409
|
+
});
|
|
410
|
+
return mapping;
|
|
326
411
|
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import type { Middleware } from '../types.js';
|
|
1
|
+
import type { Middleware, MiddlewareLike, RequestContext } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Initializes correlation-aware request contexts before lifecycle observers run.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
* @param middleware Global middleware definitions registered with the dispatcher.
|
|
7
|
+
* @param context Request context to initialize.
|
|
8
|
+
*/
|
|
9
|
+
export declare function initializeCorrelationMiddlewareRequestContext(middleware: readonly MiddlewareLike[], context: RequestContext): void;
|
|
2
10
|
/**
|
|
3
11
|
* Create correlation middleware.
|
|
4
12
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"correlation.d.ts","sourceRoot":"","sources":["../../src/middleware/correlation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"correlation.d.ts","sourceRoot":"","sources":["../../src/middleware/correlation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAuBhG;;;;;;GAMG;AACH,wBAAgB,6CAA6C,CAC3D,UAAU,EAAE,SAAS,cAAc,EAAE,EACrC,OAAO,EAAE,cAAc,GACtB,IAAI,CAUN;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,UAAU,CAWxD"}
|
|
@@ -1,16 +1,28 @@
|
|
|
1
|
+
import { resolveRequestId } from '../context/request-id.js';
|
|
1
2
|
const REQUEST_ID_HEADER = 'x-request-id';
|
|
2
|
-
const
|
|
3
|
-
function
|
|
4
|
-
const requestId =
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const CORRELATION_REQUEST_CONTEXT_INITIALIZER = Symbol('fluo.http.correlationRequestContextInitializer');
|
|
4
|
+
function initializeCorrelationRequestContext(context, request = context.request) {
|
|
5
|
+
const requestId = context.requestId ?? resolveRequestId(request);
|
|
6
|
+
if (requestId === undefined) {
|
|
7
|
+
throw new Error('Correlation request ID generation unexpectedly returned undefined.');
|
|
8
|
+
}
|
|
9
|
+
context.requestId = requestId;
|
|
10
|
+
return requestId;
|
|
7
11
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Initializes correlation-aware request contexts before lifecycle observers run.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
* @param middleware Global middleware definitions registered with the dispatcher.
|
|
18
|
+
* @param context Request context to initialize.
|
|
19
|
+
*/
|
|
20
|
+
export function initializeCorrelationMiddlewareRequestContext(middleware, context) {
|
|
21
|
+
for (const definition of middleware) {
|
|
22
|
+
if (typeof definition === 'object' && definition !== null && CORRELATION_REQUEST_CONTEXT_INITIALIZER in definition) {
|
|
23
|
+
definition[CORRELATION_REQUEST_CONTEXT_INITIALIZER](context);
|
|
24
|
+
}
|
|
12
25
|
}
|
|
13
|
-
return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;
|
|
14
26
|
}
|
|
15
27
|
|
|
16
28
|
/**
|
|
@@ -20,11 +32,10 @@ function createRequestId() {
|
|
|
20
32
|
*/
|
|
21
33
|
export function createCorrelationMiddleware() {
|
|
22
34
|
return {
|
|
35
|
+
[CORRELATION_REQUEST_CONTEXT_INITIALIZER]: initializeCorrelationRequestContext,
|
|
23
36
|
async handle(context, next) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
context.response.setHeader(REQUEST_ID_HEADER, context.requestContext.requestId);
|
|
37
|
+
const requestId = initializeCorrelationRequestContext(context.requestContext, context.request);
|
|
38
|
+
context.response.setHeader(REQUEST_ID_HEADER, requestId);
|
|
28
39
|
await next();
|
|
29
40
|
}
|
|
30
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AACA,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,5 @@
|
|
|
1
|
+
import { appendVaryHeader, getRequestHeader } from '../header-helpers.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Describes the cors options contract.
|
|
3
5
|
*/
|
|
@@ -35,7 +37,7 @@ export function createCorsMiddleware(options = {}) {
|
|
|
35
37
|
const allowMethods = options.allowMethods ?? ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];
|
|
36
38
|
return {
|
|
37
39
|
async handle(context, next) {
|
|
38
|
-
const requestOriginHeader = context.request
|
|
40
|
+
const requestOriginHeader = getRequestHeader(context.request, 'origin');
|
|
39
41
|
const requestOrigin = Array.isArray(requestOriginHeader) ? requestOriginHeader[0] : requestOriginHeader;
|
|
40
42
|
const origin = resolveOrigin(options, requestOrigin);
|
|
41
43
|
if (origin) {
|
|
@@ -50,14 +52,9 @@ export function createCorsMiddleware(options = {}) {
|
|
|
50
52
|
setHeaderIfValue(context.response, 'Access-Control-Allow-Credentials', options.allowCredentials ? 'true' : undefined);
|
|
51
53
|
setHeaderIfValue(context.response, 'Access-Control-Max-Age', options.maxAge !== undefined ? String(options.maxAge) : undefined);
|
|
52
54
|
if (origin && origin !== '*') {
|
|
53
|
-
|
|
54
|
-
const varyValues = existingVary ? Array.isArray(existingVary) ? existingVary : String(existingVary).split(',').map(v => v.trim()) : [];
|
|
55
|
-
if (!varyValues.some(v => v.toLowerCase() === 'origin')) {
|
|
56
|
-
varyValues.push('Origin');
|
|
57
|
-
}
|
|
58
|
-
context.response.setHeader('Vary', varyValues.join(', '));
|
|
55
|
+
appendVaryHeader(context.response, 'Origin');
|
|
59
56
|
}
|
|
60
|
-
const requestedPreflightMethod = context.request
|
|
57
|
+
const requestedPreflightMethod = getRequestHeader(context.request, 'access-control-request-method');
|
|
61
58
|
const hasPreflightMethod = Array.isArray(requestedPreflightMethod) ? requestedPreflightMethod.length > 0 : requestedPreflightMethod !== undefined;
|
|
62
59
|
if (context.request.method === 'OPTIONS' && hasPreflightMethod) {
|
|
63
60
|
context.response.setStatus(204);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Constructor } from '@fluojs/core';
|
|
2
|
-
import type { Middleware, MiddlewareContext, MiddlewareLike, MiddlewareRouteConfig, Next } from '../types.js';
|
|
2
|
+
import type { Middleware, MiddlewareContext, MiddlewareLike, MiddlewareRouteConfig, MiddlewareRouteSnapshot, MiddlewareSnapshotLike, Next } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Is middleware route config.
|
|
5
5
|
*
|
|
6
6
|
* @param value The value.
|
|
7
7
|
* @returns The is middleware route config result.
|
|
8
8
|
*/
|
|
9
|
-
export declare function isMiddlewareRouteConfig(value: MiddlewareLike): value is MiddlewareRouteConfig;
|
|
9
|
+
export declare function isMiddlewareRouteConfig(value: MiddlewareLike | MiddlewareSnapshotLike): value is MiddlewareRouteConfig | MiddlewareRouteSnapshot;
|
|
10
10
|
/**
|
|
11
11
|
* Normalize route pattern.
|
|
12
12
|
*
|
|
@@ -38,5 +38,5 @@ export declare function forRoutes<T extends Constructor<Middleware>>(middlewareC
|
|
|
38
38
|
* @param terminal The terminal.
|
|
39
39
|
* @returns The run middleware chain result.
|
|
40
40
|
*/
|
|
41
|
-
export declare function runMiddlewareChain(definitions: MiddlewareLike[], context: MiddlewareContext, terminal: Next): Promise<void>;
|
|
41
|
+
export declare function runMiddlewareChain(definitions: readonly (MiddlewareLike | MiddlewareSnapshotLike)[], context: MiddlewareContext, terminal: Next): Promise<void>;
|
|
42
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,
|
|
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,EACV,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,IAAI,EAEL,MAAM,aAAa,CAAC;AAMrB;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,GAAG,sBAAsB,GAC7C,KAAK,IAAI,qBAAqB,GAAG,uBAAuB,CAE1D;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;AA8CD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,SAAS,CAAC,cAAc,GAAG,sBAAsB,CAAC,EAAE,EACjE,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,IAAI,GACb,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MiddlewareContext, Middleware } from '../types.js';
|
|
2
|
+
import type { TrustProxyPolicy } from '../connection.js';
|
|
2
3
|
/** Snapshot of one key's current rate-limit window state. */
|
|
3
4
|
export interface RateLimitStoreEntry {
|
|
4
5
|
count: number;
|
|
@@ -18,10 +19,20 @@ export interface RateLimitOptions {
|
|
|
18
19
|
keyResolver?: (ctx: MiddlewareContext) => string;
|
|
19
20
|
store?: RateLimitStore;
|
|
20
21
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
22
|
+
* Broad legacy compatibility mode for forwarding headers.
|
|
23
|
+
*
|
|
24
|
+
* This trusts the complete `Forwarded`, `X-Forwarded-For`, or `X-Real-IP`
|
|
25
|
+
* chain and is not limited to the direct peer. Use `trustProxy` instead for
|
|
26
|
+
* new deployments with a known proxy boundary.
|
|
23
27
|
*/
|
|
24
28
|
trustProxyHeaders?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Explicit proxy boundary used for default client identity resolution.
|
|
31
|
+
*
|
|
32
|
+
* @remarks
|
|
33
|
+
* Prefer this policy over the broad legacy `trustProxyHeaders` mode.
|
|
34
|
+
*/
|
|
35
|
+
trustProxy?: TrustProxyPolicy;
|
|
25
36
|
}
|
|
26
37
|
/**
|
|
27
38
|
* Create the built-in in-memory store for request rate-limit windows.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,6DAA6D;AAC7D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;IAC7F,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,MAAM,CAAC;IACjD,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AASD;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,cAAc,CAwC3D;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,GAAG,UAAU,CAkD/E"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { MaybePromise } from '@fluojs/core';
|
|
2
|
+
import { type ByteRangeResponseSource } from './byte-range-response.js';
|
|
3
|
+
import type { Middleware, ResponseValidators } from './types.js';
|
|
4
|
+
/** Content encodings that a static asset source may select. */
|
|
5
|
+
export type StaticAssetContentEncoding = 'br' | 'gzip';
|
|
6
|
+
/** Request encoding names considered while selecting a static representation. */
|
|
7
|
+
export type StaticAssetAcceptedEncoding = StaticAssetContentEncoding | 'identity';
|
|
8
|
+
/** Metadata for one selected static representation. */
|
|
9
|
+
export interface StaticAsset {
|
|
10
|
+
/** Media type for the logical asset path. */
|
|
11
|
+
readonly contentType: string;
|
|
12
|
+
/** Optional representation encoding selected by the asset source. */
|
|
13
|
+
readonly contentEncoding?: StaticAssetContentEncoding;
|
|
14
|
+
/** Portable bytes or lazy stream factory for the selected representation. */
|
|
15
|
+
readonly source: ByteRangeResponseSource;
|
|
16
|
+
/** Exact selected representation length in bytes. */
|
|
17
|
+
readonly size: number;
|
|
18
|
+
/** Validators emitted and evaluated for the selected representation. */
|
|
19
|
+
readonly validators?: ResponseValidators;
|
|
20
|
+
/** Whether selection can vary by `Accept-Encoding`, including an identity fallback. */
|
|
21
|
+
readonly variesByEncoding?: boolean;
|
|
22
|
+
/** Releases source-owned resources after the response settles. */
|
|
23
|
+
readonly dispose?: () => MaybePromise<void>;
|
|
24
|
+
}
|
|
25
|
+
/** Context supplied to an application-owned static asset source. */
|
|
26
|
+
export interface StaticAssetResolveContext {
|
|
27
|
+
/** Ordered encodings accepted by the request. */
|
|
28
|
+
readonly acceptedEncodings: readonly StaticAssetAcceptedEncoding[];
|
|
29
|
+
/** Request cancellation signal when the adapter exposes one. */
|
|
30
|
+
readonly signal?: AbortSignal;
|
|
31
|
+
}
|
|
32
|
+
/** Resolution outcome for an existing asset without an acceptable representation. */
|
|
33
|
+
export interface StaticAssetNotAcceptable {
|
|
34
|
+
/** Signals that the requested asset exists but no representation is acceptable. */
|
|
35
|
+
readonly notAcceptable: true;
|
|
36
|
+
}
|
|
37
|
+
/** Result returned by an application-owned static asset source. */
|
|
38
|
+
export type StaticAssetResolution = StaticAsset | StaticAssetNotAcceptable | undefined;
|
|
39
|
+
/** Runtime-neutral source for static asset representations. */
|
|
40
|
+
export interface StaticAssetSource {
|
|
41
|
+
/**
|
|
42
|
+
* Resolves a normalized relative asset path.
|
|
43
|
+
*
|
|
44
|
+
* Paths never begin with `/`; every `/`-separated segment is non-empty, is not
|
|
45
|
+
* `.` or `..`, and contains no backslash or NUL.
|
|
46
|
+
*
|
|
47
|
+
* @param path Normalized relative asset path.
|
|
48
|
+
* @param context Request capabilities relevant to source selection.
|
|
49
|
+
* @returns The selected representation, an explicit unacceptable outcome, or `undefined` when no asset exists.
|
|
50
|
+
*/
|
|
51
|
+
resolve(path: string, context: StaticAssetResolveContext): MaybePromise<StaticAssetResolution>;
|
|
52
|
+
}
|
|
53
|
+
/** Static asset middleware configuration. */
|
|
54
|
+
export interface StaticAssetsMiddlewareOptions {
|
|
55
|
+
/** Required application-owned source; the portable layer never opens a filesystem itself. */
|
|
56
|
+
readonly source: StaticAssetSource;
|
|
57
|
+
/** URL prefix owned by this middleware. Defaults to `/`. */
|
|
58
|
+
readonly prefix?: string;
|
|
59
|
+
/** Dotfile policy. `deny` writes 403; `ignore` leaves the request to later middleware/routes. */
|
|
60
|
+
readonly dotfiles?: 'allow' | 'deny' | 'ignore';
|
|
61
|
+
/** Directory indexes resolved only for paths ending in `/`. Defaults to `false`. */
|
|
62
|
+
readonly index?: false | string | readonly string[];
|
|
63
|
+
/** Cache-Control value emitted for served and conditional responses. Defaults to `public, max-age=0`. */
|
|
64
|
+
readonly cacheControl?: false | string;
|
|
65
|
+
}
|
|
66
|
+
/** Static middleware that serves a required explicit {@link StaticAssetSource}. */
|
|
67
|
+
export interface StaticAssetsMiddleware extends Middleware {
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Creates portable static asset middleware without assuming filesystem access.
|
|
71
|
+
*
|
|
72
|
+
* @param options Source and URL/security policy for one static mount.
|
|
73
|
+
* @returns Middleware that serves matching `GET` and `HEAD` asset requests.
|
|
74
|
+
* @throws {TypeError} When configuration is structurally invalid.
|
|
75
|
+
*/
|
|
76
|
+
export declare function createStaticAssetsMiddleware(options: StaticAssetsMiddlewareOptions): StaticAssetsMiddleware;
|
|
77
|
+
//# sourceMappingURL=static-assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-assets.d.ts","sourceRoot":"","sources":["../src/static-assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAKpB,+DAA+D;AAC/D,MAAM,MAAM,0BAA0B,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvD,iFAAiF;AACjF,MAAM,MAAM,2BAA2B,GAAG,0BAA0B,GAAG,UAAU,CAAC;AAElF,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,eAAe,CAAC,EAAE,0BAA0B,CAAC;IACtD,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IACzC,uFAAuF;IACvF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,kEAAkE;IAClE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,oEAAoE;AACpE,MAAM,WAAW,yBAAyB;IACxC,iDAAiD;IACjD,QAAQ,CAAC,iBAAiB,EAAE,SAAS,2BAA2B,EAAE,CAAC;IACnE,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,qFAAqF;AACrF,MAAM,WAAW,wBAAwB;IACvC,mFAAmF;IACnF,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC;CAC9B;AAED,mEAAmE;AACnE,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG,wBAAwB,GAAG,SAAS,CAAC;AAEvF,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;OASG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;CAChG;AAED,6CAA6C;AAC7C,MAAM,WAAW,6BAA6B;IAC5C,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,iGAAiG;IACjG,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAChD,oFAAoF;IACpF,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACpD,yGAAyG;IACzG,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxC;AAED,mFAAmF;AACnF,MAAM,WAAW,sBAAuB,SAAQ,UAAU;CAAG;AAE7D;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,6BAA6B,GACrC,sBAAsB,CAyGxB"}
|