@beignet/core 0.0.1 → 0.0.2
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/CHANGELOG.md +11 -0
- package/README.md +149 -4
- package/dist/application/index.d.ts +93 -9
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +11 -11
- package/dist/application/index.js.map +1 -1
- package/dist/client/client.d.ts +73 -12
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +37 -12
- package/dist/client/client.js.map +1 -1
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/types.d.ts +69 -8
- package/dist/client/types.d.ts.map +1 -1
- package/dist/config/index.d.ts +84 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +36 -0
- package/dist/config/index.js.map +1 -1
- package/dist/contracts/contract-builder.d.ts +49 -22
- package/dist/contracts/contract-builder.d.ts.map +1 -1
- package/dist/contracts/contract-builder.js +48 -21
- package/dist/contracts/contract-builder.js.map +1 -1
- package/dist/contracts/contract-group.d.ts +35 -19
- package/dist/contracts/contract-group.d.ts.map +1 -1
- package/dist/contracts/contract-group.js +35 -19
- package/dist/contracts/contract-group.js.map +1 -1
- package/dist/contracts/contract-like.d.ts +4 -4
- package/dist/contracts/contract-like.d.ts.map +1 -1
- package/dist/contracts/contract-like.js +2 -1
- package/dist/contracts/contract-like.js.map +1 -1
- package/dist/contracts/index.d.ts +28 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +12 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/openapi-meta.d.ts +8 -8
- package/dist/contracts/openapi-meta.d.ts.map +1 -1
- package/dist/contracts/path-template.d.ts +27 -0
- package/dist/contracts/path-template.d.ts.map +1 -1
- package/dist/contracts/path-template.js +6 -0
- package/dist/contracts/path-template.js.map +1 -1
- package/dist/contracts/types.d.ts +104 -10
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/contracts/types.js +15 -0
- package/dist/contracts/types.js.map +1 -1
- package/dist/contracts/utils.d.ts +6 -0
- package/dist/contracts/utils.d.ts.map +1 -1
- package/dist/contracts/utils.js +6 -0
- package/dist/contracts/utils.js.map +1 -1
- package/dist/domain/entity.d.ts +22 -11
- package/dist/domain/entity.d.ts.map +1 -1
- package/dist/domain/entity.js +5 -1
- package/dist/domain/entity.js.map +1 -1
- package/dist/domain/events.d.ts +5 -2
- package/dist/domain/events.d.ts.map +1 -1
- package/dist/domain/events.js +4 -1
- package/dist/domain/events.js.map +1 -1
- package/dist/domain/value-object.d.ts +19 -9
- package/dist/domain/value-object.d.ts.map +1 -1
- package/dist/domain/value-object.js +5 -1
- package/dist/domain/value-object.js.map +1 -1
- package/dist/errors/catalog.d.ts +40 -16
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/catalog.js +18 -7
- package/dist/errors/catalog.js.map +1 -1
- package/dist/errors/response.d.ts +16 -4
- package/dist/errors/response.d.ts.map +1 -1
- package/dist/errors/response.js +3 -3
- package/dist/errors/response.js.map +1 -1
- package/dist/errors/validation.d.ts +10 -1
- package/dist/errors/validation.d.ts.map +1 -1
- package/dist/errors/validation.js +3 -0
- package/dist/errors/validation.js.map +1 -1
- package/dist/events/index.d.ts +133 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +30 -0
- package/dist/events/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +355 -0
- package/dist/idempotency/index.d.ts.map +1 -0
- package/dist/idempotency/index.js +360 -0
- package/dist/idempotency/index.js.map +1 -0
- package/dist/jobs/index.d.ts +110 -0
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +22 -0
- package/dist/jobs/index.js.map +1 -1
- package/dist/mail/index.d.ts +149 -0
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +30 -0
- package/dist/mail/index.js.map +1 -1
- package/dist/notifications/index.d.ts +369 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +310 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/openapi/index.d.ts +132 -16
- package/dist/openapi/index.d.ts.map +1 -1
- package/dist/openapi/index.js +1 -1
- package/dist/openapi/index.js.map +1 -1
- package/dist/outbox/index.d.ts +469 -0
- package/dist/outbox/index.d.ts.map +1 -0
- package/dist/outbox/index.js +482 -0
- package/dist/outbox/index.js.map +1 -0
- package/dist/pagination/index.d.ts +166 -0
- package/dist/pagination/index.d.ts.map +1 -0
- package/dist/pagination/index.js +96 -0
- package/dist/pagination/index.js.map +1 -0
- package/dist/ports/audit.d.ts +271 -0
- package/dist/ports/audit.d.ts.map +1 -1
- package/dist/ports/audit.js +128 -0
- package/dist/ports/audit.js.map +1 -1
- package/dist/ports/auth.d.ts +70 -0
- package/dist/ports/auth.d.ts.map +1 -1
- package/dist/ports/auth.js +30 -0
- package/dist/ports/auth.js.map +1 -1
- package/dist/ports/cache.d.ts +41 -0
- package/dist/ports/cache.d.ts.map +1 -1
- package/dist/ports/cache.js +10 -0
- package/dist/ports/cache.js.map +1 -1
- package/dist/ports/clock.d.ts +38 -0
- package/dist/ports/clock.d.ts.map +1 -1
- package/dist/ports/clock.js +20 -0
- package/dist/ports/clock.js.map +1 -1
- package/dist/ports/id-generator.d.ts +37 -0
- package/dist/ports/id-generator.d.ts.map +1 -1
- package/dist/ports/id-generator.js +22 -0
- package/dist/ports/id-generator.js.map +1 -1
- package/dist/ports/index.d.ts +83 -0
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +41 -5
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/logger.d.ts +56 -0
- package/dist/ports/logger.d.ts.map +1 -1
- package/dist/ports/logger.js +17 -0
- package/dist/ports/logger.js.map +1 -1
- package/dist/ports/policy.d.ts +132 -0
- package/dist/ports/policy.d.ts.map +1 -1
- package/dist/ports/policy.js +45 -0
- package/dist/ports/policy.js.map +1 -1
- package/dist/ports/rate-limit.d.ts +25 -0
- package/dist/ports/rate-limit.d.ts.map +1 -1
- package/dist/ports/rate-limit.js +10 -0
- package/dist/ports/rate-limit.js.map +1 -1
- package/dist/ports/redaction.d.ts +101 -0
- package/dist/ports/redaction.d.ts.map +1 -1
- package/dist/ports/redaction.js +59 -0
- package/dist/ports/redaction.js.map +1 -1
- package/dist/ports/storage.d.ts +100 -0
- package/dist/ports/storage.d.ts.map +1 -1
- package/dist/ports/storage.js +10 -0
- package/dist/ports/storage.js.map +1 -1
- package/dist/ports/testing.d.ts +47 -0
- package/dist/ports/testing.d.ts.map +1 -1
- package/dist/ports/testing.js +23 -0
- package/dist/ports/testing.js.map +1 -1
- package/dist/ports/unit-of-work.d.ts +60 -3
- package/dist/ports/unit-of-work.d.ts.map +1 -1
- package/dist/ports/unit-of-work.js +11 -2
- package/dist/ports/unit-of-work.js.map +1 -1
- package/dist/providers/instrumentation.d.ts +204 -0
- package/dist/providers/instrumentation.d.ts.map +1 -1
- package/dist/providers/instrumentation.js +14 -0
- package/dist/providers/instrumentation.js.map +1 -1
- package/dist/providers/provider.d.ts +14 -1
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/provider.js.map +1 -1
- package/dist/schedules/index.d.ts +246 -0
- package/dist/schedules/index.d.ts.map +1 -1
- package/dist/schedules/index.js +27 -0
- package/dist/schedules/index.js.map +1 -1
- package/dist/server/health.d.ts +14 -5
- package/dist/server/health.d.ts.map +1 -1
- package/dist/server/health.js +5 -2
- package/dist/server/health.js.map +1 -1
- package/dist/server/hooks/auth.d.ts +57 -0
- package/dist/server/hooks/auth.d.ts.map +1 -1
- package/dist/server/hooks/auth.js.map +1 -1
- package/dist/server/hooks/cors.d.ts +27 -0
- package/dist/server/hooks/cors.d.ts.map +1 -1
- package/dist/server/hooks/cors.js +12 -0
- package/dist/server/hooks/cors.js.map +1 -1
- package/dist/server/hooks/errors.d.ts +15 -6
- package/dist/server/hooks/errors.d.ts.map +1 -1
- package/dist/server/hooks/errors.js.map +1 -1
- package/dist/server/hooks/index.d.ts +3 -0
- package/dist/server/hooks/index.d.ts.map +1 -1
- package/dist/server/hooks/index.js +3 -0
- package/dist/server/hooks/index.js.map +1 -1
- package/dist/server/hooks/logging.d.ts +36 -0
- package/dist/server/hooks/logging.d.ts.map +1 -1
- package/dist/server/hooks/logging.js +6 -0
- package/dist/server/hooks/logging.js.map +1 -1
- package/dist/server/hooks/rate-limit.d.ts +33 -0
- package/dist/server/hooks/rate-limit.d.ts.map +1 -1
- package/dist/server/hooks/rate-limit.js +11 -0
- package/dist/server/hooks/rate-limit.js.map +1 -1
- package/dist/server/http.d.ts +170 -0
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +6 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/openapi.d.ts +5 -3
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/openapi.js +4 -2
- package/dist/server/openapi.js.map +1 -1
- package/dist/server/providers/loadProviderConfig.d.ts +9 -0
- package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
- package/dist/server/providers/loadProviderConfig.js +9 -0
- package/dist/server/providers/loadProviderConfig.js.map +1 -1
- package/dist/server/server.d.ts +107 -8
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +27 -7
- package/dist/server/server.js.map +1 -1
- package/dist/testing/index.d.ts +167 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +119 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +21 -1
- package/src/application/index.ts +85 -22
- package/src/client/client.ts +73 -12
- package/src/client/index.ts +12 -0
- package/src/client/types.ts +70 -9
- package/src/config/index.ts +86 -0
- package/src/contracts/contract-builder.ts +49 -22
- package/src/contracts/contract-group.ts +35 -19
- package/src/contracts/contract-like.ts +4 -4
- package/src/contracts/index.ts +28 -1
- package/src/contracts/openapi-meta.ts +8 -8
- package/src/contracts/path-template.ts +27 -0
- package/src/contracts/types.ts +111 -10
- package/src/contracts/utils.ts +6 -0
- package/src/domain/entity.ts +22 -11
- package/src/domain/events.ts +5 -2
- package/src/domain/value-object.ts +19 -9
- package/src/errors/catalog.ts +40 -16
- package/src/errors/response.ts +16 -4
- package/src/errors/validation.ts +10 -1
- package/src/events/index.ts +134 -0
- package/src/idempotency/index.ts +767 -0
- package/src/jobs/index.ts +111 -0
- package/src/mail/index.ts +149 -0
- package/src/notifications/index.ts +771 -0
- package/src/openapi/index.ts +133 -16
- package/src/outbox/index.ts +1024 -0
- package/src/pagination/index.ts +278 -0
- package/src/ports/audit.ts +271 -0
- package/src/ports/auth.ts +70 -0
- package/src/ports/cache.ts +41 -0
- package/src/ports/clock.ts +38 -0
- package/src/ports/id-generator.ts +37 -0
- package/src/ports/index.ts +106 -11
- package/src/ports/logger.ts +56 -0
- package/src/ports/policy.ts +133 -0
- package/src/ports/rate-limit.ts +25 -0
- package/src/ports/redaction.ts +101 -0
- package/src/ports/storage.ts +100 -0
- package/src/ports/testing.ts +47 -0
- package/src/ports/unit-of-work.ts +60 -3
- package/src/providers/instrumentation.ts +204 -0
- package/src/providers/provider.ts +14 -1
- package/src/schedules/index.ts +247 -0
- package/src/server/health.ts +14 -5
- package/src/server/hooks/auth.ts +58 -0
- package/src/server/hooks/cors.ts +27 -0
- package/src/server/hooks/errors.ts +15 -6
- package/src/server/hooks/index.ts +3 -0
- package/src/server/hooks/logging.ts +36 -0
- package/src/server/hooks/rate-limit.ts +33 -0
- package/src/server/http.ts +170 -1
- package/src/server/index.ts +18 -1
- package/src/server/openapi.ts +5 -3
- package/src/server/providers/loadProviderConfig.ts +9 -0
- package/src/server/server.ts +107 -9
- package/src/testing/index.ts +337 -0
|
@@ -6,21 +6,51 @@ import type { HttpContractConfig } from "../../contracts";
|
|
|
6
6
|
import type { HttpRequestLike, ServerHook } from "../types";
|
|
7
7
|
import { getRequestIdFromContext } from "./utils";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Minimal logger shape accepted by `createLoggingHooks(...)`.
|
|
11
|
+
*/
|
|
9
12
|
export interface Logger {
|
|
13
|
+
/**
|
|
14
|
+
* Log an informational event.
|
|
15
|
+
*/
|
|
10
16
|
info: (...args: unknown[]) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Log an error event.
|
|
19
|
+
*/
|
|
11
20
|
error: (...args: unknown[]) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Log a warning event.
|
|
23
|
+
*/
|
|
12
24
|
warn?: (...args: unknown[]) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Log a debug event.
|
|
27
|
+
*/
|
|
13
28
|
debug?: (...args: unknown[]) => void;
|
|
14
29
|
}
|
|
15
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Logging hook configuration.
|
|
33
|
+
*/
|
|
16
34
|
export interface LoggingConfig<Ctx> {
|
|
35
|
+
/**
|
|
36
|
+
* Logger used when custom lifecycle callbacks are not provided.
|
|
37
|
+
*/
|
|
17
38
|
logger?: Logger;
|
|
39
|
+
/**
|
|
40
|
+
* Response header name used to expose `ctx.requestId` when present.
|
|
41
|
+
*/
|
|
18
42
|
requestIdHeader?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Custom request-start observer.
|
|
45
|
+
*/
|
|
19
46
|
onRequestStart?: (args: {
|
|
20
47
|
ctx?: Ctx;
|
|
21
48
|
req: HttpRequestLike;
|
|
22
49
|
contract?: HttpContractConfig;
|
|
23
50
|
}) => void;
|
|
51
|
+
/**
|
|
52
|
+
* Custom request-end observer.
|
|
53
|
+
*/
|
|
24
54
|
onRequestEnd?: (args: {
|
|
25
55
|
ctx?: Ctx;
|
|
26
56
|
req: HttpRequestLike;
|
|
@@ -31,6 +61,12 @@ export interface LoggingConfig<Ctx> {
|
|
|
31
61
|
}) => void;
|
|
32
62
|
}
|
|
33
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Create request logging hooks.
|
|
66
|
+
*
|
|
67
|
+
* Logging observer errors are intentionally ignored so logging cannot break
|
|
68
|
+
* request handling.
|
|
69
|
+
*/
|
|
34
70
|
export function createLoggingHooks<Ctx>(
|
|
35
71
|
config: LoggingConfig<Ctx>,
|
|
36
72
|
): ServerHook<Ctx> {
|
|
@@ -7,10 +7,16 @@ import { AppError, httpErrors } from "../../errors";
|
|
|
7
7
|
import type { ActivityActor, RateLimitPort } from "../../ports";
|
|
8
8
|
import type { HttpRequestLike, ServerHook } from "../types";
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Ports required by rate-limit hooks.
|
|
12
|
+
*/
|
|
10
13
|
export type RateLimitPorts = {
|
|
11
14
|
rateLimit: RateLimitPort;
|
|
12
15
|
};
|
|
13
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Minimal context shape required for user-scoped rate limits.
|
|
19
|
+
*/
|
|
14
20
|
export type CtxWithRateLimit = {
|
|
15
21
|
ports: RateLimitPorts;
|
|
16
22
|
actor?: ActivityActor;
|
|
@@ -18,16 +24,32 @@ export type CtxWithRateLimit = {
|
|
|
18
24
|
|
|
19
25
|
type EarlyRateLimitScope = Exclude<RateLimitScope, "user">;
|
|
20
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Options for `createRateLimitHooks(...)`.
|
|
29
|
+
*/
|
|
21
30
|
export interface RateLimitOptions<Ctx> {
|
|
31
|
+
/**
|
|
32
|
+
* Build a rate-limit key after context exists.
|
|
33
|
+
*
|
|
34
|
+
* This is used for user-scoped limits and any late key strategy.
|
|
35
|
+
*/
|
|
22
36
|
key?: (args: {
|
|
23
37
|
ctx: Ctx;
|
|
24
38
|
req: HttpRequestLike;
|
|
25
39
|
scope: RateLimitScope;
|
|
26
40
|
}) => string;
|
|
41
|
+
/**
|
|
42
|
+
* Build a rate-limit key before request parsing and context creation.
|
|
43
|
+
*
|
|
44
|
+
* This is used for global and IP-scoped limits.
|
|
45
|
+
*/
|
|
27
46
|
earlyKey?: (args: {
|
|
28
47
|
req: HttpRequestLike;
|
|
29
48
|
scope: EarlyRateLimitScope;
|
|
30
49
|
}) => string;
|
|
50
|
+
/**
|
|
51
|
+
* Resolve a client IP from the raw request.
|
|
52
|
+
*/
|
|
31
53
|
getClientIp?: (req: HttpRequestLike) => string | undefined;
|
|
32
54
|
}
|
|
33
55
|
|
|
@@ -112,6 +134,17 @@ async function enforceRateLimit(
|
|
|
112
134
|
);
|
|
113
135
|
}
|
|
114
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Create metadata-driven rate-limit hooks.
|
|
139
|
+
*
|
|
140
|
+
* The hook reads `contract.metadata.rateLimit`. Global and IP-scoped limits run
|
|
141
|
+
* in `onRequest` before context creation; user-scoped limits run in
|
|
142
|
+
* `beforeHandle` after `ctx.actor` is available. Exceeded limits throw the
|
|
143
|
+
* framework `TooManyRequests` app error.
|
|
144
|
+
*
|
|
145
|
+
* @param options - Optional key builders and client-IP resolver.
|
|
146
|
+
* @returns A server hook backed by `ctx.ports.rateLimit`.
|
|
147
|
+
*/
|
|
115
148
|
export function createRateLimitHooks<Ctx extends CtxWithRateLimit>(
|
|
116
149
|
options: RateLimitOptions<Ctx> = {},
|
|
117
150
|
): ServerHook<Ctx, RateLimitPorts> {
|
package/src/server/http.ts
CHANGED
|
@@ -6,9 +6,24 @@ import type {
|
|
|
6
6
|
} from "../contracts";
|
|
7
7
|
import type { AnyPorts } from "../ports";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Framework-neutral request shape consumed by Beignet server adapters.
|
|
11
|
+
*
|
|
12
|
+
* Platform adapters should convert their native request into this shape before
|
|
13
|
+
* passing it to `server.api(...)` or a single route handler.
|
|
14
|
+
*/
|
|
9
15
|
export interface HttpRequestLike {
|
|
16
|
+
/**
|
|
17
|
+
* HTTP method as received from the platform.
|
|
18
|
+
*/
|
|
10
19
|
method: string;
|
|
20
|
+
/**
|
|
21
|
+
* Absolute request URL.
|
|
22
|
+
*/
|
|
11
23
|
url: string;
|
|
24
|
+
/**
|
|
25
|
+
* Request headers.
|
|
26
|
+
*/
|
|
12
27
|
headers: Headers;
|
|
13
28
|
/**
|
|
14
29
|
* The platform request when an adapter has one available.
|
|
@@ -17,20 +32,56 @@ export interface HttpRequestLike {
|
|
|
17
32
|
* framework-agnostic methods below when possible.
|
|
18
33
|
*/
|
|
19
34
|
raw?: Request;
|
|
35
|
+
/**
|
|
36
|
+
* Parse the request body as JSON.
|
|
37
|
+
*/
|
|
20
38
|
json(): Promise<unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Parse the request body as text.
|
|
41
|
+
*/
|
|
21
42
|
text(): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Parse the request body as an array buffer when the platform supports it.
|
|
45
|
+
*/
|
|
22
46
|
arrayBuffer?(): Promise<ArrayBuffer>;
|
|
47
|
+
/**
|
|
48
|
+
* Parse the request body as a Blob when the platform supports it.
|
|
49
|
+
*/
|
|
23
50
|
blob?(): Promise<Blob>;
|
|
51
|
+
/**
|
|
52
|
+
* Parse the request body as form data when the platform supports it.
|
|
53
|
+
*/
|
|
24
54
|
formData?(): Promise<FormData>;
|
|
55
|
+
/**
|
|
56
|
+
* Clone the request when the platform supports replaying the body.
|
|
57
|
+
*/
|
|
25
58
|
clone?(): HttpRequestLike;
|
|
26
59
|
}
|
|
27
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Framework-neutral response object returned by route handlers and hooks.
|
|
63
|
+
*/
|
|
28
64
|
export interface HttpResponseLike {
|
|
65
|
+
/**
|
|
66
|
+
* HTTP status code.
|
|
67
|
+
*/
|
|
29
68
|
status: number;
|
|
69
|
+
/**
|
|
70
|
+
* Response headers.
|
|
71
|
+
*/
|
|
30
72
|
headers?: Record<string, string>;
|
|
73
|
+
/**
|
|
74
|
+
* JSON-serializable body or an adapter-specific body value.
|
|
75
|
+
*/
|
|
31
76
|
body?: unknown;
|
|
32
77
|
}
|
|
33
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Response accepted by Beignet handlers.
|
|
81
|
+
*
|
|
82
|
+
* Use `HttpResponseLike` for framework-neutral responses. Return a native
|
|
83
|
+
* `Response` only when the current adapter can pass it through unchanged.
|
|
84
|
+
*/
|
|
34
85
|
export type HttpResponse = HttpResponseLike | Response;
|
|
35
86
|
|
|
36
87
|
type InferSchemaOrFallback<
|
|
@@ -38,44 +89,91 @@ type InferSchemaOrFallback<
|
|
|
38
89
|
Fallback,
|
|
39
90
|
> = T extends StandardSchema ? InferOutput<T> : Fallback;
|
|
40
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Infer the handler path parameter type for a contract.
|
|
94
|
+
*/
|
|
41
95
|
export type InferPath<C extends HttpContractConfig> = InferSchemaOrFallback<
|
|
42
96
|
C["pathParams"],
|
|
43
97
|
Record<string, string>
|
|
44
98
|
>;
|
|
45
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Infer the handler query parameter type for a contract.
|
|
102
|
+
*/
|
|
46
103
|
export type InferQuery<C extends HttpContractConfig> = InferSchemaOrFallback<
|
|
47
104
|
C["query"],
|
|
48
105
|
Record<string, string | string[]>
|
|
49
106
|
>;
|
|
50
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Infer the handler request body type for a contract.
|
|
110
|
+
*/
|
|
51
111
|
export type InferBody<C extends HttpContractConfig> = InferSchemaOrFallback<
|
|
52
112
|
C["body"],
|
|
53
113
|
unknown
|
|
54
114
|
>;
|
|
55
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Infer the merged request header type for a contract.
|
|
118
|
+
*/
|
|
56
119
|
export type InferHeaders<C extends HttpContractConfig> =
|
|
57
120
|
InferHeaderSchemaOutput<Exclude<C["headers"], undefined>> extends undefined
|
|
58
121
|
? Record<string, string>
|
|
59
122
|
: InferHeaderSchemaOutput<Exclude<C["headers"], undefined>>;
|
|
60
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Arguments passed to a route handler after request parsing and validation.
|
|
126
|
+
*/
|
|
61
127
|
export interface HandlerArgs<Ctx, C extends HttpContractConfig> {
|
|
128
|
+
/**
|
|
129
|
+
* Framework-neutral request.
|
|
130
|
+
*/
|
|
62
131
|
req: HttpRequestLike;
|
|
132
|
+
/**
|
|
133
|
+
* Application context returned by `createContext`.
|
|
134
|
+
*/
|
|
63
135
|
ctx: Ctx;
|
|
136
|
+
/**
|
|
137
|
+
* Matched contract config.
|
|
138
|
+
*/
|
|
64
139
|
contract: C;
|
|
65
140
|
|
|
66
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Parsed path parameters.
|
|
143
|
+
*/
|
|
67
144
|
path: InferPath<C>;
|
|
145
|
+
/**
|
|
146
|
+
* Parsed query parameters.
|
|
147
|
+
*/
|
|
68
148
|
query: InferQuery<C>;
|
|
149
|
+
/**
|
|
150
|
+
* Parsed request headers.
|
|
151
|
+
*/
|
|
69
152
|
headers: InferHeaders<C>;
|
|
153
|
+
/**
|
|
154
|
+
* Parsed request body.
|
|
155
|
+
*/
|
|
70
156
|
body: InferBody<C>;
|
|
71
157
|
}
|
|
72
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Route handler function for a contract.
|
|
161
|
+
*/
|
|
73
162
|
export type Handler<Ctx, C extends HttpContractConfig> = (
|
|
74
163
|
args: HandlerArgs<Ctx, C>,
|
|
75
164
|
) => Promise<HttpResponse> | HttpResponse;
|
|
76
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Value or promise of that value.
|
|
168
|
+
*/
|
|
77
169
|
export type MaybePromise<T> = T | Promise<T>;
|
|
78
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Hook that runs after a route is matched but before request parsing and
|
|
173
|
+
* context creation.
|
|
174
|
+
*
|
|
175
|
+
* Returning a response short-circuits the rest of the request pipeline.
|
|
176
|
+
*/
|
|
79
177
|
export type OnRequestHook<
|
|
80
178
|
Ports extends AnyPorts = AnyPorts,
|
|
81
179
|
C extends HttpContractConfig = HttpContractConfig,
|
|
@@ -86,6 +184,12 @@ export type OnRequestHook<
|
|
|
86
184
|
params: Record<string, string>;
|
|
87
185
|
}) => MaybePromise<HttpResponse | undefined>;
|
|
88
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Result from a `beforeHandle` hook.
|
|
189
|
+
*
|
|
190
|
+
* Returning a plain response short-circuits the handler. Returning an object can
|
|
191
|
+
* replace the context, short-circuit with a response, or do both.
|
|
192
|
+
*/
|
|
89
193
|
export type BeforeHandleResult<Ctx> =
|
|
90
194
|
| undefined
|
|
91
195
|
| HttpResponse
|
|
@@ -94,6 +198,9 @@ export type BeforeHandleResult<Ctx> =
|
|
|
94
198
|
response?: HttpResponse;
|
|
95
199
|
};
|
|
96
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Hook that runs after request parsing/context creation and before the handler.
|
|
203
|
+
*/
|
|
97
204
|
export type BeforeHandleHook<
|
|
98
205
|
Ctx,
|
|
99
206
|
C extends HttpContractConfig = HttpContractConfig,
|
|
@@ -107,6 +214,12 @@ export type BeforeHandleHook<
|
|
|
107
214
|
body: InferBody<C>;
|
|
108
215
|
}) => MaybePromise<BeforeHandleResult<Ctx>>;
|
|
109
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Hook that runs before a framework-neutral response is returned.
|
|
219
|
+
*
|
|
220
|
+
* Return a response to replace or decorate the outgoing response. Hooks run in
|
|
221
|
+
* declaration order.
|
|
222
|
+
*/
|
|
110
223
|
export type BeforeSendHook<
|
|
111
224
|
Ctx,
|
|
112
225
|
C extends HttpContractConfig = HttpContractConfig,
|
|
@@ -122,6 +235,12 @@ export type BeforeSendHook<
|
|
|
122
235
|
error?: unknown;
|
|
123
236
|
}) => MaybePromise<HttpResponseLike | undefined>;
|
|
124
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Hook that runs after the response has been prepared.
|
|
240
|
+
*
|
|
241
|
+
* This is for logging and observability. Errors thrown by `afterSend` hooks are
|
|
242
|
+
* ignored by the server pipeline.
|
|
243
|
+
*/
|
|
125
244
|
export type AfterSendHook<
|
|
126
245
|
Ctx,
|
|
127
246
|
C extends HttpContractConfig = HttpContractConfig,
|
|
@@ -138,6 +257,9 @@ export type AfterSendHook<
|
|
|
138
257
|
durationMs: number;
|
|
139
258
|
}) => MaybePromise<void>;
|
|
140
259
|
|
|
260
|
+
/**
|
|
261
|
+
* Hook notified when the framework catches an error while handling a request.
|
|
262
|
+
*/
|
|
141
263
|
export type ServerCaughtErrorHook<
|
|
142
264
|
Ctx,
|
|
143
265
|
C extends HttpContractConfig = HttpContractConfig,
|
|
@@ -152,6 +274,12 @@ export type ServerCaughtErrorHook<
|
|
|
152
274
|
body?: InferBody<C>;
|
|
153
275
|
}) => MaybePromise<void>;
|
|
154
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Hook that may map an unexpected error to a custom response.
|
|
279
|
+
*
|
|
280
|
+
* Return `undefined` to let the server's default unhandled-error mapper create
|
|
281
|
+
* the response.
|
|
282
|
+
*/
|
|
155
283
|
export type ServerUnhandledErrorMapper<
|
|
156
284
|
Ctx,
|
|
157
285
|
C extends HttpContractConfig = HttpContractConfig,
|
|
@@ -166,22 +294,63 @@ export type ServerUnhandledErrorMapper<
|
|
|
166
294
|
body?: InferBody<C>;
|
|
167
295
|
}) => MaybePromise<HttpResponse | undefined>;
|
|
168
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Server lifecycle hook collection.
|
|
299
|
+
*
|
|
300
|
+
* Hooks run in the order they are registered. `onRequest` can short-circuit
|
|
301
|
+
* before context creation; `beforeHandle` can replace context or short-circuit;
|
|
302
|
+
* `beforeSend` can replace the outgoing response; `afterSend` observes the
|
|
303
|
+
* final response.
|
|
304
|
+
*/
|
|
169
305
|
export interface ServerHook<Ctx, Ports extends AnyPorts = AnyPorts> {
|
|
306
|
+
/**
|
|
307
|
+
* Optional name used in diagnostics and devtools.
|
|
308
|
+
*/
|
|
170
309
|
name?: string;
|
|
310
|
+
/**
|
|
311
|
+
* Runs after route matching and before body/query/header parsing.
|
|
312
|
+
*/
|
|
171
313
|
onRequest?: OnRequestHook<Ports>;
|
|
314
|
+
/**
|
|
315
|
+
* Runs after request parsing and context creation.
|
|
316
|
+
*/
|
|
172
317
|
beforeHandle?: BeforeHandleHook<Ctx>;
|
|
318
|
+
/**
|
|
319
|
+
* Runs before a framework-neutral response is returned.
|
|
320
|
+
*/
|
|
173
321
|
beforeSend?: BeforeSendHook<Ctx>;
|
|
322
|
+
/**
|
|
323
|
+
* Observes the final response after send preparation.
|
|
324
|
+
*/
|
|
174
325
|
afterSend?: AfterSendHook<Ctx>;
|
|
326
|
+
/**
|
|
327
|
+
* Observes framework-caught errors.
|
|
328
|
+
*/
|
|
175
329
|
onCaughtError?: ServerCaughtErrorHook<Ctx>;
|
|
330
|
+
/**
|
|
331
|
+
* Maps unexpected errors to responses.
|
|
332
|
+
*/
|
|
176
333
|
mapUnhandledError?: ServerUnhandledErrorMapper<Ctx>;
|
|
177
334
|
}
|
|
178
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Compiled route entry used by server internals and adapter helpers.
|
|
338
|
+
*/
|
|
179
339
|
export type ResolvedRoute<_Ctx, C extends HttpContractConfig> = {
|
|
340
|
+
/**
|
|
341
|
+
* Contract config for the route.
|
|
342
|
+
*/
|
|
180
343
|
contract: C;
|
|
344
|
+
/**
|
|
345
|
+
* Handler that receives the raw request and optional path params.
|
|
346
|
+
*/
|
|
181
347
|
handler: (
|
|
182
348
|
req: HttpRequestLike,
|
|
183
349
|
params?: Record<string, string>,
|
|
184
350
|
) => Promise<HttpResponse>;
|
|
351
|
+
/**
|
|
352
|
+
* Test whether the route matches an incoming method and pathname.
|
|
353
|
+
*/
|
|
185
354
|
match: (
|
|
186
355
|
method: string,
|
|
187
356
|
pathname: string,
|
package/src/server/index.ts
CHANGED
|
@@ -5,27 +5,44 @@
|
|
|
5
5
|
* Shared by Beignet server adapters.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Contract and schema types re-exported for server users.
|
|
10
|
+
*/
|
|
9
11
|
export type {
|
|
10
12
|
HttpContractConfig,
|
|
11
13
|
InferOutput,
|
|
12
14
|
StandardSchema,
|
|
13
15
|
StandardSchemaV1,
|
|
14
16
|
} from "../contracts";
|
|
17
|
+
/**
|
|
18
|
+
* Application error base class re-exported for server users.
|
|
19
|
+
*/
|
|
15
20
|
export { AppError } from "../errors";
|
|
21
|
+
/**
|
|
22
|
+
* Any-ports helper type re-exported for server users.
|
|
23
|
+
*/
|
|
16
24
|
export type { AnyPorts } from "../ports";
|
|
25
|
+
/**
|
|
26
|
+
* Provider type re-exported for server users.
|
|
27
|
+
*/
|
|
17
28
|
export type { ServiceProvider } from "../providers";
|
|
18
29
|
export * from "./health";
|
|
19
30
|
export * from "./hooks";
|
|
20
31
|
export * from "./http";
|
|
21
32
|
export * from "./openapi";
|
|
22
33
|
export * from "./providers";
|
|
34
|
+
/**
|
|
35
|
+
* Server configuration and route types.
|
|
36
|
+
*/
|
|
23
37
|
export type {
|
|
24
38
|
CreateServerOptions,
|
|
25
39
|
RouteDef,
|
|
26
40
|
RouteGroup,
|
|
27
41
|
ServerInstance,
|
|
28
42
|
} from "./server";
|
|
43
|
+
/**
|
|
44
|
+
* Server runtime helpers.
|
|
45
|
+
*/
|
|
29
46
|
export {
|
|
30
47
|
contractsFromRoutes,
|
|
31
48
|
createServer,
|
package/src/server/openapi.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { AppEnvironment } from "./health";
|
|
|
8
8
|
import type { HttpRequestLike, HttpResponseLike } from "./types";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* OpenAPI configuration
|
|
11
|
+
* OpenAPI route handler configuration.
|
|
12
12
|
*/
|
|
13
13
|
export interface OpenAPIConfig {
|
|
14
14
|
/** Enable OpenAPI endpoint (default: false) */
|
|
@@ -28,8 +28,10 @@ export interface OpenAPIConfig {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* Create
|
|
32
|
-
*
|
|
31
|
+
* Create a framework-neutral OpenAPI JSON handler.
|
|
32
|
+
*
|
|
33
|
+
* The OpenAPI document is generated lazily on the first request and then cached
|
|
34
|
+
* for the lifetime of the handler.
|
|
33
35
|
*/
|
|
34
36
|
export function createOpenAPIHandler(
|
|
35
37
|
contracts: readonly HttpContractConfig[],
|
|
@@ -30,6 +30,12 @@ async function parseStandardSchema<
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Load and validate config for a provider.
|
|
35
|
+
*
|
|
36
|
+
* Explicit overrides take precedence over env-derived config. When a provider
|
|
37
|
+
* declares `envPrefix`, matching env keys are stripped before validation.
|
|
38
|
+
*/
|
|
33
39
|
export async function loadProviderConfig<
|
|
34
40
|
Ports extends AnyPorts,
|
|
35
41
|
Schema extends StandardSchemaV1<unknown, unknown>,
|
|
@@ -69,4 +75,7 @@ export async function loadProviderConfig<
|
|
|
69
75
|
}
|
|
70
76
|
}
|
|
71
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Parse provider config with Standard Schema and normalize validation errors.
|
|
80
|
+
*/
|
|
72
81
|
export { parseStandardSchema };
|