@heavybit/shared-lib 0.0.0-stage → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/access/index.js +118 -0
- package/dist/cjs/access/index.js.map +1 -0
- package/dist/cjs/alerting/index.js +56 -0
- package/dist/cjs/alerting/index.js.map +1 -0
- package/dist/cjs/cache/index.js +167 -0
- package/dist/cjs/cache/index.js.map +1 -0
- package/dist/cjs/common/async.js +40 -0
- package/dist/cjs/common/async.js.map +1 -0
- package/dist/cjs/common/audit.js +21 -0
- package/dist/cjs/common/audit.js.map +1 -0
- package/dist/cjs/common/crypto.js +75 -0
- package/dist/cjs/common/crypto.js.map +1 -0
- package/dist/cjs/common/errors.js +90 -0
- package/dist/cjs/common/errors.js.map +1 -0
- package/dist/cjs/common/id.js +40 -0
- package/dist/cjs/common/id.js.map +1 -0
- package/dist/cjs/common/index.js +28 -0
- package/dist/cjs/common/index.js.map +1 -0
- package/dist/cjs/common/jwt.js +59 -0
- package/dist/cjs/common/jwt.js.map +1 -0
- package/dist/cjs/common/password.js +38 -0
- package/dist/cjs/common/password.js.map +1 -0
- package/dist/cjs/common/phone.js +42 -0
- package/dist/cjs/common/phone.js.map +1 -0
- package/dist/cjs/common/response.js +32 -0
- package/dist/cjs/common/response.js.map +1 -0
- package/dist/cjs/common/text.js +46 -0
- package/dist/cjs/common/text.js.map +1 -0
- package/dist/cjs/common/time.js +109 -0
- package/dist/cjs/common/time.js.map +1 -0
- package/dist/cjs/config/index.js +96 -0
- package/dist/cjs/config/index.js.map +1 -0
- package/dist/cjs/contracts/editorial-draft.js +111 -0
- package/dist/cjs/contracts/editorial-draft.js.map +1 -0
- package/dist/cjs/contracts/index.js +20 -0
- package/dist/cjs/contracts/index.js.map +1 -0
- package/dist/cjs/contracts/notification-dispatch.js +92 -0
- package/dist/cjs/contracts/notification-dispatch.js.map +1 -0
- package/dist/cjs/contracts/upload-import.js +54 -0
- package/dist/cjs/contracts/upload-import.js.map +1 -0
- package/dist/cjs/database/index.js +57 -0
- package/dist/cjs/database/index.js.map +1 -0
- package/dist/cjs/express/auth.js +72 -0
- package/dist/cjs/express/auth.js.map +1 -0
- package/dist/cjs/express/health.js +31 -0
- package/dist/cjs/express/health.js.map +1 -0
- package/dist/cjs/express/index.js +20 -0
- package/dist/cjs/express/index.js.map +1 -0
- package/dist/cjs/express/middleware.js +95 -0
- package/dist/cjs/express/middleware.js.map +1 -0
- package/dist/cjs/http/index.js +90 -0
- package/dist/cjs/http/index.js.map +1 -0
- package/dist/cjs/http/safe-fetch.js +199 -0
- package/dist/cjs/http/safe-fetch.js.map +1 -0
- package/dist/cjs/identity/index.js +117 -0
- package/dist/cjs/identity/index.js.map +1 -0
- package/dist/cjs/index.js +29 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/knex/index.js +76 -0
- package/dist/cjs/knex/index.js.map +1 -0
- package/dist/cjs/logging/index.js +75 -0
- package/dist/cjs/logging/index.js.map +1 -0
- package/dist/cjs/messaging/connection.js +115 -0
- package/dist/cjs/messaging/connection.js.map +1 -0
- package/dist/cjs/messaging/consumer.js +134 -0
- package/dist/cjs/messaging/consumer.js.map +1 -0
- package/dist/cjs/messaging/envelope.js +23 -0
- package/dist/cjs/messaging/envelope.js.map +1 -0
- package/dist/cjs/messaging/idempotency.js +57 -0
- package/dist/cjs/messaging/idempotency.js.map +1 -0
- package/dist/cjs/messaging/index.js +62 -0
- package/dist/cjs/messaging/index.js.map +1 -0
- package/dist/cjs/messaging/monitor.js +48 -0
- package/dist/cjs/messaging/monitor.js.map +1 -0
- package/dist/cjs/messaging/outbox.js +135 -0
- package/dist/cjs/messaging/outbox.js.map +1 -0
- package/dist/cjs/messaging/publisher.js +149 -0
- package/dist/cjs/messaging/publisher.js.map +1 -0
- package/dist/cjs/messaging/rpc.js +125 -0
- package/dist/cjs/messaging/rpc.js.map +1 -0
- package/dist/cjs/messaging/staff-notifier.js +78 -0
- package/dist/cjs/messaging/staff-notifier.js.map +1 -0
- package/dist/cjs/messaging/topology.js +22 -0
- package/dist/cjs/messaging/topology.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/rate-limit/index.js +61 -0
- package/dist/cjs/rate-limit/index.js.map +1 -0
- package/dist/cjs/scheduling/index.js +88 -0
- package/dist/cjs/scheduling/index.js.map +1 -0
- package/dist/cjs/security/index.js +39 -0
- package/dist/cjs/security/index.js.map +1 -0
- package/dist/cjs/socket/index.js +53 -0
- package/dist/cjs/socket/index.js.map +1 -0
- package/dist/cjs/testing/index.js +73 -0
- package/dist/cjs/testing/index.js.map +1 -0
- package/dist/cjs/types/index.js +3 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/validation/index.js +41 -0
- package/dist/cjs/validation/index.js.map +1 -0
- package/dist/esm/access/index.js +104 -0
- package/dist/esm/access/index.js.map +1 -0
- package/dist/esm/alerting/index.js +52 -0
- package/dist/esm/alerting/index.js.map +1 -0
- package/dist/esm/cache/index.js +163 -0
- package/dist/esm/cache/index.js.map +1 -0
- package/dist/esm/common/async.js +33 -0
- package/dist/esm/common/async.js.map +1 -0
- package/dist/esm/common/audit.js +18 -0
- package/dist/esm/common/audit.js.map +1 -0
- package/dist/esm/common/crypto.js +64 -0
- package/dist/esm/common/crypto.js.map +1 -0
- package/dist/esm/common/errors.js +75 -0
- package/dist/esm/common/errors.js.map +1 -0
- package/dist/esm/common/id.js +33 -0
- package/dist/esm/common/id.js.map +1 -0
- package/dist/esm/common/index.js +12 -0
- package/dist/esm/common/index.js.map +1 -0
- package/dist/esm/common/jwt.js +49 -0
- package/dist/esm/common/jwt.js.map +1 -0
- package/dist/esm/common/password.js +30 -0
- package/dist/esm/common/password.js.map +1 -0
- package/dist/esm/common/phone.js +33 -0
- package/dist/esm/common/phone.js.map +1 -0
- package/dist/esm/common/response.js +24 -0
- package/dist/esm/common/response.js.map +1 -0
- package/dist/esm/common/text.js +39 -0
- package/dist/esm/common/text.js.map +1 -0
- package/dist/esm/common/time.js +96 -0
- package/dist/esm/common/time.js.map +1 -0
- package/dist/esm/config/index.js +88 -0
- package/dist/esm/config/index.js.map +1 -0
- package/dist/esm/contracts/editorial-draft.js +108 -0
- package/dist/esm/contracts/editorial-draft.js.map +1 -0
- package/dist/esm/contracts/index.js +4 -0
- package/dist/esm/contracts/index.js.map +1 -0
- package/dist/esm/contracts/notification-dispatch.js +89 -0
- package/dist/esm/contracts/notification-dispatch.js.map +1 -0
- package/dist/esm/contracts/upload-import.js +51 -0
- package/dist/esm/contracts/upload-import.js.map +1 -0
- package/dist/esm/database/index.js +48 -0
- package/dist/esm/database/index.js.map +1 -0
- package/dist/esm/express/auth.js +63 -0
- package/dist/esm/express/auth.js.map +1 -0
- package/dist/esm/express/health.js +27 -0
- package/dist/esm/express/health.js.map +1 -0
- package/dist/esm/express/index.js +4 -0
- package/dist/esm/express/index.js.map +1 -0
- package/dist/esm/express/middleware.js +84 -0
- package/dist/esm/express/middleware.js.map +1 -0
- package/dist/esm/http/index.js +73 -0
- package/dist/esm/http/index.js.map +1 -0
- package/dist/esm/http/safe-fetch.js +193 -0
- package/dist/esm/http/safe-fetch.js.map +1 -0
- package/dist/esm/identity/index.js +111 -0
- package/dist/esm/identity/index.js.map +1 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/knex/index.js +66 -0
- package/dist/esm/knex/index.js.map +1 -0
- package/dist/esm/logging/index.js +67 -0
- package/dist/esm/logging/index.js.map +1 -0
- package/dist/esm/messaging/connection.js +108 -0
- package/dist/esm/messaging/connection.js.map +1 -0
- package/dist/esm/messaging/consumer.js +130 -0
- package/dist/esm/messaging/consumer.js.map +1 -0
- package/dist/esm/messaging/envelope.js +19 -0
- package/dist/esm/messaging/envelope.js.map +1 -0
- package/dist/esm/messaging/idempotency.js +52 -0
- package/dist/esm/messaging/idempotency.js.map +1 -0
- package/dist/esm/messaging/index.js +45 -0
- package/dist/esm/messaging/index.js.map +1 -0
- package/dist/esm/messaging/monitor.js +44 -0
- package/dist/esm/messaging/monitor.js.map +1 -0
- package/dist/esm/messaging/outbox.js +129 -0
- package/dist/esm/messaging/outbox.js.map +1 -0
- package/dist/esm/messaging/publisher.js +142 -0
- package/dist/esm/messaging/publisher.js.map +1 -0
- package/dist/esm/messaging/rpc.js +120 -0
- package/dist/esm/messaging/rpc.js.map +1 -0
- package/dist/esm/messaging/staff-notifier.js +73 -0
- package/dist/esm/messaging/staff-notifier.js.map +1 -0
- package/dist/esm/messaging/topology.js +16 -0
- package/dist/esm/messaging/topology.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/rate-limit/index.js +56 -0
- package/dist/esm/rate-limit/index.js.map +1 -0
- package/dist/esm/scheduling/index.js +83 -0
- package/dist/esm/scheduling/index.js.map +1 -0
- package/dist/esm/security/index.js +36 -0
- package/dist/esm/security/index.js.map +1 -0
- package/dist/esm/socket/index.js +47 -0
- package/dist/esm/socket/index.js.map +1 -0
- package/dist/esm/testing/index.js +66 -0
- package/dist/esm/testing/index.js.map +1 -0
- package/dist/esm/types/index.js +2 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/validation/index.js +36 -0
- package/dist/esm/validation/index.js.map +1 -0
- package/dist/types/access/index.d.ts +50 -0
- package/dist/types/access/index.d.ts.map +1 -0
- package/dist/types/alerting/index.d.ts +43 -0
- package/dist/types/alerting/index.d.ts.map +1 -0
- package/dist/types/cache/index.d.ts +45 -0
- package/dist/types/cache/index.d.ts.map +1 -0
- package/dist/types/common/async.d.ts +14 -0
- package/dist/types/common/async.d.ts.map +1 -0
- package/dist/types/common/audit.d.ts +17 -0
- package/dist/types/common/audit.d.ts.map +1 -0
- package/dist/types/common/crypto.d.ts +18 -0
- package/dist/types/common/crypto.d.ts.map +1 -0
- package/dist/types/common/errors.d.ts +71 -0
- package/dist/types/common/errors.d.ts.map +1 -0
- package/dist/types/common/id.d.ts +14 -0
- package/dist/types/common/id.d.ts.map +1 -0
- package/dist/types/common/index.d.ts +12 -0
- package/dist/types/common/index.d.ts.map +1 -0
- package/dist/types/common/jwt.d.ts +28 -0
- package/dist/types/common/jwt.d.ts.map +1 -0
- package/dist/types/common/password.d.ts +4 -0
- package/dist/types/common/password.d.ts.map +1 -0
- package/dist/types/common/phone.d.ts +10 -0
- package/dist/types/common/phone.d.ts.map +1 -0
- package/dist/types/common/response.d.ts +12 -0
- package/dist/types/common/response.d.ts.map +1 -0
- package/dist/types/common/text.d.ts +10 -0
- package/dist/types/common/text.d.ts.map +1 -0
- package/dist/types/common/time.d.ts +40 -0
- package/dist/types/common/time.d.ts.map +1 -0
- package/dist/types/config/index.d.ts +115 -0
- package/dist/types/config/index.d.ts.map +1 -0
- package/dist/types/contracts/editorial-draft.d.ts +577 -0
- package/dist/types/contracts/editorial-draft.d.ts.map +1 -0
- package/dist/types/contracts/index.d.ts +4 -0
- package/dist/types/contracts/index.d.ts.map +1 -0
- package/dist/types/contracts/notification-dispatch.d.ts +175 -0
- package/dist/types/contracts/notification-dispatch.d.ts.map +1 -0
- package/dist/types/contracts/upload-import.d.ts +96 -0
- package/dist/types/contracts/upload-import.d.ts.map +1 -0
- package/dist/types/database/index.d.ts +25 -0
- package/dist/types/database/index.d.ts.map +1 -0
- package/dist/types/express/auth.d.ts +27 -0
- package/dist/types/express/auth.d.ts.map +1 -0
- package/dist/types/express/health.d.ts +14 -0
- package/dist/types/express/health.d.ts.map +1 -0
- package/dist/types/express/index.d.ts +4 -0
- package/dist/types/express/index.d.ts.map +1 -0
- package/dist/types/express/middleware.d.ts +20 -0
- package/dist/types/express/middleware.d.ts.map +1 -0
- package/dist/types/http/index.d.ts +34 -0
- package/dist/types/http/index.d.ts.map +1 -0
- package/dist/types/http/safe-fetch.d.ts +58 -0
- package/dist/types/http/safe-fetch.d.ts.map +1 -0
- package/dist/types/identity/index.d.ts +51 -0
- package/dist/types/identity/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/knex/index.d.ts +25 -0
- package/dist/types/knex/index.d.ts.map +1 -0
- package/dist/types/logging/index.d.ts +22 -0
- package/dist/types/logging/index.d.ts.map +1 -0
- package/dist/types/messaging/connection.d.ts +48 -0
- package/dist/types/messaging/connection.d.ts.map +1 -0
- package/dist/types/messaging/consumer.d.ts +56 -0
- package/dist/types/messaging/consumer.d.ts.map +1 -0
- package/dist/types/messaging/envelope.d.ts +16 -0
- package/dist/types/messaging/envelope.d.ts.map +1 -0
- package/dist/types/messaging/idempotency.d.ts +29 -0
- package/dist/types/messaging/idempotency.d.ts.map +1 -0
- package/dist/types/messaging/index.d.ts +39 -0
- package/dist/types/messaging/index.d.ts.map +1 -0
- package/dist/types/messaging/monitor.d.ts +23 -0
- package/dist/types/messaging/monitor.d.ts.map +1 -0
- package/dist/types/messaging/outbox.d.ts +51 -0
- package/dist/types/messaging/outbox.d.ts.map +1 -0
- package/dist/types/messaging/publisher.d.ts +84 -0
- package/dist/types/messaging/publisher.d.ts.map +1 -0
- package/dist/types/messaging/rpc.d.ts +46 -0
- package/dist/types/messaging/rpc.d.ts.map +1 -0
- package/dist/types/messaging/staff-notifier.d.ts +56 -0
- package/dist/types/messaging/staff-notifier.d.ts.map +1 -0
- package/dist/types/messaging/topology.d.ts +23 -0
- package/dist/types/messaging/topology.d.ts.map +1 -0
- package/dist/types/rate-limit/index.d.ts +28 -0
- package/dist/types/rate-limit/index.d.ts.map +1 -0
- package/dist/types/scheduling/index.d.ts +33 -0
- package/dist/types/scheduling/index.d.ts.map +1 -0
- package/dist/types/security/index.d.ts +20 -0
- package/dist/types/security/index.d.ts.map +1 -0
- package/dist/types/socket/index.d.ts +30 -0
- package/dist/types/socket/index.d.ts.map +1 -0
- package/dist/types/testing/index.d.ts +41 -0
- package/dist/types/testing/index.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +65 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/validation/index.d.ts +34 -0
- package/dist/types/validation/index.d.ts.map +1 -0
- package/package.json +189 -4
- package/README.md +0 -3
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { AuthUser } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Permission and ownership checks. Keep every authorization decision in these helpers (not
|
|
4
|
+
* inline in controllers) so the rules are identical across endpoints and services.
|
|
5
|
+
*
|
|
6
|
+
* Permission strings are dotted (`users.manage`, `media.manage.any`). Grants may use
|
|
7
|
+
* wildcards: `*` grants everything; `media.*` grants any permission starting with `media.`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const WILDCARD_PERMISSION = "*";
|
|
10
|
+
/** True when the user holds at least one of `required`. */
|
|
11
|
+
export declare function hasPermission(user: Pick<AuthUser, 'permissions'> | null | undefined, ...required: string[]): boolean;
|
|
12
|
+
export declare function hasAllPermissions(user: Pick<AuthUser, 'permissions'> | null | undefined, ...required: string[]): boolean;
|
|
13
|
+
export declare function hasRole(user: Pick<AuthUser, 'roles'> | null | undefined, ...roles: string[]): boolean;
|
|
14
|
+
export declare function requireUser(user: AuthUser | null | undefined): AuthUser;
|
|
15
|
+
export declare function assertPermission(user: AuthUser | null | undefined, ...required: string[]): AuthUser;
|
|
16
|
+
/** IDs the user may act on within a scope (e.g. profiles they are a member of). */
|
|
17
|
+
export declare function scopeIds(user: Pick<AuthUser, 'scopes'> | null | undefined, scope: string): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Self-owned data: allow when the caller *is* `ownerUserId`, or holds `bypassPermission`.
|
|
20
|
+
* Throws ForbiddenError otherwise.
|
|
21
|
+
*/
|
|
22
|
+
export declare function assertSelfOrPermission(user: AuthUser | null | undefined, ownerUserId: string, bypassPermission?: string): AuthUser;
|
|
23
|
+
/**
|
|
24
|
+
* Scoped data: allow when `resourceScopeId` is one of the caller's scope IDs, or the caller holds
|
|
25
|
+
* `bypassPermission`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function assertInScope(user: AuthUser | null | undefined, scope: string, resourceScopeId: string, bypassPermission?: string): AuthUser;
|
|
28
|
+
/**
|
|
29
|
+
* Resolves the single scope ID a request acts on. With one membership it is implicit; with
|
|
30
|
+
* several the client names one (e.g. `x-active-profile-id`), which must be a member ID.
|
|
31
|
+
* IDs from request bodies are never trusted — only the gateway-signed scopes.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveActiveScopeId(user: AuthUser | null | undefined, scope: string, requested?: string | null): string;
|
|
34
|
+
/**
|
|
35
|
+
* Like `resolveActiveScopeId`, for screens that work without a selector: with several memberships
|
|
36
|
+
* and none named, the first (primary) one is used. A named ID must still be a member ID.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolvePrimaryScopeId(user: AuthUser | null | undefined, scope: string, requested?: string | null): string;
|
|
39
|
+
export type OwnerFilter = {
|
|
40
|
+
all: true;
|
|
41
|
+
} | {
|
|
42
|
+
all: false;
|
|
43
|
+
ids: string[];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Repository filter for list queries: `{ all: true }` for callers holding `bypassPermission`,
|
|
47
|
+
* otherwise the caller's own scope IDs (possibly empty → return nothing).
|
|
48
|
+
*/
|
|
49
|
+
export declare function ownerFilter(user: AuthUser | null | undefined, scope: string, bypassPermission?: string): OwnerFilter;
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/access/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAOvC,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAGpH;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAGxH;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAErG;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,CAGvE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,CAInG;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnG;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,QAAQ,CAKlI;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,QAAQ,CAK5I;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CASxH;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGzH;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,GAAG,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAExE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,WAAW,CAIpH"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Logger } from '../types/index.js';
|
|
2
|
+
/** Sends operator alerts (DLQ depth, stalled queues…). Never throws: alerting must not break its caller. */
|
|
3
|
+
export interface AlertSender {
|
|
4
|
+
/** True when the alert was accepted; false when it was not sent (not configured, or the hook failed). */
|
|
5
|
+
send(messages: string[], options?: {
|
|
6
|
+
alertType?: string;
|
|
7
|
+
}): Promise<boolean>;
|
|
8
|
+
}
|
|
9
|
+
/** The body the platform's Slack notification app accepts (the same one `health-monitor.sh` posts). */
|
|
10
|
+
export interface SlackAlertPayload {
|
|
11
|
+
messages: string[];
|
|
12
|
+
alert_type: string;
|
|
13
|
+
app_name: string;
|
|
14
|
+
environment: string;
|
|
15
|
+
consolidate: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface SlackAlerterOptions {
|
|
18
|
+
/** The notification app's URL. Empty = not configured: alerts are logged and skipped. */
|
|
19
|
+
url: string;
|
|
20
|
+
/** Product name shown on the alert, e.g. `Showbiz`. */
|
|
21
|
+
app: string;
|
|
22
|
+
/** `staging`, `production`… */
|
|
23
|
+
environment: string;
|
|
24
|
+
logger?: Logger;
|
|
25
|
+
timeoutMs?: number;
|
|
26
|
+
/** Injected in tests; defaults to the global `fetch`. */
|
|
27
|
+
fetch?: typeof fetch;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Posts alerts to a Slack notification webhook as `{ messages, alert_type, app_name, environment, consolidate }`.
|
|
31
|
+
* An unset URL is a valid "alerts off" configuration: the first skipped alert is warned about once, then silently.
|
|
32
|
+
*/
|
|
33
|
+
export declare class SlackAlerter implements AlertSender {
|
|
34
|
+
private readonly options;
|
|
35
|
+
private warnedUnconfigured;
|
|
36
|
+
private readonly logger;
|
|
37
|
+
constructor(options: SlackAlerterOptions);
|
|
38
|
+
get configured(): boolean;
|
|
39
|
+
send(messages: string[], options?: {
|
|
40
|
+
alertType?: string;
|
|
41
|
+
}): Promise<boolean>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/alerting/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,4GAA4G;AAC5G,MAAM,WAAW,WAAW;IAC1B,yGAAyG;IACzG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9E;AAED,uGAAuG;AACvG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,yFAAyF;IACzF,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,YAAa,YAAW,WAAW;IAIlC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEH,OAAO,EAAE,mBAAmB;IAIzD,IAAI,UAAU,IAAI,OAAO,CAExB;IAEK,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAgCvF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Redis, type RedisOptions } from 'ioredis';
|
|
2
|
+
import type { Logger } from '../types/index.js';
|
|
3
|
+
export interface CacheSetOptions {
|
|
4
|
+
ttlSec?: number;
|
|
5
|
+
/** Tags let one call invalidate every key derived from an entity (e.g. `user:01J…`). */
|
|
6
|
+
tags?: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface Cache {
|
|
9
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
10
|
+
set<T>(key: string, value: T, options?: CacheSetOptions): Promise<void>;
|
|
11
|
+
del(...keys: string[]): Promise<void>;
|
|
12
|
+
/** Cache-aside: returns the cached value or loads, stores and returns it. Concurrent misses share one load. */
|
|
13
|
+
wrap<T>(key: string, loader: () => Promise<T>, options?: CacheSetOptions & {
|
|
14
|
+
cacheNull?: boolean;
|
|
15
|
+
}): Promise<T>;
|
|
16
|
+
invalidateTags(...tags: string[]): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export interface CacheOptions {
|
|
19
|
+
/** Null → in-memory only (tests, local tooling). */
|
|
20
|
+
redis: Redis | null;
|
|
21
|
+
/** Key namespace, e.g. `auth` → keys `auth:<key>`. Combine with the client-level env prefix. */
|
|
22
|
+
namespace: string;
|
|
23
|
+
defaultTtlSec?: number;
|
|
24
|
+
/** Upper bound for the in-memory layer / fallback. */
|
|
25
|
+
memoryMaxEntries?: number;
|
|
26
|
+
logger?: Logger;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Redis-backed cache with tag invalidation. If Redis errors, reads fall through to the loader
|
|
30
|
+
* and writes go to a bounded in-memory store, so a cache outage degrades latency rather than
|
|
31
|
+
* availability.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createCache(options: CacheOptions): Cache;
|
|
34
|
+
export interface RedisClientOptions {
|
|
35
|
+
url?: string;
|
|
36
|
+
db?: number;
|
|
37
|
+
/** Prepended to every key by ioredis, e.g. `showbiz:prod:`. */
|
|
38
|
+
keyPrefix?: string;
|
|
39
|
+
logger?: Logger;
|
|
40
|
+
options?: RedisOptions;
|
|
41
|
+
}
|
|
42
|
+
/** ioredis client that never crashes the process on connection errors and retries forever. */
|
|
43
|
+
export declare function createRedisClient(opts: RedisClientOptions): Redis;
|
|
44
|
+
export type { Redis };
|
|
45
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,KAAK;IACpB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC5C,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+GAA+G;IAC/G,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAChH,cAAc,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,gGAAgG;IAChG,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA+BD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,KAAK,CA+FxD;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,KAAK,CAmBjE;AAED,YAAY,EAAE,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const sleep: (ms: number) => Promise<void>;
|
|
2
|
+
export interface RetryOptions {
|
|
3
|
+
retries: number;
|
|
4
|
+
/** Delay before attempt n (1-based retry number). Default: 200ms × 2^(n-1), capped at 5s. */
|
|
5
|
+
delayMs?: (attempt: number) => number;
|
|
6
|
+
shouldRetry?: (error: unknown) => boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Runs `fn`, retrying failures with exponential back-off. */
|
|
9
|
+
export declare function retry<T>(fn: (attempt: number) => Promise<T>, options: RetryOptions): Promise<T>;
|
|
10
|
+
/** Rejects with `onTimeout()` if `promise` does not settle within `ms`. */
|
|
11
|
+
export declare function withTimeout<T>(promise: Promise<T>, ms: number, onTimeout: () => Error): Promise<T>;
|
|
12
|
+
/** Splits `items` into arrays of at most `size`. */
|
|
13
|
+
export declare function chunk<T>(items: readonly T[], size: number): T[][];
|
|
14
|
+
//# sourceMappingURL=async.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../../../src/common/async.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,KAAG,OAAO,CAAC,IAAI,CAAsD,CAAC;AAEtG,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;CAC3C;AAED,8DAA8D;AAC9D,wBAAsB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAYrG;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAMlG;AAED,oDAAoD;AACpD,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAIjE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type AuditAction = 'create' | 'update' | 'delete';
|
|
2
|
+
type AuditRow<T> = Omit<T, 'id' | 'createdAt' | 'updatedAt'> & {
|
|
3
|
+
id: string;
|
|
4
|
+
parentId: string;
|
|
5
|
+
action: AuditAction;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Builds the row for a `*_audits` sibling table: a copy of the parent row plus `action`,
|
|
9
|
+
* `parentId`, and a fresh `id`. The parent's timestamps are dropped so the audit row records
|
|
10
|
+
* when the change happened. The actor lands in `createdBy`/`updatedBy` exactly as on the parent
|
|
11
|
+
* (null for system operations). Strip secrets (e.g. password hashes) before calling.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildAuditRow<T extends {
|
|
14
|
+
id: string;
|
|
15
|
+
}>(row: T, action: AuditAction, actorId?: string | null): AuditRow<T>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/common/audit.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEzD,KAAK,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AAErH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,MAAM,GAAG,IAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,CAS/H"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare function sha256(value: string | Buffer): string;
|
|
2
|
+
export declare function hmacSha256(secret: string | Buffer, value: string): string;
|
|
3
|
+
/** Constant-time string comparison (false when lengths differ). */
|
|
4
|
+
export declare function safeEqual(a: string, b: string): boolean;
|
|
5
|
+
/** URL-safe random token (default 32 bytes of entropy). */
|
|
6
|
+
export declare function randomToken(bytes?: number): string;
|
|
7
|
+
/** Numeric one-time code, e.g. `'042917'`. Uses a CSPRNG. */
|
|
8
|
+
export declare function randomNumericCode(length?: number): string;
|
|
9
|
+
/**
|
|
10
|
+
* Hash a value that must be looked up later (refresh tokens, reset tokens, OTPs) with a
|
|
11
|
+
* server-side pepper so a database leak alone cannot be replayed.
|
|
12
|
+
*/
|
|
13
|
+
export declare function hashToken(token: string, pepper: string): string;
|
|
14
|
+
/** AES-256-GCM encrypt. Output: `v1:<iv>:<tag>:<ciphertext>` (base64url parts). */
|
|
15
|
+
export declare function encryptSecret(plaintext: string, key: string): string;
|
|
16
|
+
export declare function decryptSecret(payload: string, key: string): string;
|
|
17
|
+
export declare function isEncryptedSecret(value: unknown): value is string;
|
|
18
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../../src/common/crypto.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAIvD;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,KAAK,SAAK,GAAG,MAAM,CAE9C;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,MAAM,SAAI,GAAG,MAAM,CAIpD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/D;AAcD,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMpE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQlE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEjE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export type ErrorDetails = Record<string, string[]>;
|
|
2
|
+
/**
|
|
3
|
+
* Base class for errors that map to an HTTP status. Throw these from services; the shared
|
|
4
|
+
* error middleware turns them into the standard envelope. Anything that is not an AppError is
|
|
5
|
+
* reported as a 500 with a generic message so internals never leak.
|
|
6
|
+
*/
|
|
7
|
+
export declare class AppError extends Error {
|
|
8
|
+
readonly statusCode: number;
|
|
9
|
+
readonly code: string;
|
|
10
|
+
readonly errors?: ErrorDetails;
|
|
11
|
+
/** Consumers dead-letter immediately instead of retrying when this is false. */
|
|
12
|
+
readonly retryable: boolean;
|
|
13
|
+
constructor(statusCode: number, message: string, options?: {
|
|
14
|
+
code?: string;
|
|
15
|
+
errors?: ErrorDetails;
|
|
16
|
+
retryable?: boolean;
|
|
17
|
+
cause?: unknown;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export declare class BadRequestError extends AppError {
|
|
21
|
+
constructor(message?: string, options?: {
|
|
22
|
+
code?: string;
|
|
23
|
+
errors?: ErrorDetails;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export declare class UnauthorizedError extends AppError {
|
|
27
|
+
constructor(message?: string, options?: {
|
|
28
|
+
code?: string;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export declare class ForbiddenError extends AppError {
|
|
32
|
+
constructor(message?: string, options?: {
|
|
33
|
+
code?: string;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export declare class NotFoundError extends AppError {
|
|
37
|
+
constructor(message?: string, options?: {
|
|
38
|
+
code?: string;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export declare class ConflictError extends AppError {
|
|
42
|
+
constructor(message?: string, options?: {
|
|
43
|
+
code?: string;
|
|
44
|
+
errors?: ErrorDetails;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export declare class ValidationError extends AppError {
|
|
48
|
+
constructor(errors: ErrorDetails, message?: string);
|
|
49
|
+
}
|
|
50
|
+
export declare class TooManyRequestsError extends AppError {
|
|
51
|
+
constructor(message?: string, options?: {
|
|
52
|
+
code?: string;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
export declare class ServiceUnavailableError extends AppError {
|
|
56
|
+
constructor(message?: string, options?: {
|
|
57
|
+
code?: string;
|
|
58
|
+
cause?: unknown;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/** A failure that will never succeed on retry (bad payload, unknown template, …). */
|
|
62
|
+
export declare class NonRetryableError extends AppError {
|
|
63
|
+
constructor(message: string, options?: {
|
|
64
|
+
code?: string;
|
|
65
|
+
cause?: unknown;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
export declare function isAppError(error: unknown): error is AppError;
|
|
69
|
+
/** Message safe to show a caller; hides internals for unexpected errors. */
|
|
70
|
+
export declare function publicMessage(error: unknown): string;
|
|
71
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/common/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAEpD;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;gBAEhB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAQ9I;AAgBD,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,SAAgB,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,CAAA;KAAO;CAC5F;AACD,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,OAAO,SAA4B,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO;CACjF;AACD,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,OAAO,SAAsD,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO;CAC3G;AACD,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,SAAuB,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO;CAC5E;AACD,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,SAA4B,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,CAAA;KAAO;CACxG;AACD,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,MAAM,EAAE,YAAY,EAAE,OAAO,SAAsB;CAChE;AACD,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,OAAO,SAA+C,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAO;CACpG;AACD,qBAAa,uBAAwB,SAAQ,QAAQ;gBACvC,OAAO,SAAoC,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAC1G;AAED,qFAAqF;AACrF,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAG9E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIpD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const ID_LENGTH = 26;
|
|
2
|
+
export declare const ID_PATTERN: RegExp;
|
|
3
|
+
/** A new time-ordered, monotonic ULID. */
|
|
4
|
+
export declare function newId(): string;
|
|
5
|
+
export declare function isId(value: unknown): value is string;
|
|
6
|
+
/** Creation time encoded in a ULID. */
|
|
7
|
+
export declare function idTimestamp(id: string): Date;
|
|
8
|
+
/**
|
|
9
|
+
* A stable, valid ID for seed/fixture rows: the same `(namespace, n)` always yields the same ID, so
|
|
10
|
+
* seeds in different services can reference each other's rows without sharing a database.
|
|
11
|
+
* `namespace` is two Crockford characters (e.g. `PR` for profiles).
|
|
12
|
+
*/
|
|
13
|
+
export declare function fixtureId(namespace: string, n: number): string;
|
|
14
|
+
//# sourceMappingURL=id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../../src/common/id.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,SAAS,KAAK,CAAC;AAC5B,eAAO,MAAM,UAAU,QAA6B,CAAC;AAErD,0CAA0C;AAC1C,wBAAgB,KAAK,IAAI,MAAM,CAE9B;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEpD;AAED,uCAAuC;AACvC,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE5C;AAID;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAI9D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './id.js';
|
|
2
|
+
export * from './errors.js';
|
|
3
|
+
export * from './response.js';
|
|
4
|
+
export * from './crypto.js';
|
|
5
|
+
export * from './password.js';
|
|
6
|
+
export * from './jwt.js';
|
|
7
|
+
export * from './text.js';
|
|
8
|
+
export * from './async.js';
|
|
9
|
+
export * from './phone.js';
|
|
10
|
+
export * from './time.js';
|
|
11
|
+
export * from './audit.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface JwtSignOptions {
|
|
2
|
+
expiresIn: string | number;
|
|
3
|
+
issuer?: string;
|
|
4
|
+
audience?: string;
|
|
5
|
+
jwtId?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface JwtVerifyOptions {
|
|
8
|
+
issuer?: string;
|
|
9
|
+
audience?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Registered claims plus custom ones. Declared here so consumers never need `@types/jsonwebtoken`. */
|
|
12
|
+
export interface JwtClaims {
|
|
13
|
+
sub: string;
|
|
14
|
+
iat?: number;
|
|
15
|
+
exp?: number;
|
|
16
|
+
iss?: string;
|
|
17
|
+
aud?: string | string[];
|
|
18
|
+
jti?: string;
|
|
19
|
+
[claim: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
export declare function signJwt(payload: Record<string, unknown>, secret: string, options: JwtSignOptions): string;
|
|
22
|
+
/** Verifies signature, expiry and (when given) issuer/audience. Throws on any failure. */
|
|
23
|
+
export declare function verifyJwt<T extends JwtClaims = JwtClaims>(token: string, secret: string, options?: JwtVerifyOptions): T;
|
|
24
|
+
export declare function decodeJwt<T extends JwtClaims = JwtClaims>(token: string): T | null;
|
|
25
|
+
export declare function extractBearerToken(header?: string | null): string | null;
|
|
26
|
+
/** Converts `'15m'`, `'30d'`, `3600` into seconds. */
|
|
27
|
+
export declare function durationToSeconds(value: string | number): number;
|
|
28
|
+
//# sourceMappingURL=jwt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/common/jwt.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,uGAAuG;AACvG,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAQzG;AAED,0FAA0F;AAC1F,wBAAgB,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,CAAC,CAQ3H;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAGlF;AAED,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAIxE;AAED,sDAAsD;AACtD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAahE"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function hashPassword(password: string): Promise<string>;
|
|
2
|
+
export declare function verifyPassword(password: string, hash: string | null | undefined): Promise<boolean>;
|
|
3
|
+
export declare function needsRehash(hash: string): boolean;
|
|
4
|
+
//# sourceMappingURL=password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../../src/common/password.ts"],"names":[],"mappings":"AAYA,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAQxG;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalises a phone number to E.164 (`+254712345678`). Returns null for anything that is not a
|
|
3
|
+
* valid number for the given default region.
|
|
4
|
+
*/
|
|
5
|
+
export declare function toE164(phone: string, defaultRegion?: string): string | null;
|
|
6
|
+
/** E.164 without the plus sign, as most SMS gateways expect (`254712345678`). */
|
|
7
|
+
export declare function toMsisdn(phone: string, defaultRegion?: string): string | null;
|
|
8
|
+
export declare function phoneRegion(phone: string, defaultRegion?: string): string | null;
|
|
9
|
+
export declare function maskPhone(phone: string): string;
|
|
10
|
+
//# sourceMappingURL=phone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phone.d.ts","sourceRoot":"","sources":["../../../src/common/phone.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,SAAO,GAAG,MAAM,GAAG,IAAI,CAOzE;AAED,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,SAAO,GAAG,MAAM,GAAG,IAAI,CAG3E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,SAAO,GAAG,MAAM,GAAG,IAAI,CAM9E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ApiResponse, PaginationMeta, PaginatedResult } from '../types/index.js';
|
|
2
|
+
/** Standard success envelope: `{ success, message, data }`. */
|
|
3
|
+
export declare function successResponse<T>(data: T, message?: string): ApiResponse<T>;
|
|
4
|
+
/** Standard error envelope: `{ success: false, message, code?, errors? }`. */
|
|
5
|
+
export declare function errorResponse(message: string, errors?: Record<string, string[]>, code?: string): ApiResponse<never>;
|
|
6
|
+
export declare function buildPaginationMeta(total: number, page: number, limit: number): PaginationMeta;
|
|
7
|
+
/** Paginated envelope: `{ success, message, data: T[], meta }`. */
|
|
8
|
+
export declare function paginatedResponse<T>(data: T[], total: number, page: number, limit: number, message?: string): ApiResponse<T[]>;
|
|
9
|
+
export declare function buildPaginatedResult<T>(data: T[], total: number, page: number, limit: number): PaginatedResult<T>;
|
|
10
|
+
/** SQL offset for 1-based pages. */
|
|
11
|
+
export declare function pageOffset(page: number, limit: number): number;
|
|
12
|
+
//# sourceMappingURL=response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/common/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEtF,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,SAAY,GAAG,WAAW,CAAC,CAAC,CAAC,CAE/E;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAEnH;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAG9F;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,SAAY,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,CAEjI;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,CAEjH;AAED,oCAAoC;AACpC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** URL slug: lowercase ASCII, dash-separated, accents folded. */
|
|
2
|
+
export declare function slugify(value: string, maxLength?: number): string;
|
|
3
|
+
/** Replaces `{{ name }}` placeholders; unknown names become empty strings. */
|
|
4
|
+
export declare function interpolate(template: string, variables: Record<string, unknown>, escape?: (value: string) => string): string;
|
|
5
|
+
/** Placeholder names used by a template, e.g. `['user.name', 'code']`. */
|
|
6
|
+
export declare function templateVariables(template: string): string[];
|
|
7
|
+
export declare function escapeHtml(value: string): string;
|
|
8
|
+
/** `jane.doe@example.com` → `ja***@example.com` for logs and audit trails. */
|
|
9
|
+
export declare function maskEmail(email: string): string;
|
|
10
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/common/text.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAK,GAAG,MAAM,CAU7D;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAM5H;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAI5D;AAID,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/C"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** True for IANA zones the runtime knows (`Africa/Nairobi`), false for garbage. */
|
|
2
|
+
export declare function isValidTimeZone(zone: string): boolean;
|
|
3
|
+
/** Formats an instant in a zone, e.g. `30 Sep 2026, 14:05 EAT`. Falls back to UTC for invalid zones. */
|
|
4
|
+
export declare function formatInTimeZone(date: Date | string | number, zone: string, locale?: string): string;
|
|
5
|
+
export interface ZonedText {
|
|
6
|
+
/** The formatted instant, e.g. `30 Sep 2026, 14:05 EAT`; empty when the instant is not a valid date. */
|
|
7
|
+
text: string;
|
|
8
|
+
/** The zone actually used. */
|
|
9
|
+
timezone: string;
|
|
10
|
+
/** True when `zone` was missing or invalid and `fallbackZone` was used instead. */
|
|
11
|
+
usedFallback: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Formats an instant for a person in their zone, falling back to `fallbackZone` (itself falling back to
|
|
15
|
+
* UTC) when theirs is missing or unknown. Never throws, and says when it fell back so callers can log it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatInstantInZone(instant: Date | string | number, zone: unknown, fallbackZone?: string, locale?: string): ZonedText;
|
|
18
|
+
/** Offset of `zone` from UTC in minutes at `at` (positive east of Greenwich). */
|
|
19
|
+
export declare function timeZoneOffsetMinutes(zone: string, at?: Date): number;
|
|
20
|
+
export declare const addSeconds: (date: Date, seconds: number) => Date;
|
|
21
|
+
export declare const addMinutes: (date: Date, minutes: number) => Date;
|
|
22
|
+
/** Minutes since midnight of a 24-hour `HH:MM` clock time. Throws on anything else (never guesses). */
|
|
23
|
+
export declare function parseClockTime(value: string): number;
|
|
24
|
+
/**
|
|
25
|
+
* The instant a wall-clock time occurs in `zone` (month is 0-based; an overflowing day rolls over).
|
|
26
|
+
* The offset is read again at the first estimate, so the result is right across a DST change; a wall
|
|
27
|
+
* time skipped by a spring-forward resolves to the nearest valid instant.
|
|
28
|
+
*/
|
|
29
|
+
export declare function zonedWallTimeToInstant(year: number, month: number, day: number, minutesOfDay: number, zone: string): Date;
|
|
30
|
+
/** The local calendar day containing `at` in `zone`, as a half-open `[start, end)` UTC range (23–25 h on DST days). */
|
|
31
|
+
export declare function zonedDayBounds(at: Date, zone: string): {
|
|
32
|
+
start: Date;
|
|
33
|
+
end: Date;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* When `at` falls inside the daily window `[start, end)` (local `HH:MM` times in `zone`; the window may
|
|
37
|
+
* cross midnight), the instant that window ends; otherwise null. `start === end` means no window.
|
|
38
|
+
*/
|
|
39
|
+
export declare function quietWindowEndAt(at: Date, zone: string, start: string, end: string): Date | null;
|
|
40
|
+
//# sourceMappingURL=time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/common/time.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOrD;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAU,GAAG,MAAM,CAWrG;AAED,MAAM,WAAW,SAAS;IACxB,wGAAwG;IACxG,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,SAAQ,EAAE,MAAM,SAAU,GAAG,SAAS,CAKrI;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAE,IAAiB,GAAG,MAAM,CAOjF;AAED,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,EAAE,SAAS,MAAM,KAAG,IAAiD,CAAC;AAC3G,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,EAAE,SAAS,MAAM,KAAG,IAAsC,CAAC;AAMhG,uGAAuG;AACvG,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIpD;AASD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAIzH;AAED,uHAAuH;AACvH,wBAAgB,cAAc,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,CAGjF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAchG"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Environment building blocks. Services compose the pieces they need:
|
|
4
|
+
*
|
|
5
|
+
* const env = loadEnv(serviceEnv.merge(databaseEnv).merge(messagingEnv).extend({ MY_VAR: z.string() }));
|
|
6
|
+
*/
|
|
7
|
+
export declare const serviceEnv: z.ZodObject<{
|
|
8
|
+
NODE_ENV: z.ZodDefault<z.ZodEnum<["development", "test", "staging", "production"]>>;
|
|
9
|
+
PORT: z.ZodNumber;
|
|
10
|
+
SERVICE_NAME: z.ZodString;
|
|
11
|
+
/** Short app identifier used in exchange names and key prefixes (e.g. `showbiz`). */
|
|
12
|
+
APP_NAME: z.ZodDefault<z.ZodString>;
|
|
13
|
+
LOG_LEVEL: z.ZodOptional<z.ZodEnum<["error", "warn", "info", "http", "debug"]>>;
|
|
14
|
+
CORS_ORIGINS: z.ZodDefault<z.ZodString>;
|
|
15
|
+
/** Verifies gateway-signed identity headers. */
|
|
16
|
+
GATEWAY_SHARED_SECRET: z.ZodString;
|
|
17
|
+
/** Authenticates service-to-service `/internal/*` calls. */
|
|
18
|
+
INTERNAL_SERVICE_SECRET: z.ZodString;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
NODE_ENV: "production" | "test" | "development" | "staging";
|
|
21
|
+
PORT: number;
|
|
22
|
+
SERVICE_NAME: string;
|
|
23
|
+
APP_NAME: string;
|
|
24
|
+
CORS_ORIGINS: string;
|
|
25
|
+
GATEWAY_SHARED_SECRET: string;
|
|
26
|
+
INTERNAL_SERVICE_SECRET: string;
|
|
27
|
+
LOG_LEVEL?: "info" | "debug" | "error" | "warn" | "http" | undefined;
|
|
28
|
+
}, {
|
|
29
|
+
PORT: number;
|
|
30
|
+
SERVICE_NAME: string;
|
|
31
|
+
GATEWAY_SHARED_SECRET: string;
|
|
32
|
+
INTERNAL_SERVICE_SECRET: string;
|
|
33
|
+
NODE_ENV?: "production" | "test" | "development" | "staging" | undefined;
|
|
34
|
+
LOG_LEVEL?: "info" | "debug" | "error" | "warn" | "http" | undefined;
|
|
35
|
+
APP_NAME?: string | undefined;
|
|
36
|
+
CORS_ORIGINS?: string | undefined;
|
|
37
|
+
}>;
|
|
38
|
+
export declare const databaseEnv: z.ZodObject<{
|
|
39
|
+
DB_HOST: z.ZodDefault<z.ZodString>;
|
|
40
|
+
DB_PORT: z.ZodDefault<z.ZodNumber>;
|
|
41
|
+
DB_USER: z.ZodDefault<z.ZodString>;
|
|
42
|
+
DB_PASSWORD: z.ZodDefault<z.ZodString>;
|
|
43
|
+
DB_NAME: z.ZodString;
|
|
44
|
+
DB_POOL_MAX: z.ZodDefault<z.ZodNumber>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
DB_HOST: string;
|
|
47
|
+
DB_PORT: number;
|
|
48
|
+
DB_USER: string;
|
|
49
|
+
DB_PASSWORD: string;
|
|
50
|
+
DB_NAME: string;
|
|
51
|
+
DB_POOL_MAX: number;
|
|
52
|
+
}, {
|
|
53
|
+
DB_NAME: string;
|
|
54
|
+
DB_HOST?: string | undefined;
|
|
55
|
+
DB_PORT?: number | undefined;
|
|
56
|
+
DB_USER?: string | undefined;
|
|
57
|
+
DB_PASSWORD?: string | undefined;
|
|
58
|
+
DB_POOL_MAX?: number | undefined;
|
|
59
|
+
}>;
|
|
60
|
+
export declare const messagingEnv: z.ZodObject<{
|
|
61
|
+
RABBITMQ_URL: z.ZodOptional<z.ZodString>;
|
|
62
|
+
RABBITMQ_HOST: z.ZodDefault<z.ZodString>;
|
|
63
|
+
RABBITMQ_PORT: z.ZodDefault<z.ZodNumber>;
|
|
64
|
+
RABBITMQ_USERNAME: z.ZodDefault<z.ZodString>;
|
|
65
|
+
RABBITMQ_PASSWORD: z.ZodDefault<z.ZodString>;
|
|
66
|
+
RABBITMQ_VHOST: z.ZodDefault<z.ZodString>;
|
|
67
|
+
/** Environment prefix for queue and exchange names (`dev`, `staging`, `prod`). */
|
|
68
|
+
QUEUE_PREFIX: z.ZodDefault<z.ZodString>;
|
|
69
|
+
RABBITMQ_ENABLED: z.ZodEffects<z.ZodDefault<z.ZodEnum<["true", "false"]>>, boolean, "true" | "false" | undefined>;
|
|
70
|
+
}, "strip", z.ZodTypeAny, {
|
|
71
|
+
RABBITMQ_HOST: string;
|
|
72
|
+
RABBITMQ_PORT: number;
|
|
73
|
+
RABBITMQ_USERNAME: string;
|
|
74
|
+
RABBITMQ_PASSWORD: string;
|
|
75
|
+
RABBITMQ_VHOST: string;
|
|
76
|
+
QUEUE_PREFIX: string;
|
|
77
|
+
RABBITMQ_ENABLED: boolean;
|
|
78
|
+
RABBITMQ_URL?: string | undefined;
|
|
79
|
+
}, {
|
|
80
|
+
RABBITMQ_URL?: string | undefined;
|
|
81
|
+
RABBITMQ_HOST?: string | undefined;
|
|
82
|
+
RABBITMQ_PORT?: number | undefined;
|
|
83
|
+
RABBITMQ_USERNAME?: string | undefined;
|
|
84
|
+
RABBITMQ_PASSWORD?: string | undefined;
|
|
85
|
+
RABBITMQ_VHOST?: string | undefined;
|
|
86
|
+
QUEUE_PREFIX?: string | undefined;
|
|
87
|
+
RABBITMQ_ENABLED?: "true" | "false" | undefined;
|
|
88
|
+
}>;
|
|
89
|
+
export declare const redisEnv: z.ZodObject<{
|
|
90
|
+
REDIS_URL: z.ZodOptional<z.ZodString>;
|
|
91
|
+
REDIS_DB: z.ZodDefault<z.ZodNumber>;
|
|
92
|
+
/** Key prefix, e.g. `app:dev:` — never share one between apps or environments. */
|
|
93
|
+
REDIS_PREFIX: z.ZodDefault<z.ZodString>;
|
|
94
|
+
}, "strip", z.ZodTypeAny, {
|
|
95
|
+
REDIS_DB: number;
|
|
96
|
+
REDIS_PREFIX: string;
|
|
97
|
+
REDIS_URL?: string | undefined;
|
|
98
|
+
}, {
|
|
99
|
+
REDIS_URL?: string | undefined;
|
|
100
|
+
REDIS_DB?: number | undefined;
|
|
101
|
+
REDIS_PREFIX?: string | undefined;
|
|
102
|
+
}>;
|
|
103
|
+
/** Builds an AMQP URL from discrete env vars (or returns RABBITMQ_URL when set). */
|
|
104
|
+
export declare function amqpUrlFromEnv(env: z.infer<typeof messagingEnv>): string;
|
|
105
|
+
/** Reads `KEY=value` lines from a dotenv file into process.env without overriding set values. */
|
|
106
|
+
export declare function loadDotEnv(path?: string): void;
|
|
107
|
+
export declare class ConfigError extends Error {
|
|
108
|
+
}
|
|
109
|
+
/** Loads `.env` (if present) and validates process.env. Throws ConfigError listing every problem. */
|
|
110
|
+
export declare function loadEnv<S extends z.ZodTypeAny>(schema: S, source?: NodeJS.ProcessEnv, options?: {
|
|
111
|
+
dotenv?: boolean;
|
|
112
|
+
}): z.infer<S>;
|
|
113
|
+
/** Comma-separated env value → trimmed, non-empty list. */
|
|
114
|
+
export declare const listFromEnv: (value: string | undefined) => string[];
|
|
115
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;;IAIrB,qFAAqF;;;;IAIrF,gDAAgD;;IAEhD,4DAA4D;;;;;;;;;;;;;;;;;;;;EAE5D,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;EAOtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;IAOvB,kFAAkF;;;;;;;;;;;;;;;;;;;;;EAGlF,CAAC;AAEH,eAAO,MAAM,QAAQ;;;IAGnB,kFAAkF;;;;;;;;;;EAElF,CAAC;AAEH,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,GAAG,MAAM,CAIxE;AAED,iGAAiG;AACjG,wBAAgB,UAAU,CAAC,IAAI,SAAiC,GAAG,IAAI,CAYtE;AAED,qBAAa,WAAY,SAAQ,KAAK;CAAG;AAEzC,qGAAqG;AACrG,wBAAgB,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAE,MAAM,CAAC,UAAwB,EAAE,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAQlJ;AAED,2DAA2D;AAC3D,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAAM,EAAmE,CAAC"}
|