@decohere/http 0.0.1-dev.126 → 0.0.1-dev.5
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.md +2 -2
- package/package.json +4 -13
- package/src/app/app.ts +147 -0
- package/src/app/module.ts +19 -0
- package/src/auth/ability.ts +56 -0
- package/src/auth/auth.config.ts +34 -0
- package/src/auth/auth.extensions.ts +115 -0
- package/src/auth/auth.types.ts +124 -0
- package/src/auth/casl-authorization.service.ts +62 -0
- package/{types/src/auth/principal-provider.d.ts → src/auth/principal-provider.ts} +13 -5
- package/src/auth/safe-outbound-url.ts +117 -0
- package/src/auth/token-service.ts +192 -0
- package/src/builder/builder.ts +118 -0
- package/{es6/src/const.js → src/const.ts} +25 -17
- package/src/health/health.controller.ts +34 -0
- package/src/health/health.extensions.ts +53 -0
- package/src/health/readiness.service.ts +33 -0
- package/{types/src/health/readiness.types.d.ts → src/health/readiness.types.ts} +4 -8
- package/src/hosting/hosted-service-host.ts +102 -0
- package/src/hosting/hosted-service.ts +31 -0
- package/src/http/http.compression.ts +38 -0
- package/src/http/http.extensions.ts +244 -0
- package/{types/src/http/http.options.store.d.ts → src/http/http.options.store.ts} +11 -1
- package/src/http/http.options.ts +41 -0
- package/{types/src/http/http.security.d.ts → src/http/http.security.ts} +16 -10
- package/src/http/http.static.ts +359 -0
- package/{es6/src/index.js → src/index.ts} +1 -0
- package/src/openapi/index.ts +22 -0
- package/src/openapi/openapi.generator.ts +78 -0
- package/src/openapi/openapi.types.ts +60 -0
- package/src/openapi/request-schema.ts +155 -0
- package/src/openapi/request-validator.ts +95 -0
- package/src/providers/fastify.provider.ts +454 -0
- package/src/routing/anvil.types.ts +150 -0
- package/src/routing/decorators/argument.decorator.ts +33 -0
- package/src/routing/decorators/auth.decorator.ts +79 -0
- package/src/routing/decorators/controller.decorator.ts +9 -0
- package/src/routing/decorators/field.decorator.ts +15 -0
- package/src/routing/decorators/request.decorator.ts +34 -0
- package/src/routing/decorators/response.decorator.ts +18 -0
- package/src/routing/decorators/route.decorator.ts +52 -0
- package/src/routing/filters/exception-filter-host.ts +90 -0
- package/src/routing/filters/exception-filter.ts +29 -0
- package/src/routing/middleware/http-access-log.middleware.ts +36 -0
- package/src/routing/middleware/middleware.ts +26 -0
- package/src/routing/middleware/request-id.ts +18 -0
- package/src/routing/path.util.ts +38 -0
- package/src/routing/pipes/pipes.ts +132 -0
- package/src/routing/services/route-argument-resolver.ts +92 -0
- package/src/routing/services/route-registry.ts +229 -0
- package/src/routing/services/router.ts +166 -0
- package/src/sse/sse.decorator.ts +41 -0
- package/src/sse/sse.encoder.ts +86 -0
- package/src/sse/sse.types.ts +47 -0
- package/src/sse/sse.wire.ts +34 -0
- package/src/testing/boot-module.ts +63 -0
- package/src/testing/sse-reader.ts +120 -0
- package/tests/app.hosted-services.spec.ts +292 -0
- package/tests/app.shutdown.integration.spec.ts +160 -0
- package/tests/app.spec.ts +132 -0
- package/tests/auth.ability.spec.ts +48 -0
- package/tests/auth.decorators.spec.ts +20 -0
- package/tests/auth.fail-closed.pentest.spec.ts +77 -0
- package/tests/auth.integration.spec.ts +234 -0
- package/tests/auth.jwks-cache.spec.ts +52 -0
- package/tests/auth.missing-auth.pentest.spec.ts +56 -0
- package/tests/auth.oidc-ssrf.pentest.spec.ts +72 -0
- package/tests/auth.oidc.integration.spec.ts +161 -0
- package/tests/auth.token-service.spec.ts +251 -0
- package/tests/builder.spec.ts +12 -0
- package/tests/health.integration.spec.ts +111 -0
- package/tests/helpers/listen-ephemeral.ts +13 -0
- package/tests/helpers/local-oidc-server.ts +100 -0
- package/tests/http.access-log.integration.spec.ts +111 -0
- package/tests/http.boolean-query.integration.spec.ts +59 -0
- package/tests/http.compression.integration.spec.ts +604 -0
- package/tests/http.date-query.integration.spec.ts +71 -0
- package/tests/http.global-prefix.integration.spec.ts +284 -0
- package/tests/http.number-query.integration.spec.ts +65 -0
- package/tests/http.pino-roll-hmr.integration.spec.ts +79 -0
- package/tests/http.pipeline-order.integration.spec.ts +95 -0
- package/tests/http.request-cleanup.integration.spec.ts +57 -0
- package/tests/http.request-id-scope.pentest.spec.ts +50 -0
- package/tests/http.security.integration.spec.ts +106 -0
- package/tests/http.static.integration.spec.ts +847 -0
- package/tests/http.static.spec.ts +111 -0
- package/tests/http.surface.integration.spec.ts +167 -0
- package/tests/openapi.integration.spec.ts +193 -0
- package/tests/openapi.validator-cache.integration.spec.ts +55 -0
- package/tests/routing.decorators.spec.ts +15 -0
- package/tests/routing.registry.spec.ts +44 -0
- package/tests/routing.resolver.spec.ts +92 -0
- package/tests/sse.integration.spec.ts +421 -0
- package/tests/sse.wire.spec.ts +33 -0
- package/LICENSE +0 -15
- package/commonjs/src/app/app.js +0 -166
- package/commonjs/src/app/index.js +0 -19
- package/commonjs/src/app/module.js +0 -17
- package/commonjs/src/auth/ability.js +0 -54
- package/commonjs/src/auth/auth.config.js +0 -23
- package/commonjs/src/auth/auth.extensions.js +0 -106
- package/commonjs/src/auth/auth.types.js +0 -65
- package/commonjs/src/auth/casl-authorization.service.js +0 -36
- package/commonjs/src/auth/index.js +0 -23
- package/commonjs/src/auth/principal-provider.js +0 -19
- package/commonjs/src/auth/safe-outbound-url.js +0 -102
- package/commonjs/src/auth/token-service.js +0 -151
- package/commonjs/src/builder/builder.js +0 -95
- package/commonjs/src/builder/index.js +0 -18
- package/commonjs/src/const.js +0 -87
- package/commonjs/src/health/health.controller.js +0 -75
- package/commonjs/src/health/health.extensions.js +0 -50
- package/commonjs/src/health/index.js +0 -21
- package/commonjs/src/health/readiness.service.js +0 -67
- package/commonjs/src/health/readiness.types.js +0 -7
- package/commonjs/src/hosting/hosted-service-host.js +0 -88
- package/commonjs/src/hosting/hosted-service.js +0 -11
- package/commonjs/src/hosting/index.js +0 -19
- package/commonjs/src/http/http.compression.js +0 -27
- package/commonjs/src/http/http.extensions.js +0 -269
- package/commonjs/src/http/http.options.js +0 -26
- package/commonjs/src/http/http.options.store.js +0 -20
- package/commonjs/src/http/http.security.js +0 -27
- package/commonjs/src/http/http.static.js +0 -248
- package/commonjs/src/http/index.js +0 -22
- package/commonjs/src/index.js +0 -27
- package/commonjs/src/openapi/index.js +0 -45
- package/commonjs/src/openapi/openapi.generator.js +0 -103
- package/commonjs/src/openapi/openapi.types.js +0 -4
- package/commonjs/src/openapi/request-schema.js +0 -187
- package/commonjs/src/openapi/request-validator.js +0 -85
- package/commonjs/src/providers/fastify.provider.js +0 -391
- package/commonjs/src/providers/index.js +0 -18
- package/commonjs/src/routing/anvil.types.js +0 -99
- package/commonjs/src/routing/decorators/argument.decorator.js +0 -49
- package/commonjs/src/routing/decorators/auth.decorator.js +0 -70
- package/commonjs/src/routing/decorators/controller.decorator.js +0 -16
- package/commonjs/src/routing/decorators/field.decorator.js +0 -25
- package/commonjs/src/routing/decorators/index.js +0 -24
- package/commonjs/src/routing/decorators/request.decorator.js +0 -30
- package/commonjs/src/routing/decorators/response.decorator.js +0 -34
- package/commonjs/src/routing/decorators/route.decorator.js +0 -67
- package/commonjs/src/routing/filters/exception-filter-host.js +0 -145
- package/commonjs/src/routing/filters/exception-filter.js +0 -28
- package/commonjs/src/routing/index.js +0 -25
- package/commonjs/src/routing/middleware/http-access-log.middleware.js +0 -47
- package/commonjs/src/routing/middleware/middleware.js +0 -20
- package/commonjs/src/routing/middleware/request-id.js +0 -30
- package/commonjs/src/routing/path.util.js +0 -51
- package/commonjs/src/routing/pipes/index.js +0 -18
- package/commonjs/src/routing/pipes/pipes.js +0 -145
- package/commonjs/src/routing/services/index.js +0 -18
- package/commonjs/src/routing/services/route-argument-resolver.js +0 -77
- package/commonjs/src/routing/services/route-registry.js +0 -194
- package/commonjs/src/routing/services/router.js +0 -158
- package/commonjs/src/sse/index.js +0 -26
- package/commonjs/src/sse/sse.decorator.js +0 -42
- package/commonjs/src/sse/sse.encoder.js +0 -73
- package/commonjs/src/sse/sse.types.js +0 -36
- package/commonjs/src/sse/sse.wire.js +0 -40
- package/commonjs/src/testing/boot-module.js +0 -38
- package/commonjs/src/testing/index.js +0 -20
- package/commonjs/src/testing/sse-reader.js +0 -98
- package/es6/src/app/app.js +0 -148
- package/es6/src/app/index.js +0 -2
- package/es6/src/app/module.js +0 -7
- package/es6/src/auth/ability.js +0 -45
- package/es6/src/auth/auth.config.js +0 -19
- package/es6/src/auth/auth.extensions.js +0 -83
- package/es6/src/auth/auth.types.js +0 -35
- package/es6/src/auth/casl-authorization.service.js +0 -40
- package/es6/src/auth/index.js +0 -6
- package/es6/src/auth/principal-provider.js +0 -14
- package/es6/src/auth/safe-outbound-url.js +0 -99
- package/es6/src/auth/token-service.js +0 -141
- package/es6/src/builder/builder.js +0 -85
- package/es6/src/builder/index.js +0 -1
- package/es6/src/health/health.controller.js +0 -65
- package/es6/src/health/health.extensions.js +0 -40
- package/es6/src/health/index.js +0 -4
- package/es6/src/health/readiness.service.js +0 -57
- package/es6/src/health/readiness.types.js +0 -4
- package/es6/src/hosting/hosted-service-host.js +0 -81
- package/es6/src/hosting/hosted-service.js +0 -8
- package/es6/src/hosting/index.js +0 -2
- package/es6/src/http/http.compression.js +0 -9
- package/es6/src/http/http.extensions.js +0 -259
- package/es6/src/http/http.options.js +0 -16
- package/es6/src/http/http.options.store.js +0 -13
- package/es6/src/http/http.security.js +0 -9
- package/es6/src/http/http.static.js +0 -224
- package/es6/src/http/index.js +0 -5
- package/es6/src/openapi/index.js +0 -3
- package/es6/src/openapi/openapi.generator.js +0 -82
- package/es6/src/openapi/openapi.types.js +0 -1
- package/es6/src/openapi/request-schema.js +0 -160
- package/es6/src/openapi/request-validator.js +0 -71
- package/es6/src/providers/fastify.provider.js +0 -376
- package/es6/src/providers/index.js +0 -1
- package/es6/src/routing/anvil.types.js +0 -57
- package/es6/src/routing/decorators/argument.decorator.js +0 -28
- package/es6/src/routing/decorators/auth.decorator.js +0 -58
- package/es6/src/routing/decorators/controller.decorator.js +0 -6
- package/es6/src/routing/decorators/field.decorator.js +0 -15
- package/es6/src/routing/decorators/index.js +0 -7
- package/es6/src/routing/decorators/request.decorator.js +0 -24
- package/es6/src/routing/decorators/response.decorator.js +0 -16
- package/es6/src/routing/decorators/route.decorator.js +0 -37
- package/es6/src/routing/filters/exception-filter-host.js +0 -127
- package/es6/src/routing/filters/exception-filter.js +0 -10
- package/es6/src/routing/index.js +0 -8
- package/es6/src/routing/middleware/http-access-log.middleware.js +0 -37
- package/es6/src/routing/middleware/middleware.js +0 -10
- package/es6/src/routing/middleware/request-id.js +0 -14
- package/es6/src/routing/path.util.js +0 -33
- package/es6/src/routing/pipes/index.js +0 -1
- package/es6/src/routing/pipes/pipes.js +0 -118
- package/es6/src/routing/services/index.js +0 -1
- package/es6/src/routing/services/route-argument-resolver.js +0 -67
- package/es6/src/routing/services/route-registry.js +0 -184
- package/es6/src/routing/services/router.js +0 -148
- package/es6/src/sse/index.js +0 -2
- package/es6/src/sse/sse.decorator.js +0 -31
- package/es6/src/sse/sse.encoder.js +0 -67
- package/es6/src/sse/sse.types.js +0 -22
- package/es6/src/sse/sse.wire.js +0 -30
- package/es6/src/testing/boot-module.js +0 -35
- package/es6/src/testing/index.js +0 -2
- package/es6/src/testing/sse-reader.js +0 -91
- package/types/src/app/app.d.ts +0 -41
- package/types/src/app/module.d.ts +0 -15
- package/types/src/auth/ability.d.ts +0 -19
- package/types/src/auth/auth.config.d.ts +0 -28
- package/types/src/auth/auth.extensions.d.ts +0 -53
- package/types/src/auth/auth.types.d.ts +0 -73
- package/types/src/auth/casl-authorization.service.d.ts +0 -28
- package/types/src/auth/safe-outbound-url.d.ts +0 -9
- package/types/src/auth/token-service.d.ts +0 -31
- package/types/src/builder/builder.d.ts +0 -36
- package/types/src/const.d.ts +0 -32
- package/types/src/health/health.controller.d.ts +0 -16
- package/types/src/health/health.extensions.d.ts +0 -31
- package/types/src/health/readiness.service.d.ts +0 -9
- package/types/src/hosting/hosted-service-host.d.ts +0 -37
- package/types/src/hosting/hosted-service.d.ts +0 -31
- package/types/src/http/http.compression.d.ts +0 -32
- package/types/src/http/http.extensions.d.ts +0 -79
- package/types/src/http/http.options.d.ts +0 -39
- package/types/src/http/http.static.d.ts +0 -160
- package/types/src/index.d.ts +0 -10
- package/types/src/openapi/index.d.ts +0 -6
- package/types/src/openapi/openapi.generator.d.ts +0 -6
- package/types/src/openapi/openapi.types.d.ts +0 -58
- package/types/src/openapi/request-schema.d.ts +0 -21
- package/types/src/openapi/request-validator.d.ts +0 -9
- package/types/src/providers/fastify.provider.d.ts +0 -56
- package/types/src/routing/anvil.types.d.ts +0 -119
- package/types/src/routing/decorators/argument.decorator.d.ts +0 -11
- package/types/src/routing/decorators/auth.decorator.d.ts +0 -30
- package/types/src/routing/decorators/controller.decorator.d.ts +0 -3
- package/types/src/routing/decorators/field.decorator.d.ts +0 -2
- package/types/src/routing/decorators/request.decorator.d.ts +0 -8
- package/types/src/routing/decorators/response.decorator.d.ts +0 -4
- package/types/src/routing/decorators/route.decorator.d.ts +0 -7
- package/types/src/routing/filters/exception-filter-host.d.ts +0 -19
- package/types/src/routing/filters/exception-filter.d.ts +0 -16
- package/types/src/routing/middleware/http-access-log.middleware.d.ts +0 -8
- package/types/src/routing/middleware/middleware.d.ts +0 -10
- package/types/src/routing/middleware/request-id.d.ts +0 -6
- package/types/src/routing/path.util.d.ts +0 -9
- package/types/src/routing/pipes/pipes.d.ts +0 -21
- package/types/src/routing/services/route-argument-resolver.d.ts +0 -10
- package/types/src/routing/services/route-registry.d.ts +0 -20
- package/types/src/routing/services/router.d.ts +0 -22
- package/types/src/sse/sse.decorator.d.ts +0 -17
- package/types/src/sse/sse.encoder.d.ts +0 -16
- package/types/src/sse/sse.types.d.ts +0 -37
- package/types/src/sse/sse.wire.d.ts +0 -9
- package/types/src/testing/boot-module.d.ts +0 -34
- package/types/src/testing/sse-reader.d.ts +0 -29
- /package/{types/src/app/index.d.ts → src/app/index.ts} +0 -0
- /package/{types/src/auth/index.d.ts → src/auth/index.ts} +0 -0
- /package/{types/src/builder/index.d.ts → src/builder/index.ts} +0 -0
- /package/{types/src/health/index.d.ts → src/health/index.ts} +0 -0
- /package/{types/src/hosting/index.d.ts → src/hosting/index.ts} +0 -0
- /package/{types/src/http/index.d.ts → src/http/index.ts} +0 -0
- /package/{types/src/providers/index.d.ts → src/providers/index.ts} +0 -0
- /package/{types/src/routing/decorators/index.d.ts → src/routing/decorators/index.ts} +0 -0
- /package/{types/src/routing/index.d.ts → src/routing/index.ts} +0 -0
- /package/{types/src/routing/pipes/index.d.ts → src/routing/pipes/index.ts} +0 -0
- /package/{types/src/routing/services/index.d.ts → src/routing/services/index.ts} +0 -0
- /package/{types/src/sse/index.d.ts → src/sse/index.ts} +0 -0
- /package/{types/src/testing/index.d.ts → src/testing/index.ts} +0 -0
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Principal } from "./auth.types.js";
|
|
2
|
-
/** Root role — expands to CASL `manage`/`all` (covers every future ability). */
|
|
3
|
-
export declare const ADMIN_ROLE = "admin";
|
|
4
|
-
/**
|
|
5
|
-
* Default CASL ability factory.
|
|
6
|
-
*
|
|
7
|
-
* - `admin` role → `manage` / `all` (wildcard)
|
|
8
|
-
* - otherwise map `principal.scopes` of the form `"action:Subject"` to CASL rules
|
|
9
|
-
*
|
|
10
|
-
* Pass a custom factory to `withAuth()` (or override the app stub) for product-specific rules.
|
|
11
|
-
*/
|
|
12
|
-
export declare function defineAbilitiesFor(principal: Principal): import("@casl/ability").MongoAbility<import("@casl/ability").AbilityTuple, import("@casl/ability").MongoQuery>;
|
|
13
|
-
/**
|
|
14
|
-
* Map a raw JWT payload → {@link Principal}.
|
|
15
|
-
*
|
|
16
|
-
* Merges OAuth `scope` / `scopes` with an IdP `permissions` claim (e.g. Auth0 API permissions).
|
|
17
|
-
* Override via `withAuth(..., { principalMapper })` when claims differ.
|
|
18
|
-
*/
|
|
19
|
-
export declare function createPrincipalFromPayload(payload: Record<string, unknown>): Principal;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { Principal } from "./auth.types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Configuration for the TokenService, read from the `auth` section of the
|
|
4
|
-
* application config file. Exactly one of the discriminant fields must be set.
|
|
5
|
-
*
|
|
6
|
-
* Production → use `jwksUrl`, `publicKey`, or `secret`.
|
|
7
|
-
* Development → use `devStatic` (only works when NODE_ENV=development).
|
|
8
|
-
*/
|
|
9
|
-
export declare class AuthConfig {
|
|
10
|
-
/** OIDC discovery URL — the issuer base URL, e.g. https://accounts.google.com.
|
|
11
|
-
* The framework appends `/.well-known/openid-configuration` automatically.
|
|
12
|
-
* Use this instead of `jwksUrl` for any standard OIDC-compliant IdP.
|
|
13
|
-
*/
|
|
14
|
-
discoveryUrl?: string;
|
|
15
|
-
/** JWKS endpoint URL (RS256 / ES256 via remote key set). */
|
|
16
|
-
jwksUrl?: string;
|
|
17
|
-
/** PEM-encoded public key or JWK JSON string (RS256 / ES256 static key). */
|
|
18
|
-
publicKey?: string;
|
|
19
|
-
algorithms?: string[];
|
|
20
|
-
/** Shared secret for HS256. */
|
|
21
|
-
secret?: string;
|
|
22
|
-
/** Issuer claim to validate (all non-devStatic variants). */
|
|
23
|
-
issuer?: string;
|
|
24
|
-
/** Audience claim to validate (all non-devStatic variants). */
|
|
25
|
-
audience?: string;
|
|
26
|
-
/** Static principal injected for every request (development only). */
|
|
27
|
-
devStatic?: Principal;
|
|
28
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Builder } from "../builder/builder.js";
|
|
2
|
-
import type { PrincipalMapper } from "./auth.types.js";
|
|
3
|
-
import type { AbilityFactory } from "./casl-authorization.service.js";
|
|
4
|
-
export { ADMIN_ROLE, createPrincipalFromPayload, defineAbilitiesFor } from "./ability.js";
|
|
5
|
-
export type WithAuthOptions = {
|
|
6
|
-
/**
|
|
7
|
-
* Override the default JWT payload → Principal mapping.
|
|
8
|
-
* Use this when your IdP stores roles or scopes in non-standard claims.
|
|
9
|
-
*
|
|
10
|
-
* @example Keycloak realm roles:
|
|
11
|
-
* ```ts
|
|
12
|
-
* builder.withAuth(factory, {
|
|
13
|
-
* principalMapper: (p) => ({
|
|
14
|
-
* sub: p.sub as string,
|
|
15
|
-
* scopes: (p.realm_access as any)?.roles?.map((r: string) => `manage:${r}`) ?? [],
|
|
16
|
-
* }),
|
|
17
|
-
* });
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
principalMapper?: PrincipalMapper;
|
|
21
|
-
};
|
|
22
|
-
declare module "@decohere/http" {
|
|
23
|
-
interface Builder {
|
|
24
|
-
/**
|
|
25
|
-
* Configure JWT authentication from the `auth` config section and wire
|
|
26
|
-
* up a CASL authorization service.
|
|
27
|
-
*
|
|
28
|
-
* By default, `defineAbilitiesFor` grants `manage`/`all` for the `admin`
|
|
29
|
-
* role and maps `principal.scopes` of the form `"action:Subject"` to CASL
|
|
30
|
-
* rules. Pass a custom `abilityFactory` to override that behaviour.
|
|
31
|
-
*
|
|
32
|
-
* Requires `.withConfiguration(...)` to be called on the builder.
|
|
33
|
-
*
|
|
34
|
-
* @example Default (scope-based, no boilerplate):
|
|
35
|
-
* ```ts
|
|
36
|
-
* builder.withConfiguration(YamlDataSource).withAuth();
|
|
37
|
-
* ```
|
|
38
|
-
*
|
|
39
|
-
* @example Custom override:
|
|
40
|
-
* ```ts
|
|
41
|
-
* builder.withAuth((principal) => {
|
|
42
|
-
* const { can, build } = new AbilityBuilder(createMongoAbility);
|
|
43
|
-
* // custom logic ...
|
|
44
|
-
* return build();
|
|
45
|
-
* });
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
|
-
withAuth(abilityFactory?: AbilityFactory, options?: WithAuthOptions): Builder;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
export declare class BuilderExtensions {
|
|
52
|
-
static withAuth(builder: Builder, abilityFactory?: AbilityFactory, options?: WithAuthOptions): Builder<import("@decohere/http").App>;
|
|
53
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
export type Principal = {
|
|
2
|
-
sub: string;
|
|
3
|
-
roles?: string[];
|
|
4
|
-
scopes?: string[];
|
|
5
|
-
[key: string]: unknown;
|
|
6
|
-
};
|
|
7
|
-
/** Maps a raw JWT payload to a Principal. Override the default via withAuth() options. */
|
|
8
|
-
export type PrincipalMapper = (payload: Record<string, unknown>) => Principal;
|
|
9
|
-
export type JwksConfig = {
|
|
10
|
-
jwksUrl: string;
|
|
11
|
-
issuer?: string;
|
|
12
|
-
/** Required — empty/undefined disables jose `aud` checks (cross-API token accept). */
|
|
13
|
-
audience: string;
|
|
14
|
-
};
|
|
15
|
-
export type PublicKeyConfig = {
|
|
16
|
-
publicKey: string;
|
|
17
|
-
algorithms?: string[];
|
|
18
|
-
issuer?: string;
|
|
19
|
-
/** Required — empty/undefined disables jose `aud` checks (cross-API token accept). */
|
|
20
|
-
audience: string;
|
|
21
|
-
};
|
|
22
|
-
export type SecretConfig = {
|
|
23
|
-
secret: string;
|
|
24
|
-
issuer?: string;
|
|
25
|
-
/** Required — empty/undefined disables jose `aud` checks (cross-API token accept). */
|
|
26
|
-
audience: string;
|
|
27
|
-
};
|
|
28
|
-
export type DevStaticConfig = {
|
|
29
|
-
devStatic: Principal;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Resolve IdP configuration automatically from an OIDC discovery endpoint
|
|
33
|
-
* (`{discoveryUrl}/.well-known/openid-configuration`). The `discoveryUrl` is
|
|
34
|
-
* also used as the expected `iss` claim unless the discovery document provides
|
|
35
|
-
* a different value.
|
|
36
|
-
*/
|
|
37
|
-
export type DiscoveryConfig = {
|
|
38
|
-
discoveryUrl: string;
|
|
39
|
-
/** Required — empty/undefined disables jose `aud` checks (cross-API token accept). */
|
|
40
|
-
audience: string;
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Framework-agnostic authorization service. Implement this interface (e.g.
|
|
44
|
-
* via CaslAuthorizationService) and register it under AuthorizationServiceToken.
|
|
45
|
-
* Throw ForbiddenError to deny access.
|
|
46
|
-
*/
|
|
47
|
-
export interface IAuthorizationService {
|
|
48
|
-
authorizeRequest(request: import("../routing/anvil.types.js").HttpRequest, action: string, subject: string): Promise<Principal>;
|
|
49
|
-
/**
|
|
50
|
-
* Verify the request has a valid principal without checking a CASL ability.
|
|
51
|
-
* Used when auth is enabled but the route has no `@Authorize` metadata.
|
|
52
|
-
*/
|
|
53
|
-
authenticateRequest(request: import("../routing/anvil.types.js").HttpRequest): Promise<Principal>;
|
|
54
|
-
authorize(principal: Principal, action: string, subject: string): Promise<void>;
|
|
55
|
-
}
|
|
56
|
-
export type TokenServiceConfig = JwksConfig | PublicKeyConfig | SecretConfig | DevStaticConfig | DiscoveryConfig;
|
|
57
|
-
export declare function isDiscoveryConfig(config: TokenServiceConfig): config is DiscoveryConfig;
|
|
58
|
-
export declare function isDevStaticConfig(config: TokenServiceConfig): config is DevStaticConfig;
|
|
59
|
-
export declare function isJwksConfig(config: TokenServiceConfig): config is JwksConfig;
|
|
60
|
-
export declare function isPublicKeyConfig(config: TokenServiceConfig): config is PublicKeyConfig;
|
|
61
|
-
export declare function isSecretConfig(config: TokenServiceConfig): config is SecretConfig;
|
|
62
|
-
/** `devStatic` is only valid for local development NODE_ENV values. */
|
|
63
|
-
export declare function isDevelopmentNodeEnv(nodeEnv?: string): boolean;
|
|
64
|
-
/**
|
|
65
|
-
* Refuse `devStatic` outside development — otherwise any Bearer string is
|
|
66
|
-
* accepted as the configured principal (auth bypass in production).
|
|
67
|
-
*/
|
|
68
|
-
export declare function assertDevStaticAllowed(nodeEnv?: string): void;
|
|
69
|
-
/**
|
|
70
|
-
* jose skips `aud` validation when `audience` is undefined or "". Require a
|
|
71
|
-
* non-empty audience for every non-devStatic verification strategy.
|
|
72
|
-
*/
|
|
73
|
-
export declare function assertNonEmptyAudience(audience: string | undefined): asserts audience is string;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { AnyAbility } from "@casl/ability";
|
|
2
|
-
import type { HttpRequest } from "../routing/anvil.types.js";
|
|
3
|
-
import type { IAuthorizationService, Principal } from "./auth.types.js";
|
|
4
|
-
import type { TokenService } from "./token-service.js";
|
|
5
|
-
export type AbilityFactory = (principal: Principal) => AnyAbility;
|
|
6
|
-
/**
|
|
7
|
-
* IAuthorizationService implementation backed by CASL.
|
|
8
|
-
*
|
|
9
|
-
* Register it under AuthorizationServiceToken:
|
|
10
|
-
* ```ts
|
|
11
|
-
* builder.withServices((c) =>
|
|
12
|
-
* c.registerSingleton(AuthorizationServiceToken, new CaslAuthorizationService((principal) => {
|
|
13
|
-
* const { can, build } = new AbilityBuilder(createMongoAbility);
|
|
14
|
-
* if (principal.roles?.includes("admin")) can("manage", "all");
|
|
15
|
-
* else can("read", "Post");
|
|
16
|
-
* return build();
|
|
17
|
-
* }))
|
|
18
|
-
* );
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
export declare class CaslAuthorizationService implements IAuthorizationService {
|
|
22
|
-
private readonly factory;
|
|
23
|
-
private readonly tokenService?;
|
|
24
|
-
constructor(factory: AbilityFactory, tokenService?: TokenService);
|
|
25
|
-
authorizeRequest(request: HttpRequest, action: string, subject: string): Promise<Principal>;
|
|
26
|
-
authenticateRequest(request: HttpRequest): Promise<Principal>;
|
|
27
|
-
authorize(principal: Principal, action: string, subject: string): Promise<void>;
|
|
28
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validate URLs used for OIDC discovery / JWKS fetches to reduce SSRF risk.
|
|
3
|
-
*
|
|
4
|
-
* - http(s) only; https required except loopback (local IdP tests)
|
|
5
|
-
* - no credentials in the URL
|
|
6
|
-
* - hostname must not resolve to private, link-local, or metadata ranges
|
|
7
|
-
* (loopback allowed only when NODE_ENV is development/dev/test)
|
|
8
|
-
*/
|
|
9
|
-
export declare function assertSafeOutboundUrl(raw: string, label: string): Promise<URL>;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { type JWTPayload } from "jose";
|
|
2
|
-
import type { HttpRequest } from "../routing/anvil.types.js";
|
|
3
|
-
import type { Principal, PrincipalMapper, TokenServiceConfig } from "./auth.types.js";
|
|
4
|
-
export declare class TokenService {
|
|
5
|
-
private readonly config;
|
|
6
|
-
private readonly principalMapper?;
|
|
7
|
-
/** Lazily resolved JWKS set when using OIDC discovery. */
|
|
8
|
-
private discoveryJwks?;
|
|
9
|
-
private discoveryIssuer?;
|
|
10
|
-
/** Remote key set for `jwksUrl` mode, created once so jose can cache the keys. */
|
|
11
|
-
private configuredJwks?;
|
|
12
|
-
constructor(config: TokenServiceConfig, principalMapper?: PrincipalMapper);
|
|
13
|
-
verifyRequest(request: HttpRequest): Promise<Principal>;
|
|
14
|
-
verify(credentials: string): Promise<Principal>;
|
|
15
|
-
/**
|
|
16
|
-
* Resolve how to verify tokens for the configured strategy:
|
|
17
|
-
* - OIDC discovery → fetch JWKS + issuer from `/.well-known/openid-configuration`
|
|
18
|
-
* - explicit JWKS URL → remote key set + configured issuer/audience
|
|
19
|
-
* - public key / shared secret → static key material + configured issuer/audience
|
|
20
|
-
*/
|
|
21
|
-
private resolveVerificationContext;
|
|
22
|
-
private resolveOidcDiscovery;
|
|
23
|
-
/**
|
|
24
|
-
* Sign a payload and return a JWT string.
|
|
25
|
-
* Only available when configured with a SecretConfig (HS256).
|
|
26
|
-
* For RS256/ES256 issuance, the caller is responsible for key management.
|
|
27
|
-
*/
|
|
28
|
-
sign(payload: Omit<JWTPayload, "iss" | "aud"> & Record<string, unknown>, expiresIn?: string): Promise<string>;
|
|
29
|
-
private getStaticKey;
|
|
30
|
-
private mapPrincipal;
|
|
31
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { type ContainerBuilder, ServiceContainerBuilder, type IContainer } from "@decohere/crucible";
|
|
2
|
-
import { type IConfigurationService } from "@decohere/core/configuration";
|
|
3
|
-
import type { Constructable } from "@decohere/core/reflection";
|
|
4
|
-
import { App } from "../app/app.js";
|
|
5
|
-
import type { HostedService } from "../hosting/hosted-service.js";
|
|
6
|
-
export type BuilderOptions = {
|
|
7
|
-
containerBuilder?: ServiceContainerBuilder;
|
|
8
|
-
applicationName?: string;
|
|
9
|
-
};
|
|
10
|
-
export declare class Builder<T extends App = App> {
|
|
11
|
-
static create<T extends App = App>(options?: BuilderOptions): Builder<T>;
|
|
12
|
-
readonly containerBuilder: ServiceContainerBuilder;
|
|
13
|
-
readonly applicationName?: string;
|
|
14
|
-
private readonly logger;
|
|
15
|
-
private userServices;
|
|
16
|
-
private preBuildSteps;
|
|
17
|
-
private postBuildSteps;
|
|
18
|
-
private readonly hostedServices;
|
|
19
|
-
constructor(options?: BuilderOptions);
|
|
20
|
-
withServices(userServices: (containerBuilder: ContainerBuilder) => void): Builder<T>;
|
|
21
|
-
/**
|
|
22
|
-
* Run {@link HostedService}s for the life of the app: started in this order before the HTTP
|
|
23
|
-
* server listens, stopped in reverse when the app stops (including SIGTERM and Flux reboots).
|
|
24
|
-
* Each is registered as a singleton, so other services can inject it by its class.
|
|
25
|
-
*/
|
|
26
|
-
withHostedService(...types: Constructable<HostedService>[]): Builder<T>;
|
|
27
|
-
registerPreBuildStep(step: (config: IConfigurationService, containerBuilder: ContainerBuilder) => Promise<void> | void): void;
|
|
28
|
-
registerPostBuildStep(step: (container: IContainer) => Promise<void> | void): void;
|
|
29
|
-
buildAndStart<T extends App>(type?: Constructable<T>): Promise<T | App>;
|
|
30
|
-
build<T extends App = App>(type?: Constructable<T>): Promise<T | App>;
|
|
31
|
-
private configureUserServices;
|
|
32
|
-
private runPreBuildSteps;
|
|
33
|
-
private runPostBuildSteps;
|
|
34
|
-
private configureApp;
|
|
35
|
-
private resolveApp;
|
|
36
|
-
}
|
package/types/src/const.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export declare const RouteRegistryToken: unique symbol;
|
|
2
|
-
export declare const HttpProviderToken: unique symbol;
|
|
3
|
-
export declare const RouterToken: unique symbol;
|
|
4
|
-
export declare const PrincipalToken: unique symbol;
|
|
5
|
-
export declare const IPrincipalProviderToken: unique symbol;
|
|
6
|
-
export declare const TokenServiceToken: unique symbol;
|
|
7
|
-
export declare const AuthorizationServiceToken: unique symbol;
|
|
8
|
-
export declare const HttpOptionsToken: unique symbol;
|
|
9
|
-
export declare const ExceptionFilterHostToken: unique symbol;
|
|
10
|
-
export declare const ReadinessCheckToken: unique symbol;
|
|
11
|
-
export declare const ReadinessServiceToken: unique symbol;
|
|
12
|
-
export declare const HostedServiceHostToken: unique symbol;
|
|
13
|
-
export type HTTPMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
|
|
14
|
-
export declare const HTTPMethods: {
|
|
15
|
-
GET: "GET";
|
|
16
|
-
PUT: "PUT";
|
|
17
|
-
POST: "POST";
|
|
18
|
-
PATCH: "PATCH";
|
|
19
|
-
DELETE: "DELETE";
|
|
20
|
-
};
|
|
21
|
-
export declare const MetadataKeys: {
|
|
22
|
-
controller: string;
|
|
23
|
-
route: string;
|
|
24
|
-
parameter: string;
|
|
25
|
-
fieldMap: string;
|
|
26
|
-
authorize: string;
|
|
27
|
-
allowAnonymous: string;
|
|
28
|
-
httpCode: string;
|
|
29
|
-
headers: string;
|
|
30
|
-
catch: string;
|
|
31
|
-
sse: string;
|
|
32
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ReadinessService } from "./readiness.service.js";
|
|
2
|
-
/**
|
|
3
|
-
* Liveness (`/health`) and readiness (`/ready`) probes.
|
|
4
|
-
* Both are anonymous so orchestration can scrape them with auth enabled, and stay at the root
|
|
5
|
-
* under a global prefix, where platforms look for them.
|
|
6
|
-
*/
|
|
7
|
-
export declare class HealthController {
|
|
8
|
-
private readonly readiness;
|
|
9
|
-
constructor(readiness: ReadinessService);
|
|
10
|
-
health(): {
|
|
11
|
-
status: string;
|
|
12
|
-
};
|
|
13
|
-
ready(): Promise<{
|
|
14
|
-
status: string;
|
|
15
|
-
}>;
|
|
16
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Builder } from "../builder/builder.js";
|
|
2
|
-
import "../http/http.extensions.js";
|
|
3
|
-
import type { IReadinessCheck } from "./readiness.types.js";
|
|
4
|
-
export type WithHealthOptions = {
|
|
5
|
-
/** Extra readiness probes (e.g. custom dependency checks). */
|
|
6
|
-
checks?: IReadinessCheck[];
|
|
7
|
-
/**
|
|
8
|
-
* Serve the probes under the global prefix (`/api/health`) instead of at the root. Default
|
|
9
|
-
* `false`: Cloud Run, Kubernetes and most load balancers probe the root.
|
|
10
|
-
*/
|
|
11
|
-
underGlobalPrefix?: boolean;
|
|
12
|
-
};
|
|
13
|
-
declare module "@decohere/http" {
|
|
14
|
-
interface Builder {
|
|
15
|
-
/**
|
|
16
|
-
* Register anonymous `/health` (liveness) and `/ready` (readiness) routes.
|
|
17
|
-
*
|
|
18
|
-
* Readiness runs every {@link IReadinessCheck} registered under
|
|
19
|
-
* {@link ReadinessCheckToken} (TypeORM registers one per datasource when
|
|
20
|
-
* `.withTypeOrm()` is used). Pass `checks` for app-specific probes.
|
|
21
|
-
*
|
|
22
|
-
* The probes stay at the root under `withGlobalPrefix`, unless `underGlobalPrefix` is set.
|
|
23
|
-
*
|
|
24
|
-
* Requires `.withHttpProvider(...)` (or `@decohere/http/http` side-effect).
|
|
25
|
-
*/
|
|
26
|
-
withHealth(options?: WithHealthOptions): Builder;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
export declare class BuilderExtensions {
|
|
30
|
-
static withHealth(builder: Builder, options?: WithHealthOptions): Builder<import("@decohere/http").App>;
|
|
31
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { HostedServiceHost } from "../hosting/hosted-service-host.js";
|
|
2
|
-
import type { IReadinessCheck, ReadinessResult } from "./readiness.types.js";
|
|
3
|
-
export declare class ReadinessService {
|
|
4
|
-
private readonly hostedServices?;
|
|
5
|
-
private readonly checks;
|
|
6
|
-
constructor(checks?: IReadinessCheck[], hostedServices?: HostedServiceHost);
|
|
7
|
-
/** Registered checks, then each started hosted service that has a `check()` (still warming up). */
|
|
8
|
-
checkAll(): Promise<ReadinessResult>;
|
|
9
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { IContainer } from "@decohere/crucible";
|
|
2
|
-
import type { Constructable } from "@decohere/core/reflection";
|
|
3
|
-
import type { IReadinessCheck } from "../health/readiness.types.js";
|
|
4
|
-
import type { HostedService } from "./hosted-service.js";
|
|
5
|
-
/**
|
|
6
|
-
* Starts and stops the app's {@link HostedService}s. One per app; `Builder.withHostedService`
|
|
7
|
-
* adds the types and `App` drives it.
|
|
8
|
-
*/
|
|
9
|
-
export declare class HostedServiceHost {
|
|
10
|
-
private readonly logger;
|
|
11
|
-
private readonly types;
|
|
12
|
-
private readonly controller;
|
|
13
|
-
/** In start order; stopped in reverse. */
|
|
14
|
-
private readonly started;
|
|
15
|
-
private starting;
|
|
16
|
-
private stopping;
|
|
17
|
-
add(...types: Constructable<HostedService>[]): void;
|
|
18
|
-
get isEmpty(): boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Start every service in registration order. If one throws, the ones already started are
|
|
21
|
-
* stopped and the error is rethrown. Stops launching more once {@link stop} has begun.
|
|
22
|
-
*/
|
|
23
|
-
start(container: IContainer): Promise<void>;
|
|
24
|
-
/** Abort the services' signal: background work should wind down. {@link stop} does this too. */
|
|
25
|
-
abort(): void;
|
|
26
|
-
/**
|
|
27
|
-
* Abort the signal, wait for a start still in progress, then stop the started services in
|
|
28
|
-
* reverse order. Every `stop()` runs even if one throws; the failures are rethrown after.
|
|
29
|
-
*/
|
|
30
|
-
stop(): Promise<void>;
|
|
31
|
-
/** The started services that report readiness, for `GET /ready`. */
|
|
32
|
-
readinessChecks(): IReadinessCheck[];
|
|
33
|
-
private startAll;
|
|
34
|
-
private stopAll;
|
|
35
|
-
/** Stop what is started, newest first. Takes each service off the list, so it runs once. */
|
|
36
|
-
private stopStarted;
|
|
37
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Work that runs for the life of the app outside a request: a feed, a poller, a queue consumer.
|
|
3
|
-
* Register it with `builder.withHostedService(Type)`; it is a singleton, so other services can
|
|
4
|
-
* inject it by its class.
|
|
5
|
-
*
|
|
6
|
-
* The app starts hosted services in registration order before the HTTP server listens, and stops
|
|
7
|
-
* them in reverse order when it stops (`app.dispose()`, SIGTERM or SIGINT, a Flux reboot).
|
|
8
|
-
*/
|
|
9
|
-
export interface HostedService {
|
|
10
|
-
/**
|
|
11
|
-
* Called once when the app starts, and awaited: a throw fails `app.start()`. Do what must be
|
|
12
|
-
* ready before traffic, then start long work (a first load that takes minutes, a timer) in
|
|
13
|
-
* the background and return. Waiting for it here keeps the HTTP server dark.
|
|
14
|
-
*
|
|
15
|
-
* `signal` is aborted as soon as the app starts stopping, before `stop()` is called, also
|
|
16
|
-
* while `start()` itself is still running. Stop background work and clear timers on it.
|
|
17
|
-
*/
|
|
18
|
-
start(signal: AbortSignal): Promise<void> | void;
|
|
19
|
-
/**
|
|
20
|
-
* Called once when the app stops, after the HTTP server has drained and before the container
|
|
21
|
-
* is disposed, so the services it uses (a DataSource) are still open. Wait here for the
|
|
22
|
-
* background work to finish. Optional: a service with nothing to wait for can rely on the
|
|
23
|
-
* signal, or on `Symbol.asyncDispose`, which the container calls later.
|
|
24
|
-
*/
|
|
25
|
-
stop?(): Promise<void> | void;
|
|
26
|
-
/**
|
|
27
|
-
* Readiness while the service is started but still warming up: throw until it can serve, and
|
|
28
|
-
* `GET /ready` answers 503 (`withHealth()`). Optional.
|
|
29
|
-
*/
|
|
30
|
-
check?(): Promise<void>;
|
|
31
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Response compression (`builder.withCompression`). Provider-neutral options and defaults;
|
|
3
|
-
* the HTTP provider hands them to its compression plugin and the plugin owns the policy
|
|
4
|
-
* (which responses are compressed, `Vary`, `HEAD`, streams). See ADR 0008.
|
|
5
|
-
*/
|
|
6
|
-
/** A content coding the HTTP package can offer. */
|
|
7
|
-
export type CompressionEncoding = "br" | "gzip" | "deflate";
|
|
8
|
-
/** Bodies smaller than this many bytes are sent as they are (not applied to streams, such as files). */
|
|
9
|
-
export declare const DEFAULT_COMPRESSION_THRESHOLD = 1024;
|
|
10
|
-
/** The codings offered by default, in order of preference. `deflate` is left out on purpose. */
|
|
11
|
-
export declare const DEFAULT_COMPRESSION_ENCODINGS: readonly CompressionEncoding[];
|
|
12
|
-
/** Options for {@link Builder.withCompression}. `false` turns compression off. */
|
|
13
|
-
export type CompressionOptions = false | {
|
|
14
|
-
/** Smallest body, in bytes, that is compressed. Defaults to 1024. Not applied to streamed bodies. */
|
|
15
|
-
threshold?: number;
|
|
16
|
-
/** The codings to offer, in order of preference. Defaults to `["br", "gzip"]`. */
|
|
17
|
-
encodings?: CompressionEncoding[];
|
|
18
|
-
/**
|
|
19
|
-
* Content types to compress, tested against the `Content-Type` header. Passed to the
|
|
20
|
-
* plugin as `customTypes`: it replaces the plugin's default pattern (text, JSON, XML,
|
|
21
|
-
* `octet-stream`; never `text/event-stream`) and anything the MIME database marks
|
|
22
|
-
* compressible is still compressed. Use it to add a type; do not match
|
|
23
|
-
* `text/event-stream` unless you want streams buffered.
|
|
24
|
-
*/
|
|
25
|
-
types?: RegExp | ((contentType: string) => boolean);
|
|
26
|
-
/**
|
|
27
|
-
* Fastify-specific. Any other `@fastify/compress` option (`brotliOptions`, `zlibOptions`,
|
|
28
|
-
* `onUnsupportedEncoding`, `inflateIfDeflated`, ...), merged last so it overrides the
|
|
29
|
-
* values above. Not portable to another HTTP provider.
|
|
30
|
-
*/
|
|
31
|
-
providerOptions?: Record<string, unknown>;
|
|
32
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { Constructable } from "@decohere/core/reflection";
|
|
2
|
-
import { Builder } from "../builder/builder.js";
|
|
3
|
-
import type { OpenApiOptions } from "../openapi/openapi.types.js";
|
|
4
|
-
import type { CorsOptions, HttpProvider } from "../routing/anvil.types.js";
|
|
5
|
-
import type { ExceptionFilter } from "../routing/filters/exception-filter.js";
|
|
6
|
-
import type { Middleware } from "../routing/middleware/middleware.js";
|
|
7
|
-
import type { WithHttpOptions } from "./http.options.js";
|
|
8
|
-
import type { CompressionOptions } from "./http.compression.js";
|
|
9
|
-
import type { HelmetOptions, RateLimitOptions } from "./http.security.js";
|
|
10
|
-
import { type StaticOptions } from "./http.static.js";
|
|
11
|
-
declare module "@decohere/http" {
|
|
12
|
-
interface Builder {
|
|
13
|
-
withHttpProvider<Thttp extends Constructable<HttpProvider>>(type: Thttp): Builder;
|
|
14
|
-
/**
|
|
15
|
-
* HTTP provider plus scaffold defaults (request id + Scribe access log).
|
|
16
|
-
* Prefer this over {@link Builder.withHttpProvider} for application entrypoints.
|
|
17
|
-
*/
|
|
18
|
-
withHttp<Thttp extends Constructable<HttpProvider>>(type: Thttp, options?: WithHttpOptions): Builder;
|
|
19
|
-
withControllers(...controllers: Constructable[]): Builder;
|
|
20
|
-
/**
|
|
21
|
-
* Prefix every controller route (`/api` makes `/lp/portfolio` into `/api/lp/portfolio`).
|
|
22
|
-
* It covers controller routes only: not static mounts (`withStatic`), not the OpenAPI
|
|
23
|
-
* document, and not a controller declared with `@Controller({ globalPrefix: false })`,
|
|
24
|
-
* such as the `withHealth()` probes, which platforms expect at the root. With a prefix
|
|
25
|
-
* set, the static fallback treats everything under it as the API.
|
|
26
|
-
*/
|
|
27
|
-
withGlobalPrefix(prefix: string): Builder;
|
|
28
|
-
withCors(options: CorsOptions): Builder;
|
|
29
|
-
/**
|
|
30
|
-
* Override or disable default `@fastify/helmet` headers.
|
|
31
|
-
* Defaults are on with `withHttpProvider`; pass `false` to disable.
|
|
32
|
-
*/
|
|
33
|
-
withHelmet(options?: HelmetOptions): Builder;
|
|
34
|
-
/**
|
|
35
|
-
* Override or disable default `@fastify/rate-limit` (100 req / 1 minute).
|
|
36
|
-
* Pass `false` to disable.
|
|
37
|
-
*/
|
|
38
|
-
withRateLimit(options?: RateLimitOptions): Builder;
|
|
39
|
-
/**
|
|
40
|
-
* Compress responses with `br` or `gzip` when the client accepts it, using `@fastify/compress`
|
|
41
|
-
* with best-practice defaults (on by default, 1 KB threshold, no `deflate`). Pass `false` to
|
|
42
|
-
* turn it off, or `{ threshold, encodings, types, providerOptions }` to override. The plugin
|
|
43
|
-
* does not compress `text/event-stream` by default. Compressing a response that mixes a secret
|
|
44
|
-
* with input an attacker controls can leak the secret over HTTPS (BREACH); see ADR 0008.
|
|
45
|
-
*/
|
|
46
|
-
withCompression(options?: CompressionOptions): Builder;
|
|
47
|
-
/**
|
|
48
|
-
* Override the default request body size limit (1 MiB).
|
|
49
|
-
*/
|
|
50
|
-
withBodyLimit(bytes: number): Builder;
|
|
51
|
-
withMiddleware(...middlewares: Constructable<Middleware>[]): Builder;
|
|
52
|
-
withExceptionFilters(...filters: Constructable<ExceptionFilter>[]): Builder;
|
|
53
|
-
withOpenApi(options: OpenApiOptions): Builder;
|
|
54
|
-
/**
|
|
55
|
-
* Serve a built UI (a folder of static files) from this API, for example
|
|
56
|
-
* `.withStatic("/ui/", "ui")`. The directory is resolved from the process working
|
|
57
|
-
* directory, like `./config`. The files are public: they are served before auth,
|
|
58
|
-
* validation and middleware, and outside the rate limit. An unknown path under the prefix
|
|
59
|
-
* serves `index.html` to a browser (`Accept: text/html`) so client routes survive a reload. `"/"` mounts it at the root. Hashed assets are cached for a
|
|
60
|
-
* year, `index.html` is not cached. See {@link StaticOptions}.
|
|
61
|
-
*/
|
|
62
|
-
withStatic(prefix: string, directory: string, options?: StaticOptions): Builder;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
export declare class BuilderExtensions {
|
|
66
|
-
static withHttpProvider<Thttp extends Constructable<HttpProvider>>(builder: Builder, type: Thttp): Builder<import("@decohere/http").App>;
|
|
67
|
-
static withHttp<Thttp extends Constructable<HttpProvider>>(builder: Builder, type: Thttp, options?: WithHttpOptions): Builder<import("@decohere/http").App>;
|
|
68
|
-
static withControllers(builder: Builder, ...controllers: Constructable[]): Builder<import("@decohere/http").App>;
|
|
69
|
-
static withGlobalPrefix(builder: Builder, prefix: string): Builder<import("@decohere/http").App>;
|
|
70
|
-
static withCors(builder: Builder, options: CorsOptions): Builder<import("@decohere/http").App>;
|
|
71
|
-
static withHelmet(builder: Builder, options?: HelmetOptions): Builder<import("@decohere/http").App>;
|
|
72
|
-
static withRateLimit(builder: Builder, options?: RateLimitOptions): Builder<import("@decohere/http").App>;
|
|
73
|
-
static withCompression(builder: Builder, options?: CompressionOptions): Builder<import("@decohere/http").App>;
|
|
74
|
-
static withBodyLimit(builder: Builder, bytes: number): Builder<import("@decohere/http").App>;
|
|
75
|
-
static withMiddleware(builder: Builder, ...middlewares: Constructable<Middleware>[]): Builder<import("@decohere/http").App>;
|
|
76
|
-
static withExceptionFilters(builder: Builder, ...filters: Constructable<ExceptionFilter>[]): Builder<import("@decohere/http").App>;
|
|
77
|
-
static withOpenApi(builder: Builder, options: OpenApiOptions): Builder<import("@decohere/http").App>;
|
|
78
|
-
static withStatic(builder: Builder, prefix: string, directory: string, options?: StaticOptions): Builder<import("@decohere/http").App>;
|
|
79
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { Constructable } from "@decohere/core/reflection";
|
|
2
|
-
import type { OpenApiOptions } from "../openapi/openapi.types.js";
|
|
3
|
-
import type { CorsOptions } from "../routing/anvil.types.js";
|
|
4
|
-
import type { ExceptionFilter } from "../routing/filters/exception-filter.js";
|
|
5
|
-
import type { Middleware } from "../routing/middleware/middleware.js";
|
|
6
|
-
import type { CompressionOptions } from "./http.compression.js";
|
|
7
|
-
import type { StaticMount } from "./http.static.js";
|
|
8
|
-
import type { HelmetOptions, RateLimitOptions } from "./http.security.js";
|
|
9
|
-
/** Options for {@link Builder.withHttp} (request-id / access-log defaults, etc.). */
|
|
10
|
-
export type WithHttpOptions = {
|
|
11
|
-
/**
|
|
12
|
-
* Register {@link HttpAccessLogMiddleware} (request id echo + Scribe access log).
|
|
13
|
-
* Defaults to `true`.
|
|
14
|
-
*/
|
|
15
|
-
accessLog?: boolean;
|
|
16
|
-
};
|
|
17
|
-
/** App-level HTTP options set via builder extensions (`withCors`, `withGlobalPrefix`, …). */
|
|
18
|
-
export declare class HttpOptions {
|
|
19
|
-
globalPrefix: string;
|
|
20
|
-
/**
|
|
21
|
-
* Controllers put under the global prefix although they declare `globalPrefix: false`
|
|
22
|
-
* (`withHealth({ underGlobalPrefix: true })`).
|
|
23
|
-
*/
|
|
24
|
-
readonly underGlobalPrefix: Set<Constructable>;
|
|
25
|
-
cors?: CorsOptions;
|
|
26
|
-
openapi?: OpenApiOptions;
|
|
27
|
-
/** `undefined` = helmet on with defaults; `false` = off; object = plugin options. */
|
|
28
|
-
helmet?: HelmetOptions;
|
|
29
|
-
/** `undefined` = rate-limit on with defaults; `false` = off; object = plugin options. */
|
|
30
|
-
rateLimit?: RateLimitOptions;
|
|
31
|
-
/** `undefined` = compression on with defaults; `false` = off; object = options. See `withCompression`. */
|
|
32
|
-
compression?: CompressionOptions;
|
|
33
|
-
/** Request body size limit in bytes; `undefined` uses the 1 MiB default. */
|
|
34
|
-
bodyLimit?: number;
|
|
35
|
-
/** Built UIs served from this API, see `withStatic`. */
|
|
36
|
-
statics: StaticMount[];
|
|
37
|
-
middlewareTypes: Constructable<Middleware>[];
|
|
38
|
-
filterTypes: Constructable<ExceptionFilter>[];
|
|
39
|
-
}
|