@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
package/src/ports/auth.ts
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal request shape consumed by Beignet auth ports.
|
|
3
|
+
*
|
|
4
|
+
* Framework adapters can pass richer request objects, but auth providers should
|
|
5
|
+
* only rely on headers and the optional raw platform request unless they
|
|
6
|
+
* declare a more specific `RequestLike` type.
|
|
7
|
+
*/
|
|
1
8
|
export interface AuthRequestLike {
|
|
9
|
+
/**
|
|
10
|
+
* Request headers used for cookies, bearer tokens, API keys, or provider
|
|
11
|
+
* specific auth data.
|
|
12
|
+
*/
|
|
2
13
|
headers: Headers;
|
|
14
|
+
/**
|
|
15
|
+
* Raw platform request, when the runtime has one available.
|
|
16
|
+
*/
|
|
3
17
|
raw?: Request;
|
|
4
18
|
}
|
|
5
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Normalized authenticated session returned by an `AuthPort`.
|
|
22
|
+
*
|
|
23
|
+
* `user` is the app/provider user object. `session` can carry provider-specific
|
|
24
|
+
* session state such as cookie session metadata or token claims.
|
|
25
|
+
*/
|
|
6
26
|
export interface AuthSession<User = unknown, Session = unknown> {
|
|
7
27
|
user: User;
|
|
8
28
|
session?: Session;
|
|
9
29
|
}
|
|
10
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Error thrown by auth helpers when a route or workflow requires a user but no
|
|
33
|
+
* authenticated user is available.
|
|
34
|
+
*/
|
|
11
35
|
export class AuthUnauthorizedError extends Error {
|
|
12
36
|
readonly code = "UNAUTHORIZED";
|
|
13
37
|
|
|
@@ -17,24 +41,61 @@ export class AuthUnauthorizedError extends Error {
|
|
|
17
41
|
}
|
|
18
42
|
}
|
|
19
43
|
|
|
44
|
+
/**
|
|
45
|
+
* App-facing authentication port.
|
|
46
|
+
*
|
|
47
|
+
* Implement this with a provider adapter such as Better Auth, a custom session
|
|
48
|
+
* lookup, or a test fake. The port identifies the current user; it does not
|
|
49
|
+
* decide whether that user may perform a business action. Keep authorization in
|
|
50
|
+
* policies or use cases.
|
|
51
|
+
*/
|
|
20
52
|
export interface AuthPort<
|
|
21
53
|
User = unknown,
|
|
22
54
|
Session = unknown,
|
|
23
55
|
RequestLike extends AuthRequestLike = AuthRequestLike,
|
|
24
56
|
> {
|
|
57
|
+
/**
|
|
58
|
+
* Return the current session, or `null` when the request is unauthenticated.
|
|
59
|
+
*/
|
|
25
60
|
getSession(req: RequestLike): Promise<AuthSession<User, Session> | null>;
|
|
61
|
+
/**
|
|
62
|
+
* Return the current user, or `null` when unauthenticated.
|
|
63
|
+
*/
|
|
26
64
|
getUser(req: RequestLike): Promise<User | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Return the current user or throw `AuthUnauthorizedError`.
|
|
67
|
+
*/
|
|
27
68
|
requireUser(req: RequestLike): Promise<User>;
|
|
28
69
|
}
|
|
29
70
|
|
|
30
71
|
type MaybePromise<T> = T | Promise<T>;
|
|
31
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Request-aware factory for a static auth session.
|
|
75
|
+
*/
|
|
32
76
|
export type StaticAuthSessionFactory<
|
|
33
77
|
User,
|
|
34
78
|
Session,
|
|
35
79
|
RequestLike extends AuthRequestLike,
|
|
36
80
|
> = (req: RequestLike) => MaybePromise<AuthSession<User, Session> | null>;
|
|
37
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Create an auth port from a fixed session or request-aware session factory.
|
|
84
|
+
*
|
|
85
|
+
* This is useful for tests, examples, and simple apps. Production apps usually
|
|
86
|
+
* use a provider-backed auth port that verifies cookies, tokens, or sessions.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const auth = createStaticAuth({
|
|
91
|
+
* user: { id: "user_1", name: "Ada" },
|
|
92
|
+
* });
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @param session - Fixed session, `null`, or a function that resolves a session
|
|
96
|
+
* from the request.
|
|
97
|
+
* @returns An `AuthPort` implementation backed by the provided session source.
|
|
98
|
+
*/
|
|
38
99
|
export function createStaticAuth<
|
|
39
100
|
User,
|
|
40
101
|
Session = unknown,
|
|
@@ -67,6 +128,15 @@ export function createStaticAuth<
|
|
|
67
128
|
};
|
|
68
129
|
}
|
|
69
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Create an auth port that always treats requests as unauthenticated.
|
|
133
|
+
*
|
|
134
|
+
* Use this in tests or examples where auth is intentionally absent. It is not a
|
|
135
|
+
* security boundary; it simply returns `null` from `getSession`/`getUser` and
|
|
136
|
+
* throws from `requireUser`.
|
|
137
|
+
*
|
|
138
|
+
* @returns An `AuthPort` with no active session.
|
|
139
|
+
*/
|
|
70
140
|
export function createAnonymousAuth<
|
|
71
141
|
User = unknown,
|
|
72
142
|
Session = unknown,
|
package/src/ports/cache.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for storing a cache value.
|
|
3
|
+
*/
|
|
1
4
|
export interface CacheSetOptions {
|
|
2
5
|
/**
|
|
3
6
|
* Time-to-live in seconds. Omit this for a value that does not expire.
|
|
@@ -5,11 +8,39 @@ export interface CacheSetOptions {
|
|
|
5
8
|
ttlSeconds?: number;
|
|
6
9
|
}
|
|
7
10
|
|
|
11
|
+
/**
|
|
12
|
+
* App-facing string cache port.
|
|
13
|
+
*
|
|
14
|
+
* Values are intentionally strings so adapters can map cleanly to Redis,
|
|
15
|
+
* Upstash, and other key/value stores. Serialize structured values at the app
|
|
16
|
+
* boundary.
|
|
17
|
+
*/
|
|
8
18
|
export interface CachePort {
|
|
19
|
+
/**
|
|
20
|
+
* Return a fresh value for `key`, or `null` when missing or expired.
|
|
21
|
+
*/
|
|
9
22
|
get(key: string): Promise<string | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Store a string value.
|
|
25
|
+
*/
|
|
10
26
|
set(key: string, value: string, options?: CacheSetOptions): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Delete a cache key.
|
|
29
|
+
*
|
|
30
|
+
* @returns `true` when the key existed.
|
|
31
|
+
*/
|
|
11
32
|
delete(key: string): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Return whether a fresh value exists for `key`.
|
|
35
|
+
*/
|
|
12
36
|
has(key: string): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Return a cached value or compute, store, and return a new value.
|
|
39
|
+
*
|
|
40
|
+
* Implementations are not required to provide single-flight behavior. If
|
|
41
|
+
* concurrent cache fills matter, choose an adapter that documents that
|
|
42
|
+
* guarantee or protect the factory at the application layer.
|
|
43
|
+
*/
|
|
13
44
|
remember(
|
|
14
45
|
key: string,
|
|
15
46
|
factory: () => Promise<string>,
|
|
@@ -38,6 +69,16 @@ function isExpired(entry: MemoryCacheEntry): boolean {
|
|
|
38
69
|
return entry.expiresAt != null && entry.expiresAt <= Date.now();
|
|
39
70
|
}
|
|
40
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Create an in-memory cache for tests, examples, and single-process
|
|
74
|
+
* development.
|
|
75
|
+
*
|
|
76
|
+
* This adapter is not durable or distributed. Values are lost when the process
|
|
77
|
+
* exits and are not shared across workers, regions, or serverless invocations.
|
|
78
|
+
*
|
|
79
|
+
* @param initialValues - Optional initial string values without TTL.
|
|
80
|
+
* @returns A cache port backed by a local `Map`.
|
|
81
|
+
*/
|
|
41
82
|
export function createMemoryCache(
|
|
42
83
|
initialValues: Record<string, string> = {},
|
|
43
84
|
): CachePort {
|
package/src/ports/clock.ts
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App-facing time source.
|
|
3
|
+
*
|
|
4
|
+
* Use this port anywhere deterministic time matters, such as use-case tests,
|
|
5
|
+
* scheduled work, idempotency windows, or audit timestamps.
|
|
6
|
+
*/
|
|
1
7
|
export interface ClockPort {
|
|
8
|
+
/**
|
|
9
|
+
* Return the current time according to this clock.
|
|
10
|
+
*/
|
|
2
11
|
now(): Date;
|
|
3
12
|
}
|
|
4
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Mutable clock implementation used by tests.
|
|
16
|
+
*/
|
|
5
17
|
export interface FrozenClockPort extends ClockPort {
|
|
18
|
+
/**
|
|
19
|
+
* Replace the current time.
|
|
20
|
+
*/
|
|
6
21
|
setNow(value: Date | string | number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Move the current time forward by the given number of milliseconds.
|
|
24
|
+
*/
|
|
7
25
|
advance(milliseconds: number): void;
|
|
8
26
|
}
|
|
9
27
|
|
|
@@ -11,12 +29,32 @@ function toDate(value: Date | string | number): Date {
|
|
|
11
29
|
return value instanceof Date ? new Date(value.getTime()) : new Date(value);
|
|
12
30
|
}
|
|
13
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Create a clock backed by `new Date()`.
|
|
34
|
+
*
|
|
35
|
+
* Use this as the default production `ClockPort` when the app does not need a
|
|
36
|
+
* provider-specific time source.
|
|
37
|
+
*
|
|
38
|
+
* @returns A clock that reads the current system time.
|
|
39
|
+
*/
|
|
14
40
|
export function createSystemClock(): ClockPort {
|
|
15
41
|
return {
|
|
16
42
|
now: () => new Date(),
|
|
17
43
|
};
|
|
18
44
|
}
|
|
19
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Create a mutable clock for deterministic tests.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const clock = createFrozenClock("2026-01-01T00:00:00.000Z");
|
|
52
|
+
* clock.advance(1000);
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @param initial - Initial time for the clock. Defaults to Unix epoch.
|
|
56
|
+
* @returns A clock whose time can be replaced or advanced.
|
|
57
|
+
*/
|
|
20
58
|
export function createFrozenClock(
|
|
21
59
|
initial: Date | string | number = new Date(0),
|
|
22
60
|
): FrozenClockPort {
|
|
@@ -1,11 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App-facing ID generation port.
|
|
3
|
+
*
|
|
4
|
+
* Use this when deterministic IDs matter in use-case tests or when production
|
|
5
|
+
* infrastructure owns ID generation.
|
|
6
|
+
*/
|
|
1
7
|
export interface IdGeneratorPort {
|
|
8
|
+
/**
|
|
9
|
+
* Return the next ID.
|
|
10
|
+
*/
|
|
2
11
|
nextId(): string;
|
|
3
12
|
}
|
|
4
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Mutable sequential ID generator used by tests and simple examples.
|
|
16
|
+
*/
|
|
5
17
|
export interface SequenceIdGeneratorPort extends IdGeneratorPort {
|
|
18
|
+
/**
|
|
19
|
+
* Reset the next sequence value.
|
|
20
|
+
*/
|
|
6
21
|
reset(next?: number): void;
|
|
7
22
|
}
|
|
8
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Create an ID generator backed by `globalThis.crypto.randomUUID()`.
|
|
26
|
+
*
|
|
27
|
+
* The factory itself does not read from `crypto`; the returned generator's
|
|
28
|
+
* `nextId()` method throws if the current runtime does not expose
|
|
29
|
+
* `globalThis.crypto.randomUUID()`.
|
|
30
|
+
*
|
|
31
|
+
* @returns An ID generator that returns UUID strings from `nextId()`.
|
|
32
|
+
*/
|
|
9
33
|
export function createUuidIdGenerator(): IdGeneratorPort {
|
|
10
34
|
return {
|
|
11
35
|
nextId: () => {
|
|
@@ -20,6 +44,19 @@ export function createUuidIdGenerator(): IdGeneratorPort {
|
|
|
20
44
|
};
|
|
21
45
|
}
|
|
22
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Create a deterministic sequence ID generator for tests and examples.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* const ids = createSequenceIdGenerator({ prefix: "post", start: 10 });
|
|
53
|
+
* ids.nextId(); // "post_10"
|
|
54
|
+
* ids.nextId(); // "post_11"
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @param options - Optional ID prefix and starting sequence number.
|
|
58
|
+
* @returns A mutable sequence ID generator.
|
|
59
|
+
*/
|
|
23
60
|
export function createSequenceIdGenerator(
|
|
24
61
|
options: { prefix?: string; start?: number } = {},
|
|
25
62
|
): SequenceIdGeneratorPort {
|
package/src/ports/index.ts
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* - `EventBusPort` – interface for event bus implementations
|
|
11
11
|
* - `JobDispatcherPort` – interface for job dispatch implementations
|
|
12
12
|
* - `UnitOfWorkPort` – interface for app-owned transaction boundaries
|
|
13
|
+
* - `OutboxPort` – interface for durable event/job delivery storage
|
|
14
|
+
* - `IdempotencyPort` – interface for retry-safe command/key storage
|
|
13
15
|
* - `AuthPort` – interface for request authentication implementations
|
|
14
16
|
* - `AuditLogPort` – interface for audit/activity log implementations
|
|
15
17
|
* - `ClockPort` – interface for deterministic time
|
|
@@ -21,7 +23,10 @@
|
|
|
21
23
|
* - `StoragePort` – interface for object/file storage implementations
|
|
22
24
|
*
|
|
23
25
|
* Dedicated framework areas own their capability-specific APIs:
|
|
26
|
+
* - `@beignet/core/idempotency` owns idempotency helpers and test adapters
|
|
24
27
|
* - `@beignet/core/mail` owns `MailerPort` and mail test adapters
|
|
28
|
+
* - `@beignet/core/notifications` owns notification helpers and test adapters
|
|
29
|
+
* - `@beignet/core/outbox` owns durable outbox helpers and test adapters
|
|
25
30
|
* - `@beignet/core/schedules` owns scheduled task definitions and runners
|
|
26
31
|
*/
|
|
27
32
|
|
|
@@ -79,6 +84,44 @@ export interface PortsContext<P extends AnyPorts = AnyPorts> {
|
|
|
79
84
|
ports: P;
|
|
80
85
|
}
|
|
81
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Idempotency port exports.
|
|
89
|
+
*/
|
|
90
|
+
export type {
|
|
91
|
+
IdempotencyCompleteInput,
|
|
92
|
+
IdempotencyFailInput,
|
|
93
|
+
IdempotencyPort,
|
|
94
|
+
IdempotencyReservation,
|
|
95
|
+
IdempotencyReserveInput,
|
|
96
|
+
} from "../idempotency";
|
|
97
|
+
/**
|
|
98
|
+
* Notification port exports.
|
|
99
|
+
*/
|
|
100
|
+
export type {
|
|
101
|
+
MemoryNotificationDelivery,
|
|
102
|
+
MemoryNotificationPort,
|
|
103
|
+
NotificationChannelResult,
|
|
104
|
+
NotificationPort,
|
|
105
|
+
SendNotificationOptions,
|
|
106
|
+
SendNotificationResult,
|
|
107
|
+
} from "../notifications";
|
|
108
|
+
/**
|
|
109
|
+
* Transactional outbox port exports.
|
|
110
|
+
*/
|
|
111
|
+
export type {
|
|
112
|
+
ClaimedOutboxMessage,
|
|
113
|
+
OutboxClaimBatchOptions,
|
|
114
|
+
OutboxEnqueueInput,
|
|
115
|
+
OutboxMarkDeliveredInput,
|
|
116
|
+
OutboxMarkFailedInput,
|
|
117
|
+
OutboxMessage,
|
|
118
|
+
OutboxMessageKind,
|
|
119
|
+
OutboxMessageStatus,
|
|
120
|
+
OutboxPort,
|
|
121
|
+
} from "../outbox";
|
|
122
|
+
/**
|
|
123
|
+
* Audit log port exports.
|
|
124
|
+
*/
|
|
82
125
|
export type {
|
|
83
126
|
ActivityActor,
|
|
84
127
|
ActivityActorType,
|
|
@@ -93,6 +136,9 @@ export type {
|
|
|
93
136
|
AuditOutcome,
|
|
94
137
|
MemoryAuditLogPort,
|
|
95
138
|
} from "./audit";
|
|
139
|
+
/**
|
|
140
|
+
* Audit log helper exports.
|
|
141
|
+
*/
|
|
96
142
|
export {
|
|
97
143
|
createAnonymousActor,
|
|
98
144
|
createMemoryAuditLog,
|
|
@@ -104,30 +150,50 @@ export {
|
|
|
104
150
|
normalizeAuditLogEntry,
|
|
105
151
|
redactAuditLogEntry,
|
|
106
152
|
} from "./audit";
|
|
153
|
+
/**
|
|
154
|
+
* Auth port exports.
|
|
155
|
+
*/
|
|
107
156
|
export type {
|
|
108
157
|
AuthPort,
|
|
109
158
|
AuthRequestLike,
|
|
110
159
|
AuthSession,
|
|
111
160
|
StaticAuthSessionFactory,
|
|
112
161
|
} from "./auth";
|
|
162
|
+
/**
|
|
163
|
+
* Auth helper exports.
|
|
164
|
+
*/
|
|
113
165
|
export {
|
|
114
166
|
AuthUnauthorizedError,
|
|
115
167
|
createAnonymousAuth,
|
|
116
168
|
createStaticAuth,
|
|
117
169
|
} from "./auth";
|
|
118
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Ports builder exports.
|
|
172
|
+
*/
|
|
119
173
|
export {
|
|
120
174
|
createPortsBuilder,
|
|
121
175
|
type PortsBuilder,
|
|
122
176
|
type PortsOf,
|
|
123
177
|
} from "./builder";
|
|
178
|
+
/**
|
|
179
|
+
* Cache port exports.
|
|
180
|
+
*/
|
|
124
181
|
export type { CachePort, CacheSetOptions } from "./cache";
|
|
125
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Cache helper exports.
|
|
184
|
+
*/
|
|
126
185
|
export { createMemoryCache } from "./cache";
|
|
127
|
-
|
|
186
|
+
/**
|
|
187
|
+
* Clock port exports.
|
|
188
|
+
*/
|
|
128
189
|
export type { ClockPort, FrozenClockPort } from "./clock";
|
|
190
|
+
/**
|
|
191
|
+
* Clock helper exports.
|
|
192
|
+
*/
|
|
129
193
|
export { createFrozenClock, createSystemClock } from "./clock";
|
|
130
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Event bus and job dispatcher port exports.
|
|
196
|
+
*/
|
|
131
197
|
export type {
|
|
132
198
|
DomainEventDef,
|
|
133
199
|
EventBusPort,
|
|
@@ -136,21 +202,33 @@ export type {
|
|
|
136
202
|
JobDef,
|
|
137
203
|
JobDispatcherPort,
|
|
138
204
|
} from "./events";
|
|
139
|
-
|
|
205
|
+
/**
|
|
206
|
+
* ID generator port exports.
|
|
207
|
+
*/
|
|
140
208
|
export type { IdGeneratorPort, SequenceIdGeneratorPort } from "./id-generator";
|
|
209
|
+
/**
|
|
210
|
+
* ID generator helper exports.
|
|
211
|
+
*/
|
|
141
212
|
export {
|
|
142
213
|
createSequenceIdGenerator,
|
|
143
214
|
createUuidIdGenerator,
|
|
144
215
|
} from "./id-generator";
|
|
145
|
-
|
|
216
|
+
/**
|
|
217
|
+
* Logger port exports.
|
|
218
|
+
*/
|
|
146
219
|
export type {
|
|
147
220
|
LoggerPort,
|
|
148
221
|
LogLevel,
|
|
149
222
|
MemoryLogEntry,
|
|
150
223
|
MemoryLoggerPort,
|
|
151
224
|
} from "./logger";
|
|
225
|
+
/**
|
|
226
|
+
* Logger helper exports.
|
|
227
|
+
*/
|
|
152
228
|
export { createMemoryLogger, createNoopLogger } from "./logger";
|
|
153
|
-
|
|
229
|
+
/**
|
|
230
|
+
* Policy and authorization gate type exports.
|
|
231
|
+
*/
|
|
154
232
|
export type {
|
|
155
233
|
BoundGate,
|
|
156
234
|
CreateGateOptions,
|
|
@@ -166,6 +244,9 @@ export type {
|
|
|
166
244
|
PolicyResolver,
|
|
167
245
|
PolicySubjectArgs,
|
|
168
246
|
} from "./policy";
|
|
247
|
+
/**
|
|
248
|
+
* Policy and authorization gate helper exports.
|
|
249
|
+
*/
|
|
169
250
|
export {
|
|
170
251
|
allow,
|
|
171
252
|
createGate,
|
|
@@ -173,14 +254,21 @@ export {
|
|
|
173
254
|
deny,
|
|
174
255
|
GateAuthorizationError,
|
|
175
256
|
} from "./policy";
|
|
257
|
+
/**
|
|
258
|
+
* Rate limit port exports.
|
|
259
|
+
*/
|
|
176
260
|
export type {
|
|
177
261
|
RateLimitHitOptions,
|
|
178
262
|
RateLimitPort,
|
|
179
263
|
RateLimitResult,
|
|
180
264
|
} from "./rate-limit";
|
|
181
|
-
|
|
265
|
+
/**
|
|
266
|
+
* Rate limit helper exports.
|
|
267
|
+
*/
|
|
182
268
|
export { createMemoryRateLimiter } from "./rate-limit";
|
|
183
|
-
|
|
269
|
+
/**
|
|
270
|
+
* Redaction helper exports.
|
|
271
|
+
*/
|
|
184
272
|
export {
|
|
185
273
|
createRedactor,
|
|
186
274
|
DEFAULT_CIRCULAR_VALUE,
|
|
@@ -196,7 +284,9 @@ export {
|
|
|
196
284
|
redactHeaders,
|
|
197
285
|
redactValue,
|
|
198
286
|
} from "./redaction";
|
|
199
|
-
|
|
287
|
+
/**
|
|
288
|
+
* Storage port exports.
|
|
289
|
+
*/
|
|
200
290
|
export type {
|
|
201
291
|
MemoryStorageOptions,
|
|
202
292
|
StorageBody,
|
|
@@ -207,8 +297,13 @@ export type {
|
|
|
207
297
|
StoragePutOptions,
|
|
208
298
|
StorageVisibility,
|
|
209
299
|
} from "./storage";
|
|
300
|
+
/**
|
|
301
|
+
* Storage helper exports.
|
|
302
|
+
*/
|
|
210
303
|
export { createMemoryStorage } from "./storage";
|
|
211
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Unit of Work port exports.
|
|
306
|
+
*/
|
|
212
307
|
export {
|
|
213
308
|
type BufferedDomainEventRecorder,
|
|
214
309
|
createDomainEventRecorder,
|
package/src/ports/logger.ts
CHANGED
|
@@ -1,15 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported structured logger levels.
|
|
3
|
+
*/
|
|
1
4
|
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
2
5
|
|
|
6
|
+
/**
|
|
7
|
+
* App-facing structured logger port.
|
|
8
|
+
*
|
|
9
|
+
* Application code logs through this interface so production can use Pino,
|
|
10
|
+
* Datadog, or another adapter while tests can use no-op or memory loggers.
|
|
11
|
+
*/
|
|
3
12
|
export interface LoggerPort {
|
|
13
|
+
/**
|
|
14
|
+
* Log very detailed diagnostic information.
|
|
15
|
+
*/
|
|
4
16
|
trace(message: string, meta?: Record<string, unknown>): void;
|
|
17
|
+
/**
|
|
18
|
+
* Log debug-level diagnostic information.
|
|
19
|
+
*/
|
|
5
20
|
debug(message: string, meta?: Record<string, unknown>): void;
|
|
21
|
+
/**
|
|
22
|
+
* Log normal application progress.
|
|
23
|
+
*/
|
|
6
24
|
info(message: string, meta?: Record<string, unknown>): void;
|
|
25
|
+
/**
|
|
26
|
+
* Log recoverable problems or unusual conditions.
|
|
27
|
+
*/
|
|
7
28
|
warn(message: string, meta?: Record<string, unknown>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Log failed operations.
|
|
31
|
+
*/
|
|
8
32
|
error(message: string, meta?: Record<string, unknown>): void;
|
|
33
|
+
/**
|
|
34
|
+
* Log unrecoverable failures.
|
|
35
|
+
*/
|
|
9
36
|
fatal(message: string, meta?: Record<string, unknown>): void;
|
|
37
|
+
/**
|
|
38
|
+
* Return a logger with additional structured bindings.
|
|
39
|
+
*/
|
|
10
40
|
child(bindings: Record<string, unknown>): LoggerPort;
|
|
11
41
|
}
|
|
12
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Captured entry from `createMemoryLogger(...)`.
|
|
45
|
+
*/
|
|
13
46
|
export interface MemoryLogEntry {
|
|
14
47
|
level: LogLevel;
|
|
15
48
|
message: string;
|
|
@@ -17,10 +50,23 @@ export interface MemoryLogEntry {
|
|
|
17
50
|
bindings: Record<string, unknown>;
|
|
18
51
|
}
|
|
19
52
|
|
|
53
|
+
/**
|
|
54
|
+
* In-memory logger port used by tests and local assertions.
|
|
55
|
+
*/
|
|
20
56
|
export interface MemoryLoggerPort extends LoggerPort {
|
|
57
|
+
/**
|
|
58
|
+
* Captured log entries in call order.
|
|
59
|
+
*/
|
|
21
60
|
entries: MemoryLogEntry[];
|
|
22
61
|
}
|
|
23
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Create a logger that discards every log call.
|
|
65
|
+
*
|
|
66
|
+
* Use this in tests where logging is irrelevant.
|
|
67
|
+
*
|
|
68
|
+
* @returns A logger port whose methods are no-ops.
|
|
69
|
+
*/
|
|
24
70
|
export function createNoopLogger(): LoggerPort {
|
|
25
71
|
const logger: LoggerPort = {
|
|
26
72
|
trace: () => {},
|
|
@@ -35,6 +81,16 @@ export function createNoopLogger(): LoggerPort {
|
|
|
35
81
|
return logger;
|
|
36
82
|
}
|
|
37
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Create a logger that captures entries in memory.
|
|
86
|
+
*
|
|
87
|
+
* Child loggers inherit existing bindings and append new bindings to each
|
|
88
|
+
* captured entry.
|
|
89
|
+
*
|
|
90
|
+
* @param bindings - Structured bindings attached to every captured entry.
|
|
91
|
+
* @param entries - Optional shared entry array.
|
|
92
|
+
* @returns A logger port with an inspectable `entries` array.
|
|
93
|
+
*/
|
|
38
94
|
export function createMemoryLogger(
|
|
39
95
|
bindings: Record<string, unknown> = {},
|
|
40
96
|
entries: MemoryLogEntry[] = [],
|