@beignet/core 0.0.1
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 +5 -0
- package/README.md +288 -0
- package/dist/application/index.d.ts +260 -0
- package/dist/application/index.d.ts.map +1 -0
- package/dist/application/index.js +324 -0
- package/dist/application/index.js.map +1 -0
- package/dist/client/client.d.ts +241 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +531 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +10 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +8 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/types.d.ts +139 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/config/index.d.ts +122 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +216 -0
- package/dist/config/index.js.map +1 -0
- package/dist/contracts/contract-builder.d.ts +121 -0
- package/dist/contracts/contract-builder.d.ts.map +1 -0
- package/dist/contracts/contract-builder.js +346 -0
- package/dist/contracts/contract-builder.js.map +1 -0
- package/dist/contracts/contract-group.d.ts +106 -0
- package/dist/contracts/contract-group.d.ts.map +1 -0
- package/dist/contracts/contract-group.js +240 -0
- package/dist/contracts/contract-group.js.map +1 -0
- package/dist/contracts/contract-like.d.ts +21 -0
- package/dist/contracts/contract-like.d.ts.map +1 -0
- package/dist/contracts/contract-like.js +9 -0
- package/dist/contracts/contract-like.js.map +1 -0
- package/dist/contracts/index.d.ts +15 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +11 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/openapi-meta.d.ts +23 -0
- package/dist/contracts/openapi-meta.d.ts.map +1 -0
- package/dist/contracts/openapi-meta.js +2 -0
- package/dist/contracts/openapi-meta.js.map +1 -0
- package/dist/contracts/path-template.d.ts +17 -0
- package/dist/contracts/path-template.d.ts.map +1 -0
- package/dist/contracts/path-template.js +50 -0
- package/dist/contracts/path-template.js.map +1 -0
- package/dist/contracts/rate-limit.d.ts +50 -0
- package/dist/contracts/rate-limit.d.ts.map +1 -0
- package/dist/contracts/rate-limit.js +2 -0
- package/dist/contracts/rate-limit.js.map +1 -0
- package/dist/contracts/types.d.ts +97 -0
- package/dist/contracts/types.d.ts.map +1 -0
- package/dist/contracts/types.js +54 -0
- package/dist/contracts/types.js.map +1 -0
- package/dist/contracts/utils.d.ts +3 -0
- package/dist/contracts/utils.d.ts.map +1 -0
- package/dist/contracts/utils.js +44 -0
- package/dist/contracts/utils.js.map +1 -0
- package/dist/domain/entity.d.ts +87 -0
- package/dist/domain/entity.d.ts.map +1 -0
- package/dist/domain/entity.js +155 -0
- package/dist/domain/entity.js.map +1 -0
- package/dist/domain/events.d.ts +41 -0
- package/dist/domain/events.d.ts.map +1 -0
- package/dist/domain/events.js +21 -0
- package/dist/domain/events.js.map +1 -0
- package/dist/domain/index.d.ts +14 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +14 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/value-object.d.ts +60 -0
- package/dist/domain/value-object.d.ts.map +1 -0
- package/dist/domain/value-object.js +87 -0
- package/dist/domain/value-object.js.map +1 -0
- package/dist/errors/catalog.d.ts +71 -0
- package/dist/errors/catalog.d.ts.map +1 -0
- package/dist/errors/catalog.js +71 -0
- package/dist/errors/catalog.js.map +1 -0
- package/dist/errors/http.d.ts +77 -0
- package/dist/errors/http.d.ts.map +1 -0
- package/dist/errors/http.js +74 -0
- package/dist/errors/http.js.map +1 -0
- package/dist/errors/index.d.ts +10 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +14 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/response.d.ts +26 -0
- package/dist/errors/response.d.ts.map +1 -0
- package/dist/errors/response.js +34 -0
- package/dist/errors/response.js.map +1 -0
- package/dist/errors/validation.d.ts +18 -0
- package/dist/errors/validation.d.ts.map +1 -0
- package/dist/errors/validation.js +21 -0
- package/dist/errors/validation.js.map +1 -0
- package/dist/events/index.d.ts +58 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +102 -0
- package/dist/events/index.js.map +1 -0
- package/dist/jobs/index.d.ts +56 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +89 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/mail/index.d.ts +75 -0
- package/dist/mail/index.d.ts.map +1 -0
- package/dist/mail/index.js +84 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/openapi/index.d.ts +207 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +449 -0
- package/dist/openapi/index.js.map +1 -0
- package/dist/openapi/schema-introspector.d.ts +38 -0
- package/dist/openapi/schema-introspector.d.ts.map +1 -0
- package/dist/openapi/schema-introspector.js +67 -0
- package/dist/openapi/schema-introspector.js.map +1 -0
- package/dist/ports/audit.d.ts +58 -0
- package/dist/ports/audit.d.ts.map +1 -0
- package/dist/ports/audit.js +74 -0
- package/dist/ports/audit.js.map +1 -0
- package/dist/ports/auth.d.ts +23 -0
- package/dist/ports/auth.d.ts.map +1 -0
- package/dist/ports/auth.js +31 -0
- package/dist/ports/auth.js.map +1 -0
- package/dist/ports/builder.d.ts +61 -0
- package/dist/ports/builder.d.ts.map +1 -0
- package/dist/ports/builder.js +48 -0
- package/dist/ports/builder.js.map +1 -0
- package/dist/ports/cache.d.ts +15 -0
- package/dist/ports/cache.d.ts.map +1 -0
- package/dist/ports/cache.js +57 -0
- package/dist/ports/cache.js.map +1 -0
- package/dist/ports/clock.d.ts +10 -0
- package/dist/ports/clock.d.ts.map +1 -0
- package/dist/ports/clock.js +21 -0
- package/dist/ports/clock.js.map +1 -0
- package/dist/ports/events.d.ts +71 -0
- package/dist/ports/events.d.ts.map +1 -0
- package/dist/ports/events.js +2 -0
- package/dist/ports/events.js.map +1 -0
- package/dist/ports/id-generator.d.ts +12 -0
- package/dist/ports/id-generator.d.ts.map +1 -0
- package/dist/ports/id-generator.js +22 -0
- package/dist/ports/id-generator.js.map +1 -0
- package/dist/ports/index.d.ts +98 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +67 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/ports/logger.d.ts +22 -0
- package/dist/ports/logger.d.ts.map +1 -0
- package/dist/ports/logger.js +34 -0
- package/dist/ports/logger.js.map +1 -0
- package/dist/ports/mailer.d.ts +6 -0
- package/dist/ports/mailer.d.ts.map +1 -0
- package/dist/ports/mailer.js +2 -0
- package/dist/ports/mailer.js.map +1 -0
- package/dist/ports/policy.d.ts +53 -0
- package/dist/ports/policy.d.ts.map +1 -0
- package/dist/ports/policy.js +81 -0
- package/dist/ports/policy.js.map +1 -0
- package/dist/ports/rate-limit.d.ts +41 -0
- package/dist/ports/rate-limit.d.ts.map +1 -0
- package/dist/ports/rate-limit.js +37 -0
- package/dist/ports/rate-limit.js.map +1 -0
- package/dist/ports/redaction.d.ts +26 -0
- package/dist/ports/redaction.d.ts.map +1 -0
- package/dist/ports/redaction.js +126 -0
- package/dist/ports/redaction.js.map +1 -0
- package/dist/ports/schedules.d.ts +9 -0
- package/dist/ports/schedules.d.ts.map +1 -0
- package/dist/ports/schedules.js +2 -0
- package/dist/ports/schedules.js.map +1 -0
- package/dist/ports/storage.d.ts +47 -0
- package/dist/ports/storage.d.ts.map +1 -0
- package/dist/ports/storage.js +185 -0
- package/dist/ports/storage.js.map +1 -0
- package/dist/ports/testing.d.ts +73 -0
- package/dist/ports/testing.d.ts.map +1 -0
- package/dist/ports/testing.js +105 -0
- package/dist/ports/testing.js.map +1 -0
- package/dist/ports/unit-of-work.d.ts +56 -0
- package/dist/ports/unit-of-work.d.ts.map +1 -0
- package/dist/ports/unit-of-work.js +64 -0
- package/dist/ports/unit-of-work.js.map +1 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/instrumentation.d.ts +91 -0
- package/dist/providers/instrumentation.d.ts.map +1 -0
- package/dist/providers/instrumentation.js +93 -0
- package/dist/providers/instrumentation.js.map +1 -0
- package/dist/providers/provider.d.ts +146 -0
- package/dist/providers/provider.d.ts.map +1 -0
- package/dist/providers/provider.js +31 -0
- package/dist/providers/provider.js.map +1 -0
- package/dist/schedules/index.d.ts +105 -0
- package/dist/schedules/index.d.ts.map +1 -0
- package/dist/schedules/index.js +178 -0
- package/dist/schedules/index.js.map +1 -0
- package/dist/server/contract-like.d.ts +5 -0
- package/dist/server/contract-like.d.ts.map +1 -0
- package/dist/server/contract-like.js +5 -0
- package/dist/server/contract-like.js.map +1 -0
- package/dist/server/health.d.ts +41 -0
- package/dist/server/health.d.ts.map +1 -0
- package/dist/server/health.js +46 -0
- package/dist/server/health.js.map +1 -0
- package/dist/server/hooks/auth.d.ts +42 -0
- package/dist/server/hooks/auth.d.ts.map +1 -0
- package/dist/server/hooks/auth.js +61 -0
- package/dist/server/hooks/auth.js.map +1 -0
- package/dist/server/hooks/cors.d.ts +13 -0
- package/dist/server/hooks/cors.d.ts.map +1 -0
- package/dist/server/hooks/cors.js +70 -0
- package/dist/server/hooks/cors.js.map +1 -0
- package/dist/server/hooks/errors.d.ts +66 -0
- package/dist/server/hooks/errors.d.ts.map +1 -0
- package/dist/server/hooks/errors.js +83 -0
- package/dist/server/hooks/errors.js.map +1 -0
- package/dist/server/hooks/index.d.ts +12 -0
- package/dist/server/hooks/index.d.ts.map +1 -0
- package/dist/server/hooks/index.js +12 -0
- package/dist/server/hooks/index.js.map +1 -0
- package/dist/server/hooks/logging.d.ts +33 -0
- package/dist/server/hooks/logging.d.ts.map +1 -0
- package/dist/server/hooks/logging.js +90 -0
- package/dist/server/hooks/logging.js.map +1 -0
- package/dist/server/hooks/rate-limit.d.ts +29 -0
- package/dist/server/hooks/rate-limit.d.ts.map +1 -0
- package/dist/server/hooks/rate-limit.js +93 -0
- package/dist/server/hooks/rate-limit.js.map +1 -0
- package/dist/server/hooks/utils.d.ts +9 -0
- package/dist/server/hooks/utils.d.ts.map +1 -0
- package/dist/server/hooks/utils.js +16 -0
- package/dist/server/hooks/utils.js.map +1 -0
- package/dist/server/hooks.d.ts +2 -0
- package/dist/server/hooks.d.ts.map +1 -0
- package/dist/server/hooks.js +2 -0
- package/dist/server/hooks.js.map +1 -0
- package/dist/server/http.d.ts +124 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +2 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/index.d.ts +19 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +15 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/openapi.d.ts +32 -0
- package/dist/server/openapi.d.ts.map +1 -0
- package/dist/server/openapi.js +43 -0
- package/dist/server/openapi.js.map +1 -0
- package/dist/server/providers/index.d.ts +4 -0
- package/dist/server/providers/index.d.ts.map +1 -0
- package/dist/server/providers/index.js +4 -0
- package/dist/server/providers/index.js.map +1 -0
- package/dist/server/providers/loadProviderConfig.d.ts +7 -0
- package/dist/server/providers/loadProviderConfig.d.ts.map +1 -0
- package/dist/server/providers/loadProviderConfig.js +42 -0
- package/dist/server/providers/loadProviderConfig.js.map +1 -0
- package/dist/server/server.d.ts +86 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +1031 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/types.d.ts +3 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +3 -0
- package/dist/server/types.js.map +1 -0
- package/package.json +129 -0
- package/src/application/index.ts +747 -0
- package/src/client/client.ts +1105 -0
- package/src/client/index.ts +45 -0
- package/src/client/types.ts +305 -0
- package/src/config/index.ts +497 -0
- package/src/contracts/contract-builder.ts +583 -0
- package/src/contracts/contract-group.ts +502 -0
- package/src/contracts/contract-like.ts +29 -0
- package/src/contracts/index.ts +53 -0
- package/src/contracts/openapi-meta.ts +22 -0
- package/src/contracts/path-template.ts +91 -0
- package/src/contracts/rate-limit.ts +50 -0
- package/src/contracts/types.ts +207 -0
- package/src/contracts/utils.ts +56 -0
- package/src/domain/entity.ts +256 -0
- package/src/domain/events.ts +52 -0
- package/src/domain/index.ts +18 -0
- package/src/domain/value-object.ts +135 -0
- package/src/errors/catalog.ts +149 -0
- package/src/errors/http.ts +80 -0
- package/src/errors/index.ts +28 -0
- package/src/errors/response.ts +54 -0
- package/src/errors/validation.ts +35 -0
- package/src/events/index.ts +246 -0
- package/src/jobs/index.ts +211 -0
- package/src/mail/index.ts +177 -0
- package/src/openapi/index.ts +865 -0
- package/src/openapi/schema-introspector.ts +107 -0
- package/src/ports/audit.ts +176 -0
- package/src/ports/auth.ts +76 -0
- package/src/ports/builder.ts +97 -0
- package/src/ports/cache.ts +94 -0
- package/src/ports/clock.ts +34 -0
- package/src/ports/events.ts +100 -0
- package/src/ports/id-generator.ts +36 -0
- package/src/ports/index.ts +221 -0
- package/src/ports/logger.ts +67 -0
- package/src/ports/policy.ts +242 -0
- package/src/ports/rate-limit.ts +91 -0
- package/src/ports/redaction.ts +199 -0
- package/src/ports/storage.ts +282 -0
- package/src/ports/testing.ts +234 -0
- package/src/ports/unit-of-work.ts +134 -0
- package/src/providers/index.ts +40 -0
- package/src/providers/instrumentation.ts +248 -0
- package/src/providers/provider.ts +191 -0
- package/src/schedules/index.ts +442 -0
- package/src/server/contract-like.ts +8 -0
- package/src/server/health.ts +82 -0
- package/src/server/hooks/auth.ts +147 -0
- package/src/server/hooks/cors.ts +87 -0
- package/src/server/hooks/errors.ts +126 -0
- package/src/server/hooks/index.ts +43 -0
- package/src/server/hooks/logging.ts +121 -0
- package/src/server/hooks/rate-limit.ts +171 -0
- package/src/server/hooks/utils.ts +16 -0
- package/src/server/hooks.ts +1 -0
- package/src/server/http.ts +189 -0
- package/src/server/index.ts +35 -0
- package/src/server/openapi.ts +72 -0
- package/src/server/providers/index.ts +3 -0
- package/src/server/providers/loadProviderConfig.ts +72 -0
- package/src/server/server.ts +1521 -0
- package/src/server/types.ts +2 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
|
|
3
|
+
export type StandardSchema = StandardSchemaV1<unknown, unknown>;
|
|
4
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
5
|
+
|
|
6
|
+
export type InferSchemaOutput<T extends StandardSchemaV1> =
|
|
7
|
+
StandardSchemaV1.InferOutput<T>;
|
|
8
|
+
|
|
9
|
+
export type ScheduleDateInput = Date | string | number;
|
|
10
|
+
|
|
11
|
+
export interface ScheduleRunContext {
|
|
12
|
+
readonly id?: string;
|
|
13
|
+
readonly scheduledAt?: Date;
|
|
14
|
+
readonly triggeredAt: Date;
|
|
15
|
+
readonly source?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface SchedulePayloadDef<
|
|
19
|
+
Name extends string = string,
|
|
20
|
+
Payload extends StandardSchema = StandardSchema,
|
|
21
|
+
> {
|
|
22
|
+
readonly name: Name;
|
|
23
|
+
readonly payload: Payload;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ScheduleDef<
|
|
27
|
+
Name extends string = string,
|
|
28
|
+
Payload extends StandardSchema = StandardSchema,
|
|
29
|
+
Ctx = unknown,
|
|
30
|
+
> extends SchedulePayloadDef<Name, Payload> {
|
|
31
|
+
readonly kind: "schedule";
|
|
32
|
+
readonly cron: string;
|
|
33
|
+
readonly timezone?: string;
|
|
34
|
+
readonly description?: string;
|
|
35
|
+
createPayload?(
|
|
36
|
+
args: ScheduleCreatePayloadArgs<ScheduleDef<Name, Payload, Ctx>>,
|
|
37
|
+
): MaybePromise<InferSchemaOutput<Payload>>;
|
|
38
|
+
handle(
|
|
39
|
+
args: ScheduleHandleArgs<ScheduleDef<Name, Payload, Ctx>, Ctx>,
|
|
40
|
+
): MaybePromise<void>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type InferSchedulePayload<S extends SchedulePayloadDef> =
|
|
44
|
+
S["payload"] extends StandardSchemaV1<unknown, infer Output> ? Output : never;
|
|
45
|
+
|
|
46
|
+
export interface ScheduleCreatePayloadArgs<S extends SchedulePayloadDef> {
|
|
47
|
+
schedule: S;
|
|
48
|
+
run: ScheduleRunContext;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface ScheduleHandleArgs<S extends ScheduleDef, Ctx> {
|
|
52
|
+
schedule: S;
|
|
53
|
+
payload: InferSchedulePayload<S>;
|
|
54
|
+
ctx: Ctx;
|
|
55
|
+
run: ScheduleRunContext;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface DefineScheduleOptions<
|
|
59
|
+
Name extends string,
|
|
60
|
+
Payload extends StandardSchema,
|
|
61
|
+
Ctx,
|
|
62
|
+
> {
|
|
63
|
+
cron: string;
|
|
64
|
+
timezone?: string;
|
|
65
|
+
payload: Payload;
|
|
66
|
+
description?: string;
|
|
67
|
+
createPayload?(
|
|
68
|
+
args: ScheduleCreatePayloadArgs<ScheduleDef<Name, Payload, Ctx>>,
|
|
69
|
+
): MaybePromise<InferSchemaOutput<Payload>>;
|
|
70
|
+
handle(
|
|
71
|
+
args: ScheduleHandleArgs<ScheduleDef<Name, Payload, Ctx>, Ctx>,
|
|
72
|
+
): MaybePromise<void>;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface ScheduleRunOptions<Payload = unknown> {
|
|
76
|
+
payload?: Payload;
|
|
77
|
+
id?: string;
|
|
78
|
+
scheduledAt?: ScheduleDateInput;
|
|
79
|
+
triggeredAt?: ScheduleDateInput;
|
|
80
|
+
source?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type ScheduleRunArgs<
|
|
84
|
+
Ctx,
|
|
85
|
+
Payload = unknown,
|
|
86
|
+
> = ScheduleRunOptions<Payload> & {
|
|
87
|
+
ctx: Ctx;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export interface ScheduleLifecycleArgs<S extends ScheduleDef = ScheduleDef> {
|
|
91
|
+
schedule: S;
|
|
92
|
+
payload: InferSchedulePayload<S>;
|
|
93
|
+
run: ScheduleRunContext;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface ScheduleErrorArgs<S extends ScheduleDef = ScheduleDef> {
|
|
97
|
+
schedule: S;
|
|
98
|
+
payload?: InferSchedulePayload<S>;
|
|
99
|
+
run: ScheduleRunContext;
|
|
100
|
+
error: unknown;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export type ScheduleHookName = "start" | "success" | "error";
|
|
104
|
+
|
|
105
|
+
export interface ScheduleHookErrorArgs<S extends ScheduleDef = ScheduleDef> {
|
|
106
|
+
schedule: S;
|
|
107
|
+
payload?: InferSchedulePayload<S>;
|
|
108
|
+
run: ScheduleRunContext;
|
|
109
|
+
hook: ScheduleHookName;
|
|
110
|
+
error: unknown;
|
|
111
|
+
scheduleError?: unknown;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface InlineScheduleRunnerOptions<Ctx> {
|
|
115
|
+
ctx?: Ctx | (() => MaybePromise<Ctx>);
|
|
116
|
+
now?: () => Date;
|
|
117
|
+
onStart?<S extends ScheduleDef<string, StandardSchema, Ctx>>(
|
|
118
|
+
args: ScheduleLifecycleArgs<S>,
|
|
119
|
+
): MaybePromise<void>;
|
|
120
|
+
onSuccess?<S extends ScheduleDef<string, StandardSchema, Ctx>>(
|
|
121
|
+
args: ScheduleLifecycleArgs<S>,
|
|
122
|
+
): MaybePromise<void>;
|
|
123
|
+
onError?<S extends ScheduleDef<string, StandardSchema, Ctx>>(
|
|
124
|
+
args: ScheduleErrorArgs<S>,
|
|
125
|
+
): MaybePromise<void>;
|
|
126
|
+
onHookError?<S extends ScheduleDef<string, StandardSchema, Ctx>>(
|
|
127
|
+
args: ScheduleHookErrorArgs<S>,
|
|
128
|
+
): MaybePromise<void>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface ScheduleRunnerPort<Ctx = unknown> {
|
|
132
|
+
run<S extends ScheduleDef<string, StandardSchema, Ctx>>(
|
|
133
|
+
schedule: S,
|
|
134
|
+
options?: ScheduleRunOptions<InferSchedulePayload<S>>,
|
|
135
|
+
): Promise<void>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface InlineScheduleRunner<Ctx = unknown>
|
|
139
|
+
extends ScheduleRunnerPort<Ctx> {}
|
|
140
|
+
|
|
141
|
+
export interface ScheduleHandlers<Ctx> {
|
|
142
|
+
defineSchedule<Name extends string, Payload extends StandardSchema>(
|
|
143
|
+
name: Name,
|
|
144
|
+
options: DefineScheduleOptions<Name, Payload, Ctx>,
|
|
145
|
+
): ScheduleDef<Name, Payload, Ctx>;
|
|
146
|
+
|
|
147
|
+
createInlineScheduleRunner(
|
|
148
|
+
options?: InlineScheduleRunnerOptions<Ctx>,
|
|
149
|
+
): InlineScheduleRunner<Ctx>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export class ScheduleValidationError extends Error {
|
|
153
|
+
readonly issues: readonly StandardSchemaV1.Issue[];
|
|
154
|
+
|
|
155
|
+
constructor(args: {
|
|
156
|
+
name: string;
|
|
157
|
+
issues: readonly StandardSchemaV1.Issue[];
|
|
158
|
+
}) {
|
|
159
|
+
super(
|
|
160
|
+
`Schedule "${args.name}" payload validation failed: ${formatIssues(args.issues)}`,
|
|
161
|
+
);
|
|
162
|
+
this.name = "ScheduleValidationError";
|
|
163
|
+
this.issues = args.issues;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export class ScheduleRunContextError extends Error {
|
|
168
|
+
constructor(message: string) {
|
|
169
|
+
super(message);
|
|
170
|
+
this.name = "ScheduleRunContextError";
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function formatPath(path: StandardSchemaV1.Issue["path"]): string {
|
|
175
|
+
if (!path?.length) return "";
|
|
176
|
+
|
|
177
|
+
return path
|
|
178
|
+
.map((segment) =>
|
|
179
|
+
typeof segment === "object" && segment !== null && "key" in segment
|
|
180
|
+
? String(segment.key)
|
|
181
|
+
: String(segment),
|
|
182
|
+
)
|
|
183
|
+
.join(".");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function formatIssues(issues: readonly StandardSchemaV1.Issue[]): string {
|
|
187
|
+
return issues
|
|
188
|
+
.map((issue) => {
|
|
189
|
+
const path = formatPath(issue.path);
|
|
190
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
191
|
+
})
|
|
192
|
+
.join("; ");
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function parsePayload<Schema extends StandardSchemaV1>(
|
|
196
|
+
schema: Schema,
|
|
197
|
+
input: unknown,
|
|
198
|
+
args: { name: string },
|
|
199
|
+
): Promise<InferSchemaOutput<Schema>> {
|
|
200
|
+
const result = await schema["~standard"].validate(input);
|
|
201
|
+
|
|
202
|
+
if (result.issues?.length) {
|
|
203
|
+
throw new ScheduleValidationError({
|
|
204
|
+
name: args.name,
|
|
205
|
+
issues: result.issues,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if ("value" in result) {
|
|
210
|
+
return result.value as InferSchemaOutput<Schema>;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
throw new Error("Invalid Standard Schema result: missing value");
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function normalizeDate(
|
|
217
|
+
value: ScheduleDateInput | undefined,
|
|
218
|
+
field: string,
|
|
219
|
+
fallback: () => Date,
|
|
220
|
+
): Date {
|
|
221
|
+
if (value === undefined) return fallback();
|
|
222
|
+
|
|
223
|
+
const date =
|
|
224
|
+
value instanceof Date ? new Date(value.getTime()) : new Date(value);
|
|
225
|
+
|
|
226
|
+
if (Number.isNaN(date.getTime())) {
|
|
227
|
+
throw new ScheduleRunContextError(
|
|
228
|
+
`Schedule run ${field} must be a valid date.`,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return date;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function normalizeOptionalDate(
|
|
236
|
+
value: ScheduleDateInput | undefined,
|
|
237
|
+
field: string,
|
|
238
|
+
): Date | undefined {
|
|
239
|
+
if (value === undefined) return undefined;
|
|
240
|
+
return normalizeDate(value, field, () => new Date());
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function createRunContext(
|
|
244
|
+
options: ScheduleRunOptions<unknown>,
|
|
245
|
+
now: () => Date,
|
|
246
|
+
): ScheduleRunContext {
|
|
247
|
+
return {
|
|
248
|
+
id: options.id,
|
|
249
|
+
scheduledAt: normalizeOptionalDate(options.scheduledAt, "scheduledAt"),
|
|
250
|
+
triggeredAt: normalizeDate(options.triggeredAt, "triggeredAt", now),
|
|
251
|
+
source: options.source,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async function resolveCtx<Ctx>(
|
|
256
|
+
ctx: Ctx | (() => MaybePromise<Ctx>) | undefined,
|
|
257
|
+
): Promise<Ctx> {
|
|
258
|
+
if (typeof ctx === "function") {
|
|
259
|
+
return (ctx as () => MaybePromise<Ctx>)();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return ctx as Ctx;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async function resolveSchedulePayload<S extends ScheduleDef>(
|
|
266
|
+
schedule: S,
|
|
267
|
+
options: ScheduleRunOptions<InferSchedulePayload<S>>,
|
|
268
|
+
run: ScheduleRunContext,
|
|
269
|
+
): Promise<InferSchedulePayload<S>> {
|
|
270
|
+
const hasExplicitPayload = Object.hasOwn(options, "payload");
|
|
271
|
+
const rawPayload = hasExplicitPayload
|
|
272
|
+
? options.payload
|
|
273
|
+
: await schedule.createPayload?.({ schedule, run });
|
|
274
|
+
|
|
275
|
+
return parseSchedulePayload(schedule, rawPayload);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async function reportHookError<
|
|
279
|
+
Ctx,
|
|
280
|
+
S extends ScheduleDef<string, StandardSchema, Ctx>,
|
|
281
|
+
>(
|
|
282
|
+
onHookError: InlineScheduleRunnerOptions<Ctx>["onHookError"] | undefined,
|
|
283
|
+
args: ScheduleHookErrorArgs<S>,
|
|
284
|
+
): Promise<void> {
|
|
285
|
+
try {
|
|
286
|
+
await onHookError?.(args);
|
|
287
|
+
} catch {
|
|
288
|
+
// Hook failures are isolated from schedule execution.
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async function runLifecycleHook<
|
|
293
|
+
Ctx,
|
|
294
|
+
S extends ScheduleDef<string, StandardSchema, Ctx>,
|
|
295
|
+
>(
|
|
296
|
+
hook: Exclude<ScheduleHookName, "error">,
|
|
297
|
+
handler: ((args: ScheduleLifecycleArgs<S>) => MaybePromise<void>) | undefined,
|
|
298
|
+
onHookError: InlineScheduleRunnerOptions<Ctx>["onHookError"] | undefined,
|
|
299
|
+
args: ScheduleLifecycleArgs<S>,
|
|
300
|
+
): Promise<void> {
|
|
301
|
+
try {
|
|
302
|
+
await handler?.(args);
|
|
303
|
+
} catch (error) {
|
|
304
|
+
await reportHookError(onHookError, { ...args, hook, error });
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
async function runErrorHook<
|
|
309
|
+
Ctx,
|
|
310
|
+
S extends ScheduleDef<string, StandardSchema, Ctx>,
|
|
311
|
+
>(
|
|
312
|
+
handler: ((args: ScheduleErrorArgs<S>) => MaybePromise<void>) | undefined,
|
|
313
|
+
onHookError: InlineScheduleRunnerOptions<Ctx>["onHookError"] | undefined,
|
|
314
|
+
args: ScheduleErrorArgs<S>,
|
|
315
|
+
): Promise<void> {
|
|
316
|
+
try {
|
|
317
|
+
await handler?.(args);
|
|
318
|
+
} catch (error) {
|
|
319
|
+
await reportHookError(onHookError, {
|
|
320
|
+
schedule: args.schedule,
|
|
321
|
+
payload: args.payload,
|
|
322
|
+
run: args.run,
|
|
323
|
+
hook: "error",
|
|
324
|
+
error,
|
|
325
|
+
scheduleError: args.error,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export function defineSchedule<
|
|
331
|
+
Name extends string,
|
|
332
|
+
Payload extends StandardSchema,
|
|
333
|
+
Ctx = unknown,
|
|
334
|
+
>(
|
|
335
|
+
name: Name,
|
|
336
|
+
options: DefineScheduleOptions<Name, Payload, Ctx>,
|
|
337
|
+
): ScheduleDef<Name, Payload, Ctx> {
|
|
338
|
+
return {
|
|
339
|
+
kind: "schedule",
|
|
340
|
+
name,
|
|
341
|
+
cron: options.cron,
|
|
342
|
+
timezone: options.timezone,
|
|
343
|
+
payload: options.payload,
|
|
344
|
+
description: options.description,
|
|
345
|
+
createPayload: options.createPayload as
|
|
346
|
+
| ScheduleDef<Name, Payload, Ctx>["createPayload"]
|
|
347
|
+
| undefined,
|
|
348
|
+
handle: options.handle as ScheduleDef<Name, Payload, Ctx>["handle"],
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export async function parseSchedulePayload<S extends SchedulePayloadDef>(
|
|
353
|
+
schedule: S,
|
|
354
|
+
payload: unknown,
|
|
355
|
+
): Promise<InferSchedulePayload<S>> {
|
|
356
|
+
return (await parsePayload(schedule.payload, payload, {
|
|
357
|
+
name: schedule.name,
|
|
358
|
+
})) as InferSchedulePayload<S>;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export async function runSchedule<
|
|
362
|
+
Ctx,
|
|
363
|
+
S extends ScheduleDef<string, StandardSchema, Ctx>,
|
|
364
|
+
>(
|
|
365
|
+
schedule: S,
|
|
366
|
+
args: ScheduleRunArgs<Ctx, InferSchedulePayload<S>>,
|
|
367
|
+
): Promise<void> {
|
|
368
|
+
const run = createRunContext(args, () => new Date());
|
|
369
|
+
const payload = await resolveSchedulePayload(schedule, args, run);
|
|
370
|
+
|
|
371
|
+
await schedule.handle({
|
|
372
|
+
schedule,
|
|
373
|
+
payload,
|
|
374
|
+
ctx: args.ctx,
|
|
375
|
+
run,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export function createInlineScheduleRunner<Ctx>(
|
|
380
|
+
options: InlineScheduleRunnerOptions<Ctx> = {},
|
|
381
|
+
): InlineScheduleRunner<Ctx> {
|
|
382
|
+
const now = options.now ?? (() => new Date());
|
|
383
|
+
|
|
384
|
+
return {
|
|
385
|
+
async run<S extends ScheduleDef<string, StandardSchema, Ctx>>(
|
|
386
|
+
schedule: S,
|
|
387
|
+
runOptions: ScheduleRunOptions<InferSchedulePayload<S>> = {},
|
|
388
|
+
) {
|
|
389
|
+
const run = createRunContext(runOptions, now);
|
|
390
|
+
let payload: InferSchedulePayload<S> | undefined;
|
|
391
|
+
|
|
392
|
+
try {
|
|
393
|
+
payload = await resolveSchedulePayload(schedule, runOptions, run);
|
|
394
|
+
|
|
395
|
+
const lifecycleArgs = { schedule, payload, run };
|
|
396
|
+
await runLifecycleHook(
|
|
397
|
+
"start",
|
|
398
|
+
options.onStart,
|
|
399
|
+
options.onHookError,
|
|
400
|
+
lifecycleArgs,
|
|
401
|
+
);
|
|
402
|
+
await schedule.handle({
|
|
403
|
+
schedule,
|
|
404
|
+
payload,
|
|
405
|
+
ctx: await resolveCtx(options.ctx),
|
|
406
|
+
run,
|
|
407
|
+
});
|
|
408
|
+
await runLifecycleHook(
|
|
409
|
+
"success",
|
|
410
|
+
options.onSuccess,
|
|
411
|
+
options.onHookError,
|
|
412
|
+
lifecycleArgs,
|
|
413
|
+
);
|
|
414
|
+
} catch (error) {
|
|
415
|
+
await runErrorHook(options.onError, options.onHookError, {
|
|
416
|
+
error,
|
|
417
|
+
schedule,
|
|
418
|
+
payload,
|
|
419
|
+
run,
|
|
420
|
+
});
|
|
421
|
+
throw error;
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export function createScheduleHandlers<Ctx>(): ScheduleHandlers<Ctx> {
|
|
428
|
+
return {
|
|
429
|
+
defineSchedule<Name extends string, Payload extends StandardSchema>(
|
|
430
|
+
name: Name,
|
|
431
|
+
options: DefineScheduleOptions<Name, Payload, Ctx>,
|
|
432
|
+
): ScheduleDef<Name, Payload, Ctx> {
|
|
433
|
+
return defineSchedule(name, options);
|
|
434
|
+
},
|
|
435
|
+
|
|
436
|
+
createInlineScheduleRunner(
|
|
437
|
+
options: InlineScheduleRunnerOptions<Ctx> = {},
|
|
438
|
+
): InlineScheduleRunner<Ctx> {
|
|
439
|
+
return createInlineScheduleRunner(options);
|
|
440
|
+
},
|
|
441
|
+
};
|
|
442
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health check handler
|
|
3
|
+
* Health check handler for Beignet server adapters.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { AnyPorts } from "../ports";
|
|
7
|
+
import type { HttpRequestLike, HttpResponseLike } from "./types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Health check result
|
|
11
|
+
*/
|
|
12
|
+
export interface HealthCheckResult {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
details?: Record<string, { ok: boolean; message?: string }>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Health check configuration
|
|
19
|
+
*/
|
|
20
|
+
export interface HealthConfig<Ports> {
|
|
21
|
+
/** Enable health endpoint (default: false) */
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Suggested path for the health endpoint (e.g., "/api/health").
|
|
25
|
+
* NOTE: This field is for documentation/metadata only and does not control routing.
|
|
26
|
+
* You must manually wire the healthHandler to your desired route.
|
|
27
|
+
*/
|
|
28
|
+
suggestedPath?: string;
|
|
29
|
+
/** Custom health check function */
|
|
30
|
+
check?: (ports: Ports) => Promise<HealthCheckResult>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Application environment type
|
|
35
|
+
*/
|
|
36
|
+
export type AppEnvironment = "development" | "production" | "test";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create a health check handler
|
|
40
|
+
* Returns a function that can be called with an HttpRequestLike to get an HttpResponseLike
|
|
41
|
+
*/
|
|
42
|
+
export function createHealthHandler<Ports extends AnyPorts>(
|
|
43
|
+
ports: Ports,
|
|
44
|
+
healthConfig: HealthConfig<Ports> | undefined,
|
|
45
|
+
env: AppEnvironment,
|
|
46
|
+
): (req: HttpRequestLike) => Promise<HttpResponseLike> {
|
|
47
|
+
return async (_req: HttpRequestLike): Promise<HttpResponseLike> => {
|
|
48
|
+
let result: HealthCheckResult;
|
|
49
|
+
if (healthConfig?.check) {
|
|
50
|
+
try {
|
|
51
|
+
result = await healthConfig.check(ports);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// Health check function threw - treat as unhealthy
|
|
54
|
+
// Only include error details in development/test to avoid leaking sensitive info
|
|
55
|
+
const includeErrorDetails = env === "development" || env === "test";
|
|
56
|
+
result = {
|
|
57
|
+
ok: false,
|
|
58
|
+
details: {
|
|
59
|
+
error: {
|
|
60
|
+
ok: false,
|
|
61
|
+
message: includeErrorDetails
|
|
62
|
+
? error instanceof Error
|
|
63
|
+
? error.message
|
|
64
|
+
: String(error)
|
|
65
|
+
: "Health check failed",
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
result = { ok: true };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const status = result.ok ? 200 : 503;
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
status,
|
|
78
|
+
body: result,
|
|
79
|
+
headers: { "Content-Type": "application/json" },
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type AuthPort,
|
|
3
|
+
type AuthSession,
|
|
4
|
+
AuthUnauthorizedError,
|
|
5
|
+
} from "../../ports";
|
|
6
|
+
import type { HttpRequestLike, HttpResponse, ServerHook } from "../types";
|
|
7
|
+
|
|
8
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
9
|
+
|
|
10
|
+
export type AuthHookMode = "public" | "optional" | "required";
|
|
11
|
+
export type AuthHookModeInput = AuthHookMode | boolean | null | undefined;
|
|
12
|
+
|
|
13
|
+
export type CtxWithAuthPort = {
|
|
14
|
+
ports: {
|
|
15
|
+
auth: AuthPort;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type AuthHookArgs<Ctx> = {
|
|
20
|
+
req: HttpRequestLike;
|
|
21
|
+
ctx: Ctx;
|
|
22
|
+
contract: {
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
};
|
|
25
|
+
path: unknown;
|
|
26
|
+
query: unknown;
|
|
27
|
+
headers: unknown;
|
|
28
|
+
body: unknown;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type AuthHookAssignArgs<Ctx, Session> = AuthHookArgs<Ctx> & {
|
|
32
|
+
session: Session | null;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type AuthHookUnauthorizedArgs<Ctx, Session> = AuthHookArgs<Ctx> & {
|
|
36
|
+
session: Session | null;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type AuthHooksOptions<Ctx, Session> = {
|
|
40
|
+
name?: string;
|
|
41
|
+
mode?: (args: AuthHookArgs<Ctx>) => MaybePromise<AuthHookModeInput>;
|
|
42
|
+
getSession?: (args: AuthHookArgs<Ctx>) => MaybePromise<Session | null>;
|
|
43
|
+
isAuthenticated?: (session: Session | null) => boolean;
|
|
44
|
+
assign?: (args: AuthHookAssignArgs<Ctx, Session>) => MaybePromise<Ctx>;
|
|
45
|
+
unauthorized?: (
|
|
46
|
+
args: AuthHookUnauthorizedArgs<Ctx, Session>,
|
|
47
|
+
) => MaybePromise<HttpResponse>;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type InferAuthSession<TAuth> =
|
|
51
|
+
TAuth extends AuthPort<infer User, infer SessionMetadata>
|
|
52
|
+
? AuthSession<User, SessionMetadata>
|
|
53
|
+
: unknown;
|
|
54
|
+
|
|
55
|
+
function modeFromInput(input: AuthHookModeInput): AuthHookMode {
|
|
56
|
+
if (input === true || input === "required") return "required";
|
|
57
|
+
if (input === "optional") return "optional";
|
|
58
|
+
return "public";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function defaultMode<Ctx>(args: AuthHookArgs<Ctx>): AuthHookMode {
|
|
62
|
+
return modeFromInput(args.contract.metadata?.auth as AuthHookModeInput);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function defaultGetSession<Ctx>(
|
|
66
|
+
args: AuthHookArgs<Ctx>,
|
|
67
|
+
): Promise<unknown | null> {
|
|
68
|
+
const auth = (args.ctx as { ports?: { auth?: AuthPort } }).ports?.auth;
|
|
69
|
+
if (!auth) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"createAuthHooks requires ctx.ports.auth or an explicit getSession option.",
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return auth.getSession(args.req);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function defaultIsAuthenticated<Session>(session: Session | null): boolean {
|
|
79
|
+
return session !== null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function createAuthHooks<Ctx extends CtxWithAuthPort>(
|
|
83
|
+
options?: AuthHooksOptions<Ctx, InferAuthSession<Ctx["ports"]["auth"]>>,
|
|
84
|
+
): ServerHook<Ctx, Ctx["ports"]>;
|
|
85
|
+
export function createAuthHooks<Ctx, Session>(
|
|
86
|
+
options: AuthHooksOptions<Ctx, Session> & {
|
|
87
|
+
getSession: (args: AuthHookArgs<Ctx>) => MaybePromise<Session | null>;
|
|
88
|
+
},
|
|
89
|
+
): ServerHook<Ctx>;
|
|
90
|
+
export function createAuthHooks<Ctx, Session>(
|
|
91
|
+
options: AuthHooksOptions<Ctx, Session> = {},
|
|
92
|
+
): ServerHook<Ctx> {
|
|
93
|
+
return {
|
|
94
|
+
name: options.name ?? "auth",
|
|
95
|
+
beforeHandle: async ({
|
|
96
|
+
req,
|
|
97
|
+
ctx,
|
|
98
|
+
contract,
|
|
99
|
+
path,
|
|
100
|
+
query,
|
|
101
|
+
headers,
|
|
102
|
+
body,
|
|
103
|
+
}) => {
|
|
104
|
+
const args: AuthHookArgs<Ctx> = {
|
|
105
|
+
req,
|
|
106
|
+
ctx,
|
|
107
|
+
contract,
|
|
108
|
+
path,
|
|
109
|
+
query,
|
|
110
|
+
headers,
|
|
111
|
+
body,
|
|
112
|
+
};
|
|
113
|
+
const mode = modeFromInput(
|
|
114
|
+
options.mode ? await options.mode(args) : defaultMode(args),
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
if (mode === "public") {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const session = options.getSession
|
|
122
|
+
? await options.getSession(args)
|
|
123
|
+
: ((await defaultGetSession(args)) as Session | null);
|
|
124
|
+
const isAuthenticated =
|
|
125
|
+
options.isAuthenticated?.(session) ?? defaultIsAuthenticated(session);
|
|
126
|
+
|
|
127
|
+
if (mode === "required" && !isAuthenticated) {
|
|
128
|
+
if (options.unauthorized) {
|
|
129
|
+
return {
|
|
130
|
+
ctx,
|
|
131
|
+
response: await options.unauthorized({ ...args, session }),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
throw new AuthUnauthorizedError();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!options.assign) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
ctx: await options.assign({ ...args, session }),
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|