@heavybit/shared-lib 0.0.0-stage → 1.2.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 +21 -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/express/security.js +18 -0
- package/dist/cjs/express/security.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/metrics/index.js +15 -0
- package/dist/cjs/metrics/index.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 +5 -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/express/security.js +11 -0
- package/dist/esm/express/security.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/metrics/index.js +6 -0
- package/dist/esm/metrics/index.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 +5 -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/express/security.d.ts +9 -0
- package/dist/types/express/security.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/metrics/index.d.ts +7 -0
- package/dist/types/metrics/index.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 +181 -4
- package/README.md +0 -3
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* `notification:dispatch` — the one command every Showbiz service stages (through its outbox) to have
|
|
4
|
+
* notification-service render a seeded template and deliver it by email and/or the in-app feed. No
|
|
5
|
+
* other service sends email itself. One contract for both sides: producers type their payload with it
|
|
6
|
+
* and notification-service validates against it, so the two cannot drift.
|
|
7
|
+
*/
|
|
8
|
+
export declare const NOTIFICATION_DISPATCH = "notification:dispatch";
|
|
9
|
+
/** Channels a dispatch may ask for. `in_app` needs a recipient `userId` (the bell feed is per user). */
|
|
10
|
+
export declare const DISPATCH_CHANNELS: readonly ["email", "in_app"];
|
|
11
|
+
export type DispatchChannel = (typeof DISPATCH_CHANNELS)[number];
|
|
12
|
+
/**
|
|
13
|
+
* What a dispatch is about. Account mail (`security`, `account`, `team`, `marketing`) goes to a user;
|
|
14
|
+
* `staff` is an operational alert to a configured staff address.
|
|
15
|
+
*/
|
|
16
|
+
export declare const NOTIFICATION_CATEGORIES: readonly ["security", "account", "team", "marketing", "staff"];
|
|
17
|
+
export type NotificationCategory = (typeof NOTIFICATION_CATEGORIES)[number];
|
|
18
|
+
export declare const DISPATCH_LIMITS: {
|
|
19
|
+
readonly template: 100;
|
|
20
|
+
readonly email: 254;
|
|
21
|
+
readonly name: 200;
|
|
22
|
+
readonly dataKeys: 40;
|
|
23
|
+
readonly dataKey: 64;
|
|
24
|
+
readonly dataValue: 2000;
|
|
25
|
+
readonly secretKeys: 10;
|
|
26
|
+
readonly permission: 100;
|
|
27
|
+
};
|
|
28
|
+
/** Template variables are flat scalars: they are printed into the copy, never serialised objects. */
|
|
29
|
+
export declare const dispatchValueSchema: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
|
|
30
|
+
export type DispatchValue = z.infer<typeof dispatchValueSchema>;
|
|
31
|
+
export declare const dispatchRecipientSchema: z.ZodObject<{
|
|
32
|
+
email: z.ZodString;
|
|
33
|
+
name: z.ZodOptional<z.ZodString>;
|
|
34
|
+
userId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
35
|
+
locale: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
36
|
+
/** IANA zone; time variables are rendered in it. */
|
|
37
|
+
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
38
|
+
}, "strip", z.ZodTypeAny, {
|
|
39
|
+
email: string;
|
|
40
|
+
name?: string | undefined;
|
|
41
|
+
userId?: string | null | undefined;
|
|
42
|
+
locale?: string | null | undefined;
|
|
43
|
+
timezone?: string | null | undefined;
|
|
44
|
+
}, {
|
|
45
|
+
email: string;
|
|
46
|
+
name?: string | undefined;
|
|
47
|
+
userId?: string | null | undefined;
|
|
48
|
+
locale?: string | null | undefined;
|
|
49
|
+
timezone?: string | null | undefined;
|
|
50
|
+
}>;
|
|
51
|
+
export type DispatchRecipient = z.infer<typeof dispatchRecipientSchema>;
|
|
52
|
+
export declare const notificationDispatchSchema: z.ZodEffects<z.ZodObject<{
|
|
53
|
+
/** Seeded `notification_templates.slug`. */
|
|
54
|
+
template: z.ZodString;
|
|
55
|
+
category: z.ZodEnum<["security", "account", "team", "marketing", "staff"]>;
|
|
56
|
+
recipient: z.ZodObject<{
|
|
57
|
+
email: z.ZodString;
|
|
58
|
+
name: z.ZodOptional<z.ZodString>;
|
|
59
|
+
userId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
60
|
+
locale: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
61
|
+
/** IANA zone; time variables are rendered in it. */
|
|
62
|
+
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
63
|
+
}, "strip", z.ZodTypeAny, {
|
|
64
|
+
email: string;
|
|
65
|
+
name?: string | undefined;
|
|
66
|
+
userId?: string | null | undefined;
|
|
67
|
+
locale?: string | null | undefined;
|
|
68
|
+
timezone?: string | null | undefined;
|
|
69
|
+
}, {
|
|
70
|
+
email: string;
|
|
71
|
+
name?: string | undefined;
|
|
72
|
+
userId?: string | null | undefined;
|
|
73
|
+
locale?: string | null | undefined;
|
|
74
|
+
timezone?: string | null | undefined;
|
|
75
|
+
}>;
|
|
76
|
+
channels: z.ZodArray<z.ZodEnum<["email", "in_app"]>, "many">;
|
|
77
|
+
data: z.ZodEffects<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>>, Record<string, string | number | boolean | null>, Record<string, string | number | boolean | null> | undefined>;
|
|
78
|
+
/**
|
|
79
|
+
* Keys of `data` holding a one-time secret (a sign-in code, a reset or confirm link). They are used to
|
|
80
|
+
* render the email and nothing else: notification-service never stores them and never puts them in the
|
|
81
|
+
* in-app feed, and email-service masks them in what it keeps.
|
|
82
|
+
*/
|
|
83
|
+
secretKeys: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
84
|
+
/** Security and staff alerts are always delivered, whatever the recipient's preferences. */
|
|
85
|
+
bypassPreferences: z.ZodOptional<z.ZodBoolean>;
|
|
86
|
+
/** The permission staff recipients hold; informational until recipients are resolved by permission. */
|
|
87
|
+
targetPermission: z.ZodOptional<z.ZodString>;
|
|
88
|
+
}, "strip", z.ZodTypeAny, {
|
|
89
|
+
data: Record<string, string | number | boolean | null>;
|
|
90
|
+
category: "security" | "account" | "team" | "marketing" | "staff";
|
|
91
|
+
template: string;
|
|
92
|
+
recipient: {
|
|
93
|
+
email: string;
|
|
94
|
+
name?: string | undefined;
|
|
95
|
+
userId?: string | null | undefined;
|
|
96
|
+
locale?: string | null | undefined;
|
|
97
|
+
timezone?: string | null | undefined;
|
|
98
|
+
};
|
|
99
|
+
channels: ("email" | "in_app")[];
|
|
100
|
+
secretKeys: string[];
|
|
101
|
+
bypassPreferences?: boolean | undefined;
|
|
102
|
+
targetPermission?: string | undefined;
|
|
103
|
+
}, {
|
|
104
|
+
category: "security" | "account" | "team" | "marketing" | "staff";
|
|
105
|
+
template: string;
|
|
106
|
+
recipient: {
|
|
107
|
+
email: string;
|
|
108
|
+
name?: string | undefined;
|
|
109
|
+
userId?: string | null | undefined;
|
|
110
|
+
locale?: string | null | undefined;
|
|
111
|
+
timezone?: string | null | undefined;
|
|
112
|
+
};
|
|
113
|
+
channels: ("email" | "in_app")[];
|
|
114
|
+
data?: Record<string, string | number | boolean | null> | undefined;
|
|
115
|
+
secretKeys?: string[] | undefined;
|
|
116
|
+
bypassPreferences?: boolean | undefined;
|
|
117
|
+
targetPermission?: string | undefined;
|
|
118
|
+
}>, {
|
|
119
|
+
data: Record<string, string | number | boolean | null>;
|
|
120
|
+
category: "security" | "account" | "team" | "marketing" | "staff";
|
|
121
|
+
template: string;
|
|
122
|
+
recipient: {
|
|
123
|
+
email: string;
|
|
124
|
+
name?: string | undefined;
|
|
125
|
+
userId?: string | null | undefined;
|
|
126
|
+
locale?: string | null | undefined;
|
|
127
|
+
timezone?: string | null | undefined;
|
|
128
|
+
};
|
|
129
|
+
channels: ("email" | "in_app")[];
|
|
130
|
+
secretKeys: string[];
|
|
131
|
+
bypassPreferences?: boolean | undefined;
|
|
132
|
+
targetPermission?: string | undefined;
|
|
133
|
+
}, {
|
|
134
|
+
category: "security" | "account" | "team" | "marketing" | "staff";
|
|
135
|
+
template: string;
|
|
136
|
+
recipient: {
|
|
137
|
+
email: string;
|
|
138
|
+
name?: string | undefined;
|
|
139
|
+
userId?: string | null | undefined;
|
|
140
|
+
locale?: string | null | undefined;
|
|
141
|
+
timezone?: string | null | undefined;
|
|
142
|
+
};
|
|
143
|
+
channels: ("email" | "in_app")[];
|
|
144
|
+
data?: Record<string, string | number | boolean | null> | undefined;
|
|
145
|
+
secretKeys?: string[] | undefined;
|
|
146
|
+
bypassPreferences?: boolean | undefined;
|
|
147
|
+
targetPermission?: string | undefined;
|
|
148
|
+
}>;
|
|
149
|
+
/**
|
|
150
|
+
* The seeded templates Showbiz services dispatch, with the variables (`data` keys) each dispatch carries.
|
|
151
|
+
* Producers send exactly these keys; a seeded template may use any subset (notification-service dead-letters
|
|
152
|
+
* a dispatch missing a variable its template uses). Both sides test against this table.
|
|
153
|
+
*/
|
|
154
|
+
export declare const DISPATCH_TEMPLATE_VARIABLES: {
|
|
155
|
+
readonly 'account-activation': readonly ["name", "code", "expiresInHours"];
|
|
156
|
+
readonly 'login-otp': readonly ["name", "code", "expiresInMinutes", "device"];
|
|
157
|
+
readonly 'password-reset': readonly ["name", "resetUrl", "expiresInMinutes"];
|
|
158
|
+
readonly 'staff-invitation': readonly ["name", "resetUrl", "expiresInMinutes"];
|
|
159
|
+
readonly 'password-changed': readonly ["name", "changedAt"];
|
|
160
|
+
readonly 'new-device-login': readonly ["name", "device", "ip", "country", "occurredAt", "confirmUrl", "disputeUrl"];
|
|
161
|
+
readonly 'team-member-added': readonly ["name", "profileName", "role", "invitedBy"];
|
|
162
|
+
readonly 'account-suspended': readonly ["name", "reason"];
|
|
163
|
+
readonly 'welcome-listener': readonly ["name"];
|
|
164
|
+
readonly 'welcome-creator': readonly ["name"];
|
|
165
|
+
readonly ai_budget_threshold: readonly ["requester", "period", "threshold_pct", "spent_usd", "limit_usd"];
|
|
166
|
+
readonly newswire_source_unhealthy: readonly ["source_name", "source_slug", "consecutive_failures", "last_error", "last_success_at"];
|
|
167
|
+
readonly newswire_block_rate_high: readonly ["blocked", "total", "block_rate_pct", "window_hours"];
|
|
168
|
+
readonly autopublish_audit_alert: readonly ["problem_rate_pct", "problem_count", "sample_count", "window_days", "action_taken"];
|
|
169
|
+
};
|
|
170
|
+
export type DispatchTemplate = keyof typeof DISPATCH_TEMPLATE_VARIABLES;
|
|
171
|
+
/** The validated command (defaults applied). */
|
|
172
|
+
export type NotificationDispatch = z.infer<typeof notificationDispatchSchema>;
|
|
173
|
+
/** What a producer stages: `data` and `secretKeys` may be omitted. */
|
|
174
|
+
export type NotificationDispatchInput = z.input<typeof notificationDispatchSchema>;
|
|
175
|
+
//# sourceMappingURL=notification-dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-dispatch.d.ts","sourceRoot":"","sources":["../../../src/contracts/notification-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D,wGAAwG;AACxG,eAAO,MAAM,iBAAiB,8BAA+B,CAAC;AAC9D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,uBAAuB,gEAAiE,CAAC;AACtG,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E,eAAO,MAAM,eAAe;;;;;;;;;CASlB,CAAC;AAEX,qGAAqG;AACrG,eAAO,MAAM,mBAAmB,iEAAmG,CAAC;AACpI,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,uBAAuB;;;;;IAKlC,oDAAoD;;;;;;;;;;;;;;EAEpD,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE,eAAO,MAAM,0BAA0B;IAEnC,4CAA4C;;;;;;;;QAT9C,oDAAoD;;;;;;;;;;;;;;;;;IAkBlD;;;;OAIG;;IAEH,4FAA4F;;IAE5F,uGAAuG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASvG,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;CAiBc,CAAC;AACvD,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,2BAA2B,CAAC;AAExE,gDAAgD;AAChD,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,sEAAsE;AACtE,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Licensed image import by URL (Newswire R5, decision R39). newswire-service (and later
|
|
4
|
+
* editorial-service) sends `upload:import`; upload-service fetches the file and answers with an
|
|
5
|
+
* `upload.import.completed` or `upload.import.failed` event. One contract for both sides.
|
|
6
|
+
*/
|
|
7
|
+
export declare const UPLOAD_IMPORT = "upload:import";
|
|
8
|
+
export declare const UPLOAD_IMPORT_EVENTS: {
|
|
9
|
+
readonly COMPLETED: "upload.import.completed";
|
|
10
|
+
readonly FAILED: "upload.import.failed";
|
|
11
|
+
};
|
|
12
|
+
/** Upload policies an import may use. */
|
|
13
|
+
export declare const UPLOAD_IMPORT_POLICIES: readonly ["news_image"];
|
|
14
|
+
export type UploadImportPolicy = (typeof UPLOAD_IMPORT_POLICIES)[number];
|
|
15
|
+
/** Field limits of the contract (upload-service's `uploads` columns). */
|
|
16
|
+
export declare const UPLOAD_IMPORT_LIMITS: {
|
|
17
|
+
readonly url: 2048;
|
|
18
|
+
readonly ownerType: 50;
|
|
19
|
+
readonly licenceHolder: 160;
|
|
20
|
+
readonly licenceBasis: 255;
|
|
21
|
+
readonly reason: 255;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* `upload:import` data. The URL is only length-checked here: upload-service rejects a non-https or
|
|
25
|
+
* unsafe URL itself, so the sender hears about it through a `failed` event instead of a dead letter.
|
|
26
|
+
*/
|
|
27
|
+
export declare const uploadImportCommandSchema: z.ZodObject<{
|
|
28
|
+
/** ULID the outcome event echoes back; upload-service is idempotent on it. */
|
|
29
|
+
importId: z.ZodString;
|
|
30
|
+
url: z.ZodString;
|
|
31
|
+
policy: z.ZodEnum<["news_image"]>;
|
|
32
|
+
/** Echoed in the outcome only; the imported upload is a system row with no owner. */
|
|
33
|
+
ownerType: z.ZodString;
|
|
34
|
+
ownerId: z.ZodString;
|
|
35
|
+
licence: z.ZodObject<{
|
|
36
|
+
holder: z.ZodString;
|
|
37
|
+
basis: z.ZodString;
|
|
38
|
+
}, "strip", z.ZodTypeAny, {
|
|
39
|
+
holder: string;
|
|
40
|
+
basis: string;
|
|
41
|
+
}, {
|
|
42
|
+
holder: string;
|
|
43
|
+
basis: string;
|
|
44
|
+
}>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
url: string;
|
|
47
|
+
importId: string;
|
|
48
|
+
policy: "news_image";
|
|
49
|
+
ownerType: string;
|
|
50
|
+
ownerId: string;
|
|
51
|
+
licence: {
|
|
52
|
+
holder: string;
|
|
53
|
+
basis: string;
|
|
54
|
+
};
|
|
55
|
+
}, {
|
|
56
|
+
url: string;
|
|
57
|
+
importId: string;
|
|
58
|
+
policy: "news_image";
|
|
59
|
+
ownerType: string;
|
|
60
|
+
ownerId: string;
|
|
61
|
+
licence: {
|
|
62
|
+
holder: string;
|
|
63
|
+
basis: string;
|
|
64
|
+
};
|
|
65
|
+
}>;
|
|
66
|
+
export declare const uploadImportCompletedSchema: z.ZodObject<{
|
|
67
|
+
importId: z.ZodString;
|
|
68
|
+
uploadId: z.ZodString;
|
|
69
|
+
ownerType: z.ZodString;
|
|
70
|
+
ownerId: z.ZodString;
|
|
71
|
+
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
uploadId: string;
|
|
73
|
+
importId: string;
|
|
74
|
+
ownerType: string;
|
|
75
|
+
ownerId: string;
|
|
76
|
+
}, {
|
|
77
|
+
uploadId: string;
|
|
78
|
+
importId: string;
|
|
79
|
+
ownerType: string;
|
|
80
|
+
ownerId: string;
|
|
81
|
+
}>;
|
|
82
|
+
/** `reason` is a machine code (`too_large`, `http_404`, …; see upload-service `ImportFailureReason`). */
|
|
83
|
+
export declare const uploadImportFailedSchema: z.ZodObject<{
|
|
84
|
+
importId: z.ZodString;
|
|
85
|
+
reason: z.ZodString;
|
|
86
|
+
}, "strip", z.ZodTypeAny, {
|
|
87
|
+
reason: string;
|
|
88
|
+
importId: string;
|
|
89
|
+
}, {
|
|
90
|
+
reason: string;
|
|
91
|
+
importId: string;
|
|
92
|
+
}>;
|
|
93
|
+
export type UploadImportCommand = z.infer<typeof uploadImportCommandSchema>;
|
|
94
|
+
export type UploadImportCompleted = z.infer<typeof uploadImportCompletedSchema>;
|
|
95
|
+
export type UploadImportFailed = z.infer<typeof uploadImportFailedSchema>;
|
|
96
|
+
//# sourceMappingURL=upload-import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-import.d.ts","sourceRoot":"","sources":["../../../src/contracts/upload-import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;GAIG;AACH,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX,yCAAyC;AACzC,eAAO,MAAM,sBAAsB,yBAA0B,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,yEAAyE;AACzE,eAAO,MAAM,oBAAoB;;;;;;CAMvB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,yBAAyB;IACpC,8EAA8E;;;;IAI9E,qFAAqF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOrF,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;EAKtC,CAAC;AAEH,yGAAyG;AACzG,eAAO,MAAM,wBAAwB;;;;;;;;;EAGnC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC5E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
import mysql from 'mysql2/promise';
|
|
3
|
+
export interface MysqlConnectionOptions {
|
|
4
|
+
host: string;
|
|
5
|
+
port: number;
|
|
6
|
+
user: string;
|
|
7
|
+
password: string;
|
|
8
|
+
database: string;
|
|
9
|
+
poolMax?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* mysql2 pool for Drizzle. Sessions run in UTC and utf8mb4 so timestamps and emoji round-trip
|
|
13
|
+
* unchanged regardless of server defaults.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createMysqlPool(options: MysqlConnectionOptions): mysql.Pool;
|
|
16
|
+
/** Knex config for migrations/seeds and query-builder use (same session settings as the pool). */
|
|
17
|
+
export declare function createKnexConfig(options: MysqlConnectionOptions & {
|
|
18
|
+
migrationsDir?: string;
|
|
19
|
+
seedsDir?: string;
|
|
20
|
+
}): Knex.Config;
|
|
21
|
+
/** Readiness probe helper. */
|
|
22
|
+
export declare function pingMysql(pool: mysql.Pool): Promise<void>;
|
|
23
|
+
/** Escapes `%`, `_` and `\` for use inside a LIKE pattern. */
|
|
24
|
+
export declare function escapeLike(value: string): string;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/database/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,MAAM,gBAAgB,CAAC;AAEnC,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,KAAK,CAAC,IAAI,CAe3E;AAED,kGAAkG;AAClG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,MAAM,CAgB7H;AAED,8BAA8B;AAC9B,wBAAsB,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/D;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
|
+
import type { AuthUser, Logger } from '../types/index.js';
|
|
3
|
+
declare global {
|
|
4
|
+
namespace Express {
|
|
5
|
+
interface Request {
|
|
6
|
+
user?: AuthUser;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export interface GatewayAuthOptions {
|
|
11
|
+
secret: string;
|
|
12
|
+
maxSkewMs?: number;
|
|
13
|
+
logger?: Logger;
|
|
14
|
+
}
|
|
15
|
+
/** Requires a valid gateway-signed identity; 401 otherwise. */
|
|
16
|
+
export declare function authenticateFromGateway(options: GatewayAuthOptions): RequestHandler;
|
|
17
|
+
/** Attaches `req.user` when a valid identity is present; continues anonymously otherwise. */
|
|
18
|
+
export declare function optionalAuthFromGateway(options: GatewayAuthOptions): RequestHandler;
|
|
19
|
+
/** Allows callers holding any of `permissions`. */
|
|
20
|
+
export declare const requirePermission: (...permissions: string[]) => RequestHandler;
|
|
21
|
+
/** Allows callers holding every one of `permissions`. */
|
|
22
|
+
export declare const requireAllPermissions: (...permissions: string[]) => RequestHandler;
|
|
23
|
+
/** Allows callers with any of `roles`. Prefer permissions; roles are for coarse gates only. */
|
|
24
|
+
export declare const requireRole: (...roles: string[]) => RequestHandler;
|
|
25
|
+
/** Guards `/internal/*` routes: requires the shared service secret header. */
|
|
26
|
+
export declare function requireInternalServiceSecret(secret: string): RequestHandler;
|
|
27
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/express/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,cAAc,EAAY,MAAM,SAAS,CAAC;AAK/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,IAAI,CAAC,EAAE,QAAQ,CAAC;SACjB;KACF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAeD,+DAA+D;AAC/D,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,CAKnF;AAED,6FAA6F;AAC7F,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,CAQnF;AAgBD,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,GAAI,GAAG,aAAa,MAAM,EAAE,KAAG,cAAgE,CAAC;AAE9H,yDAAyD;AACzD,eAAO,MAAM,qBAAqB,GAAI,GAAG,aAAa,MAAM,EAAE,KAAG,cAAoE,CAAC;AAEtI,+FAA+F;AAC/F,eAAO,MAAM,WAAW,GAAI,GAAG,OAAO,MAAM,EAAE,KAAG,cAAyE,CAAC;AAE3H,8EAA8E;AAC9E,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAM3E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
|
+
export type HealthCheck = () => Promise<unknown> | unknown;
|
|
3
|
+
export interface HealthOptions {
|
|
4
|
+
service: string;
|
|
5
|
+
version?: string;
|
|
6
|
+
/** Readiness dependencies, e.g. `{ mysql: () => pool.query('select 1'), rabbitmq: () => conn.assertReady() }`. */
|
|
7
|
+
checks?: Record<string, HealthCheck>;
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
}
|
|
10
|
+
/** `GET /health` — liveness: the process is up. Never touches dependencies. */
|
|
11
|
+
export declare function livenessHandler(options: HealthOptions): RequestHandler;
|
|
12
|
+
/** `GET /health/ready` — readiness: every dependency responds. 503 when any fails. */
|
|
13
|
+
export declare function readinessHandler(options: HealthOptions): RequestHandler;
|
|
14
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../src/express/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,cAAc,EAAY,MAAM,SAAS,CAAC;AAGjE,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kHAAkH;IAClH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,cAAc,CAKtE;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,cAAc,CAevE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/express/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ErrorRequestHandler, NextFunction, Request, RequestHandler, Response } from 'express';
|
|
2
|
+
import type { ZodTypeAny } from 'zod';
|
|
3
|
+
import type { Logger } from '../types/index.js';
|
|
4
|
+
/** Ensures every request carries `x-correlation-id` (reused from the gateway when present). */
|
|
5
|
+
export declare function correlationMiddleware(): RequestHandler;
|
|
6
|
+
export declare function correlationId(req: Request): string | undefined;
|
|
7
|
+
/** Real client IP: gateway-forwarded header first, then Express's `req.ip`. */
|
|
8
|
+
export declare function clientIp(req: Request): string | null;
|
|
9
|
+
export declare function clientTimezone(req: Request): string | null;
|
|
10
|
+
export declare function anonId(req: Request): string | null;
|
|
11
|
+
type RequestPart = 'body' | 'query' | 'params';
|
|
12
|
+
/** Validates and replaces `req[part]` with the parsed value; 422 with field errors on failure. */
|
|
13
|
+
export declare function validate(schema: ZodTypeAny, part?: RequestPart): RequestHandler;
|
|
14
|
+
/** Wraps an async handler so rejections reach the error middleware (needed on Express 4). */
|
|
15
|
+
export declare function asyncHandler<Req extends Request = Request>(fn: (req: Req, res: Response, next: NextFunction) => Promise<unknown>): RequestHandler;
|
|
16
|
+
/** Maps AppErrors to their status; everything else becomes a logged 500 with a generic message. */
|
|
17
|
+
export declare function errorHandler(logger?: Logger): ErrorRequestHandler;
|
|
18
|
+
export declare function notFoundHandler(): RequestHandler;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/express/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAKtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,+FAA+F;AAC/F,wBAAgB,qBAAqB,IAAI,cAAc,CAQtD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG9D;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAIpD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAG1D;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAGlD;AAED,KAAK,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE/C,kGAAkG;AAClG,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,WAAoB,GAAG,cAAc,CAWvF;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,GAAG,SAAS,OAAO,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,cAAc,CAIjJ;AAED,mGAAmG;AACnG,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAqBjE;AAED,wBAAgB,eAAe,IAAI,cAAc,CAIhD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type CorsOptions } from 'cors';
|
|
2
|
+
import { type HelmetOptions } from 'helmet';
|
|
3
|
+
import type { RequestHandler } from 'express';
|
|
4
|
+
export type { CorsOptions, HelmetOptions };
|
|
5
|
+
/** Standard security headers (helmet). Pass options only to relax a header a service genuinely needs. */
|
|
6
|
+
export declare function securityHeaders(options?: HelmetOptions): RequestHandler;
|
|
7
|
+
/** CORS for browser-facing services. An empty origin list disables CORS (no `Access-Control-*` headers). */
|
|
8
|
+
export declare function corsMiddleware(origins: string[], options?: Omit<CorsOptions, 'origin'>): RequestHandler;
|
|
9
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../src/express/security.ts"],"names":[],"mappings":"AAAA,OAAa,EAAE,KAAK,WAAW,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAe,EAAE,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAE3C,yGAAyG;AACzG,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,cAAc,CAEvE;AAED,4GAA4G;AAC5G,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAM,GAAG,cAAc,CAE3G"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Logger } from '../types/index.js';
|
|
2
|
+
export * from './safe-fetch.js';
|
|
3
|
+
export interface ServiceClientOptions {
|
|
4
|
+
/** e.g. `http://auth-admin-service:4001` */
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
/** Sent as `x-internal-service-secret`. */
|
|
7
|
+
internalSecret: string;
|
|
8
|
+
callerService: string;
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
/** Retries for network errors and 502/503/504 on idempotent methods. */
|
|
11
|
+
retries?: number;
|
|
12
|
+
logger?: Logger;
|
|
13
|
+
}
|
|
14
|
+
export interface RequestOptions {
|
|
15
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
16
|
+
body?: unknown;
|
|
17
|
+
headers?: Record<string, string>;
|
|
18
|
+
correlationId?: string;
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface ServiceClient {
|
|
22
|
+
get<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
23
|
+
post<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
24
|
+
put<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
25
|
+
patch<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
26
|
+
delete<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Typed client for `/internal/*` calls between services. Unwraps the `{ success, data }`
|
|
30
|
+
* envelope, maps upstream errors to AppErrors with the same status, and turns network failures
|
|
31
|
+
* and timeouts into 503s.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createServiceClient(options: ServiceClientOptions): ServiceClient;
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/http/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAe,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE7D,cAAc,iBAAiB,CAAC;AAEhC,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5D,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3D,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC/D;AAKD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAyDhF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Error codes raised by the safe fetcher. */
|
|
2
|
+
export type SafeFetchErrorCode = 'BLOCKED_ADDRESS' | 'PROTOCOL_NOT_ALLOWED' | 'TOO_MANY_REDIRECTS' | 'TOO_LARGE' | 'TIMEOUT' | 'NETWORK';
|
|
3
|
+
/** A fetch rejected for an SSRF guard, a limit, or a transport failure. */
|
|
4
|
+
export declare class SafeFetchError extends Error {
|
|
5
|
+
readonly code: SafeFetchErrorCode;
|
|
6
|
+
constructor(code: SafeFetchErrorCode, message: string, options?: {
|
|
7
|
+
cause?: unknown;
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
interface ResolvedAddress {
|
|
11
|
+
address: string;
|
|
12
|
+
family: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Node `dns.lookup`-shaped callback. The safe fetcher always calls it with `{ all: true }`, so the
|
|
16
|
+
* result is an array. Tests inject a fake to force a chosen address (including the rebinding case).
|
|
17
|
+
*/
|
|
18
|
+
export type SafeLookup = (hostname: string, options: {
|
|
19
|
+
all: true;
|
|
20
|
+
family?: number;
|
|
21
|
+
}, callback: (err: NodeJS.ErrnoException | null, addresses: ResolvedAddress[]) => void) => void;
|
|
22
|
+
export interface SafeFetcherOptions {
|
|
23
|
+
userAgent: string;
|
|
24
|
+
maxBytes: number;
|
|
25
|
+
timeoutMs: number;
|
|
26
|
+
maxRedirects?: number;
|
|
27
|
+
allowedProtocols?: string[];
|
|
28
|
+
/** Override DNS resolution (tests). Defaults to `node:dns` lookup. */
|
|
29
|
+
lookup?: SafeLookup;
|
|
30
|
+
/**
|
|
31
|
+
* IP literals that bypass the private/loopback blocklist. Empty by default; a service may allow a
|
|
32
|
+
* specific internal host. Also the seam the tests use to reach a loopback test server.
|
|
33
|
+
*/
|
|
34
|
+
allowedAddresses?: string[];
|
|
35
|
+
}
|
|
36
|
+
export interface SafeFetchRequest {
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
/** Value for the `accept` header. */
|
|
39
|
+
accept?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface SafeFetchResponse {
|
|
42
|
+
status: number;
|
|
43
|
+
headers: Record<string, string | string[] | undefined>;
|
|
44
|
+
body: Buffer;
|
|
45
|
+
finalUrl: string;
|
|
46
|
+
redirects: number;
|
|
47
|
+
}
|
|
48
|
+
export interface SafeFetcher {
|
|
49
|
+
fetch(url: string, req?: SafeFetchRequest): Promise<SafeFetchResponse>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns a human-readable reason if `ip` is a disallowed destination (private, loopback,
|
|
53
|
+
* link-local, CGNAT, multicast, unspecified, IPv4-mapped IPv6, cloud metadata), otherwise `null`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function blockedAddressReason(ip: string): string | null;
|
|
56
|
+
export declare function createSafeFetcher(options: SafeFetcherOptions): SafeFetcher;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=safe-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-fetch.d.ts","sourceRoot":"","sources":["../../../src/http/safe-fetch.ts"],"names":[],"mappings":"AAIA,8CAA8C;AAC9C,MAAM,MAAM,kBAAkB,GAC1B,iBAAiB,GACjB,sBAAsB,GACtB,oBAAoB,GACpB,WAAW,GACX,SAAS,GACT,SAAS,CAAC;AAEd,2EAA2E;AAC3E,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;gBAEtB,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAKrF;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,GAAG,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EACvC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,IAAI,KAChF,IAAI,CAAC;AAEV,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACxE;AAWD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK9D;AA6BD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CA2H1E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { AuthUser } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Header contract between the gateway and downstream services.
|
|
4
|
+
*
|
|
5
|
+
* The gateway strips any client-supplied identity headers, then writes these and signs them with
|
|
6
|
+
* `x-gateway-auth` = HMAC-SHA256(secret, canonical string). Services verify the signature and
|
|
7
|
+
* timestamp before trusting anything, so a request that bypasses the gateway on the internal
|
|
8
|
+
* network cannot forge an identity.
|
|
9
|
+
*/
|
|
10
|
+
export declare const IDENTITY_HEADERS: {
|
|
11
|
+
readonly USER_ID: "x-user-id";
|
|
12
|
+
readonly USER_EMAIL: "x-user-email";
|
|
13
|
+
readonly USER_ROLES: "x-user-roles";
|
|
14
|
+
readonly USER_PERMISSIONS: "x-user-permissions";
|
|
15
|
+
readonly USER_SCOPES: "x-user-scopes";
|
|
16
|
+
readonly USER_ATTRS: "x-user-attrs";
|
|
17
|
+
readonly SESSION_ID: "x-session-id";
|
|
18
|
+
readonly TIMESTAMP: "x-gateway-ts";
|
|
19
|
+
readonly SIGNATURE: "x-gateway-auth";
|
|
20
|
+
};
|
|
21
|
+
export declare const CONTEXT_HEADERS: {
|
|
22
|
+
readonly CORRELATION_ID: "x-correlation-id";
|
|
23
|
+
readonly ANON_ID: "x-anon-id";
|
|
24
|
+
readonly TIMEZONE: "x-timezone";
|
|
25
|
+
readonly CLIENT_IP: "x-client-ip";
|
|
26
|
+
readonly INTERNAL_SECRET: "x-internal-service-secret";
|
|
27
|
+
readonly CALLER_SERVICE: "x-caller-service";
|
|
28
|
+
};
|
|
29
|
+
/** Every header a client must never be allowed to set. */
|
|
30
|
+
export declare const PROTECTED_HEADERS: readonly string[];
|
|
31
|
+
type HeaderBag = Record<string, string | string[] | undefined>;
|
|
32
|
+
/** Gateway side: headers (including signature) that represent `user`. */
|
|
33
|
+
export declare function signIdentityHeaders(user: AuthUser, secret: string, now?: number): Record<string, string>;
|
|
34
|
+
export type IdentityResult = {
|
|
35
|
+
status: 'anonymous';
|
|
36
|
+
} | {
|
|
37
|
+
status: 'invalid';
|
|
38
|
+
reason: string;
|
|
39
|
+
} | {
|
|
40
|
+
status: 'authenticated';
|
|
41
|
+
user: AuthUser;
|
|
42
|
+
};
|
|
43
|
+
/** Service side: verifies and decodes the gateway identity headers. */
|
|
44
|
+
export declare function verifyIdentityHeaders(headers: HeaderBag, secret: string, options?: {
|
|
45
|
+
maxSkewMs?: number;
|
|
46
|
+
now?: number;
|
|
47
|
+
}): IdentityResult;
|
|
48
|
+
/** Removes every protected header in place (gateway ingress). */
|
|
49
|
+
export declare function stripProtectedHeaders(headers: HeaderBag): void;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/identity/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;CAUnB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;CAOlB,CAAC;AAEX,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAqG,CAAC;AAIrJ,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;AAiC/D,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAapH;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEhD,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,cAAc,CA6B5I;AAED,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAE9D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './types/index.js';
|
|
2
|
+
export * from './common/index.js';
|
|
3
|
+
export * from './identity/index.js';
|
|
4
|
+
export * from './access/index.js';
|
|
5
|
+
export * from './validation/index.js';
|
|
6
|
+
export * from './logging/index.js';
|
|
7
|
+
export * from './config/index.js';
|
|
8
|
+
export * from './contracts/index.js';
|
|
9
|
+
export * from './alerting/index.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
/**
|
|
3
|
+
* Migration helpers (usable from CommonJS `.cjs` migrations via `require('@heavybit/shared-lib/knex')`).
|
|
4
|
+
* They keep ID, timestamp and audit column definitions identical across services.
|
|
5
|
+
*/
|
|
6
|
+
/** `id CHAR(26)` primary key for ULIDs. */
|
|
7
|
+
export declare function ulidPrimary(table: Knex.CreateTableBuilder, name?: string): void;
|
|
8
|
+
/** `CHAR(26)` column referencing another ULID (FK constraints only within the same database). */
|
|
9
|
+
export declare function ulidColumn(table: Knex.CreateTableBuilder | Knex.AlterTableBuilder, name: string): Knex.ColumnBuilder;
|
|
10
|
+
/** `created_at` / `updated_at` as `DATETIME(3)` in UTC, maintained by MySQL. */
|
|
11
|
+
export declare function timestamps(table: Knex.CreateTableBuilder, knex: Knex): void;
|
|
12
|
+
/** `created_by` / `updated_by` actor columns (null for system operations). */
|
|
13
|
+
export declare function actorColumns(table: Knex.CreateTableBuilder): void;
|
|
14
|
+
/** Nullable `DATETIME(3)` column. */
|
|
15
|
+
export declare function datetime(table: Knex.CreateTableBuilder | Knex.AlterTableBuilder, name: string): Knex.ColumnBuilder;
|
|
16
|
+
/**
|
|
17
|
+
* Creates `<parent>_audits`: every parent column (defined again by `columns`) plus `parent_id`
|
|
18
|
+
* and `action`. Audit rows are append-only history, so no unique constraints are copied.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createAuditTable(knex: Knex, parentTable: string, columns: (table: Knex.CreateTableBuilder) => void): Promise<void>;
|
|
21
|
+
/** Transactional outbox table used by `OutboxRelay`. */
|
|
22
|
+
export declare function createOutboxTable(knex: Knex, name?: string): Promise<void>;
|
|
23
|
+
/** Standard table options: InnoDB, utf8mb4. Call inside `createTable`. */
|
|
24
|
+
export declare function utf8mb4(table: Knex.CreateTableBuilder): void;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/knex/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC;;;GAGG;AAEH,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,SAAO,GAAG,IAAI,CAE7E;AAED,iGAAiG;AACjG,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,aAAa,CAEpH;AAED,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAG3E;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAGjE;AAED,qCAAqC;AACrC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,aAAa,CAElH;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAYxI;AAED,wDAAwD;AACxD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYxF;AAED,0EAA0E;AAC1E,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAI5D"}
|