@heavybit/shared-lib 2.1.0 → 2.7.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/README.md +163 -2
- package/dist/cjs/access/index.js +9 -1
- package/dist/cjs/access/index.js.map +1 -1
- package/dist/cjs/approvals/index.js +137 -0
- package/dist/cjs/approvals/index.js.map +1 -0
- package/dist/cjs/audit/index.js +74 -0
- package/dist/cjs/audit/index.js.map +1 -0
- package/dist/cjs/cache/index.js +90 -16
- package/dist/cjs/cache/index.js.map +1 -1
- package/dist/cjs/cache/keyspace.js +101 -0
- package/dist/cjs/cache/keyspace.js.map +1 -0
- package/dist/cjs/common/circuit-breaker.js +74 -0
- package/dist/cjs/common/circuit-breaker.js.map +1 -0
- package/dist/cjs/common/index.js +4 -0
- package/dist/cjs/common/index.js.map +1 -1
- package/dist/cjs/common/internal-client.js +177 -0
- package/dist/cjs/common/internal-client.js.map +1 -0
- package/dist/cjs/common/internal-constants.js +12 -0
- package/dist/cjs/common/internal-constants.js.map +1 -0
- package/dist/cjs/common/internal-service-auth.js +160 -0
- package/dist/cjs/common/internal-service-auth.js.map +1 -0
- package/dist/cjs/common/money.js +215 -0
- package/dist/cjs/common/money.js.map +1 -0
- package/dist/cjs/common/phone.js +41 -22
- package/dist/cjs/common/phone.js.map +1 -1
- package/dist/cjs/common/time.js +28 -2
- package/dist/cjs/common/time.js.map +1 -1
- package/dist/cjs/config/index.js +139 -19
- package/dist/cjs/config/index.js.map +1 -1
- package/dist/cjs/contracts/notification-dispatch.js +1 -1
- package/dist/cjs/database/db.js +37 -0
- package/dist/cjs/database/db.js.map +1 -0
- package/dist/cjs/database/index.js +22 -51
- package/dist/cjs/database/index.js.map +1 -1
- package/dist/cjs/database/pagination.js +88 -0
- package/dist/cjs/database/pagination.js.map +1 -0
- package/dist/cjs/database/pool.js +60 -0
- package/dist/cjs/database/pool.js.map +1 -0
- package/dist/cjs/database/scoped-repository.js +132 -0
- package/dist/cjs/database/scoped-repository.js.map +1 -0
- package/dist/cjs/database/scopes.js +166 -0
- package/dist/cjs/database/scopes.js.map +1 -0
- package/dist/cjs/database/table-names.js +14 -0
- package/dist/cjs/database/table-names.js.map +1 -0
- package/dist/cjs/database/tables.js +71 -0
- package/dist/cjs/database/tables.js.map +1 -0
- package/dist/cjs/express/auth.js +64 -50
- package/dist/cjs/express/auth.js.map +1 -1
- package/dist/cjs/express/index.js +2 -0
- package/dist/cjs/express/index.js.map +1 -1
- package/dist/cjs/express/internal-caller.js +52 -0
- package/dist/cjs/express/internal-caller.js.map +1 -0
- package/dist/cjs/express/step-up.js +41 -0
- package/dist/cjs/express/step-up.js.map +1 -0
- package/dist/cjs/http/index.js +3 -71
- package/dist/cjs/http/index.js.map +1 -1
- package/dist/cjs/identity/index.js +269 -67
- package/dist/cjs/identity/index.js.map +1 -1
- package/dist/cjs/identity/step-up.js +52 -0
- package/dist/cjs/identity/step-up.js.map +1 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/knex/columns.js +36 -0
- package/dist/cjs/knex/columns.js.map +1 -0
- package/dist/cjs/knex/index.js +26 -43
- package/dist/cjs/knex/index.js.map +1 -1
- package/dist/cjs/knex/migration-helpers.js +57 -0
- package/dist/cjs/knex/migration-helpers.js.map +1 -0
- package/dist/cjs/logging/redact.js +6 -11
- package/dist/cjs/logging/redact.js.map +1 -1
- package/dist/cjs/messaging/base-consumer.js +36 -0
- package/dist/cjs/messaging/base-consumer.js.map +1 -0
- package/dist/cjs/messaging/consumer.js +142 -73
- package/dist/cjs/messaging/consumer.js.map +1 -1
- package/dist/cjs/messaging/envelope.js +53 -10
- package/dist/cjs/messaging/envelope.js.map +1 -1
- package/dist/cjs/messaging/idempotency.js +95 -8
- package/dist/cjs/messaging/idempotency.js.map +1 -1
- package/dist/cjs/messaging/index.js +2 -1
- package/dist/cjs/messaging/index.js.map +1 -1
- package/dist/cjs/messaging/outbox.js +97 -55
- package/dist/cjs/messaging/outbox.js.map +1 -1
- package/dist/cjs/messaging/publisher.js +86 -38
- package/dist/cjs/messaging/publisher.js.map +1 -1
- package/dist/cjs/messaging/staff-notifier.js +4 -4
- package/dist/cjs/messaging/staff-notifier.js.map +1 -1
- package/dist/cjs/messaging/topology.js +41 -5
- package/dist/cjs/messaging/topology.js.map +1 -1
- package/dist/cjs/rate-limit/index.js +57 -6
- package/dist/cjs/rate-limit/index.js.map +1 -1
- package/dist/cjs/rate-limit/keys.js +47 -0
- package/dist/cjs/rate-limit/keys.js.map +1 -0
- package/dist/cjs/socket/index.js +127 -16
- package/dist/cjs/socket/index.js.map +1 -1
- package/dist/cjs/socket/ticket.js +124 -0
- package/dist/cjs/socket/ticket.js.map +1 -0
- package/dist/cjs/testing/index.js +23 -14
- package/dist/cjs/testing/index.js.map +1 -1
- package/dist/esm/access/index.js +9 -1
- package/dist/esm/access/index.js.map +1 -1
- package/dist/esm/approvals/index.js +127 -0
- package/dist/esm/approvals/index.js.map +1 -0
- package/dist/esm/audit/index.js +70 -0
- package/dist/esm/audit/index.js.map +1 -0
- package/dist/esm/cache/index.js +70 -13
- package/dist/esm/cache/index.js.map +1 -1
- package/dist/esm/cache/keyspace.js +95 -0
- package/dist/esm/cache/keyspace.js.map +1 -0
- package/dist/esm/common/circuit-breaker.js +70 -0
- package/dist/esm/common/circuit-breaker.js.map +1 -0
- package/dist/esm/common/index.js +4 -0
- package/dist/esm/common/index.js.map +1 -1
- package/dist/esm/common/internal-client.js +173 -0
- package/dist/esm/common/internal-client.js.map +1 -0
- package/dist/esm/common/internal-constants.js +9 -0
- package/dist/esm/common/internal-constants.js.map +1 -0
- package/dist/esm/common/internal-service-auth.js +150 -0
- package/dist/esm/common/internal-service-auth.js.map +1 -0
- package/dist/esm/common/money.js +207 -0
- package/dist/esm/common/money.js.map +1 -0
- package/dist/esm/common/phone.js +41 -22
- package/dist/esm/common/phone.js.map +1 -1
- package/dist/esm/common/time.js +27 -2
- package/dist/esm/common/time.js.map +1 -1
- package/dist/esm/config/index.js +135 -18
- package/dist/esm/config/index.js.map +1 -1
- package/dist/esm/contracts/notification-dispatch.js +1 -1
- package/dist/esm/database/db.js +32 -0
- package/dist/esm/database/db.js.map +1 -0
- package/dist/esm/database/index.js +9 -45
- package/dist/esm/database/index.js.map +1 -1
- package/dist/esm/database/pagination.js +81 -0
- package/dist/esm/database/pagination.js.map +1 -0
- package/dist/esm/database/pool.js +51 -0
- package/dist/esm/database/pool.js.map +1 -0
- package/dist/esm/database/scoped-repository.js +128 -0
- package/dist/esm/database/scoped-repository.js.map +1 -0
- package/dist/esm/database/scopes.js +157 -0
- package/dist/esm/database/scopes.js.map +1 -0
- package/dist/esm/database/table-names.js +11 -0
- package/dist/esm/database/table-names.js.map +1 -0
- package/dist/esm/database/tables.js +61 -0
- package/dist/esm/database/tables.js.map +1 -0
- package/dist/esm/express/auth.js +62 -48
- package/dist/esm/express/auth.js.map +1 -1
- package/dist/esm/express/index.js +2 -0
- package/dist/esm/express/index.js.map +1 -1
- package/dist/esm/express/internal-caller.js +49 -0
- package/dist/esm/express/internal-caller.js.map +1 -0
- package/dist/esm/express/step-up.js +38 -0
- package/dist/esm/express/step-up.js.map +1 -0
- package/dist/esm/http/index.js +3 -70
- package/dist/esm/http/index.js.map +1 -1
- package/dist/esm/identity/index.js +246 -64
- package/dist/esm/identity/index.js.map +1 -1
- package/dist/esm/identity/step-up.js +47 -0
- package/dist/esm/identity/step-up.js.map +1 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/knex/columns.js +28 -0
- package/dist/esm/knex/columns.js.map +1 -0
- package/dist/esm/knex/index.js +8 -34
- package/dist/esm/knex/index.js.map +1 -1
- package/dist/esm/knex/migration-helpers.js +51 -0
- package/dist/esm/knex/migration-helpers.js.map +1 -0
- package/dist/esm/logging/redact.js +3 -7
- package/dist/esm/logging/redact.js.map +1 -1
- package/dist/esm/messaging/base-consumer.js +32 -0
- package/dist/esm/messaging/base-consumer.js.map +1 -0
- package/dist/esm/messaging/consumer.js +139 -71
- package/dist/esm/messaging/consumer.js.map +1 -1
- package/dist/esm/messaging/envelope.js +50 -10
- package/dist/esm/messaging/envelope.js.map +1 -1
- package/dist/esm/messaging/idempotency.js +91 -7
- package/dist/esm/messaging/idempotency.js.map +1 -1
- package/dist/esm/messaging/index.js +2 -1
- package/dist/esm/messaging/index.js.map +1 -1
- package/dist/esm/messaging/outbox.js +97 -54
- package/dist/esm/messaging/outbox.js.map +1 -1
- package/dist/esm/messaging/publisher.js +86 -38
- package/dist/esm/messaging/publisher.js.map +1 -1
- package/dist/esm/messaging/staff-notifier.js +4 -4
- package/dist/esm/messaging/staff-notifier.js.map +1 -1
- package/dist/esm/messaging/topology.js +39 -4
- package/dist/esm/messaging/topology.js.map +1 -1
- package/dist/esm/rate-limit/index.js +41 -6
- package/dist/esm/rate-limit/index.js.map +1 -1
- package/dist/esm/rate-limit/keys.js +43 -0
- package/dist/esm/rate-limit/keys.js.map +1 -0
- package/dist/esm/socket/index.js +112 -17
- package/dist/esm/socket/index.js.map +1 -1
- package/dist/esm/socket/ticket.js +117 -0
- package/dist/esm/socket/ticket.js.map +1 -0
- package/dist/esm/testing/index.js +24 -15
- package/dist/esm/testing/index.js.map +1 -1
- package/dist/types/access/index.d.ts +9 -3
- package/dist/types/access/index.d.ts.map +1 -1
- package/dist/types/approvals/index.d.ts +99 -0
- package/dist/types/approvals/index.d.ts.map +1 -0
- package/dist/types/audit/index.d.ts +82 -0
- package/dist/types/audit/index.d.ts.map +1 -0
- package/dist/types/cache/index.d.ts +64 -14
- package/dist/types/cache/index.d.ts.map +1 -1
- package/dist/types/cache/keyspace.d.ts +84 -0
- package/dist/types/cache/keyspace.d.ts.map +1 -0
- package/dist/types/common/circuit-breaker.d.ts +51 -0
- package/dist/types/common/circuit-breaker.d.ts.map +1 -0
- package/dist/types/common/index.d.ts +4 -0
- package/dist/types/common/index.d.ts.map +1 -1
- package/dist/types/common/internal-client.d.ts +116 -0
- package/dist/types/common/internal-client.d.ts.map +1 -0
- package/dist/types/common/internal-constants.d.ts +9 -0
- package/dist/types/common/internal-constants.d.ts.map +1 -0
- package/dist/types/common/internal-service-auth.d.ts +102 -0
- package/dist/types/common/internal-service-auth.d.ts.map +1 -0
- package/dist/types/common/money.d.ts +104 -0
- package/dist/types/common/money.d.ts.map +1 -0
- package/dist/types/common/phone.d.ts +25 -15
- package/dist/types/common/phone.d.ts.map +1 -1
- package/dist/types/common/time.d.ts +20 -2
- package/dist/types/common/time.d.ts.map +1 -1
- package/dist/types/config/index.d.ts +251 -27
- package/dist/types/config/index.d.ts.map +1 -1
- package/dist/types/contracts/notification-dispatch.d.ts +13 -13
- package/dist/types/database/db.d.ts +46 -0
- package/dist/types/database/db.d.ts.map +1 -0
- package/dist/types/database/index.d.ts +9 -22
- package/dist/types/database/index.d.ts.map +1 -1
- package/dist/types/database/pagination.d.ts +68 -0
- package/dist/types/database/pagination.d.ts.map +1 -0
- package/dist/types/database/pool.d.ts +39 -0
- package/dist/types/database/pool.d.ts.map +1 -0
- package/dist/types/database/scoped-repository.d.ts +92 -0
- package/dist/types/database/scoped-repository.d.ts.map +1 -0
- package/dist/types/database/scopes.d.ts +159 -0
- package/dist/types/database/scopes.d.ts.map +1 -0
- package/dist/types/database/table-names.d.ts +13 -0
- package/dist/types/database/table-names.d.ts.map +1 -0
- package/dist/types/database/tables.d.ts +748 -0
- package/dist/types/database/tables.d.ts.map +1 -0
- package/dist/types/express/auth.d.ts +40 -24
- package/dist/types/express/auth.d.ts.map +1 -1
- package/dist/types/express/index.d.ts +2 -0
- package/dist/types/express/index.d.ts.map +1 -1
- package/dist/types/express/internal-caller.d.ts +53 -0
- package/dist/types/express/internal-caller.d.ts.map +1 -0
- package/dist/types/express/step-up.d.ts +38 -0
- package/dist/types/express/step-up.d.ts.map +1 -0
- package/dist/types/http/index.d.ts +3 -31
- package/dist/types/http/index.d.ts.map +1 -1
- package/dist/types/identity/index.d.ts +159 -21
- package/dist/types/identity/index.d.ts.map +1 -1
- package/dist/types/identity/step-up.d.ts +41 -0
- package/dist/types/identity/step-up.d.ts.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/knex/columns.d.ts +15 -0
- package/dist/types/knex/columns.d.ts.map +1 -0
- package/dist/types/knex/index.d.ts +3 -11
- package/dist/types/knex/index.d.ts.map +1 -1
- package/dist/types/knex/migration-helpers.d.ts +28 -0
- package/dist/types/knex/migration-helpers.d.ts.map +1 -0
- package/dist/types/logging/redact.d.ts +2 -2
- package/dist/types/logging/redact.d.ts.map +1 -1
- package/dist/types/messaging/base-consumer.d.ts +33 -0
- package/dist/types/messaging/base-consumer.d.ts.map +1 -0
- package/dist/types/messaging/consumer.d.ts +59 -21
- package/dist/types/messaging/consumer.d.ts.map +1 -1
- package/dist/types/messaging/envelope.d.ts +50 -11
- package/dist/types/messaging/envelope.d.ts.map +1 -1
- package/dist/types/messaging/idempotency.d.ts +60 -3
- package/dist/types/messaging/idempotency.d.ts.map +1 -1
- package/dist/types/messaging/index.d.ts +7 -0
- package/dist/types/messaging/index.d.ts.map +1 -1
- package/dist/types/messaging/outbox.d.ts +62 -22
- package/dist/types/messaging/outbox.d.ts.map +1 -1
- package/dist/types/messaging/publisher.d.ts +54 -21
- package/dist/types/messaging/publisher.d.ts.map +1 -1
- package/dist/types/messaging/staff-notifier.d.ts +9 -9
- package/dist/types/messaging/staff-notifier.d.ts.map +1 -1
- package/dist/types/messaging/staff-recipients.d.ts +1 -1
- package/dist/types/messaging/topology.d.ts +40 -8
- package/dist/types/messaging/topology.d.ts.map +1 -1
- package/dist/types/rate-limit/index.d.ts +40 -4
- package/dist/types/rate-limit/index.d.ts.map +1 -1
- package/dist/types/rate-limit/keys.d.ts +52 -0
- package/dist/types/rate-limit/keys.d.ts.map +1 -0
- package/dist/types/socket/index.d.ts +86 -2
- package/dist/types/socket/index.d.ts.map +1 -1
- package/dist/types/socket/ticket.d.ts +90 -0
- package/dist/types/socket/ticket.d.ts.map +1 -0
- package/dist/types/testing/index.d.ts +31 -10
- package/dist/types/testing/index.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +26 -14
- package/dist/types/types/index.d.ts.map +1 -1
- package/package.json +3 -1
|
@@ -1,9 +1,5 @@
|
|
|
1
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
|
-
*/
|
|
2
|
+
/** Service identity, logging, CORS and the gateway signing secret. */
|
|
7
3
|
export declare const serviceEnv: z.ZodObject<{
|
|
8
4
|
NODE_ENV: z.ZodDefault<z.ZodEnum<["development", "test", "staging", "production"]>>;
|
|
9
5
|
PORT: z.ZodNumber;
|
|
@@ -12,29 +8,46 @@ export declare const serviceEnv: z.ZodObject<{
|
|
|
12
8
|
APP_NAME: z.ZodDefault<z.ZodString>;
|
|
13
9
|
LOG_LEVEL: z.ZodOptional<z.ZodEnum<["error", "warn", "info", "http", "debug"]>>;
|
|
14
10
|
CORS_ORIGINS: z.ZodDefault<z.ZodString>;
|
|
15
|
-
/** Verifies gateway-signed identity headers. */
|
|
16
|
-
|
|
17
|
-
/** Authenticates service-to-service `/internal/*` calls. */
|
|
18
|
-
INTERNAL_SERVICE_SECRET: z.ZodString;
|
|
11
|
+
/** Verifies gateway-signed identity headers (v2); at least 32 characters, same value on the gateway and every service. */
|
|
12
|
+
GATEWAY_SIGNING_SECRET: z.ZodString;
|
|
19
13
|
}, "strip", z.ZodTypeAny, {
|
|
20
|
-
NODE_ENV: "
|
|
14
|
+
NODE_ENV: "development" | "test" | "staging" | "production";
|
|
21
15
|
PORT: number;
|
|
22
16
|
SERVICE_NAME: string;
|
|
23
17
|
APP_NAME: string;
|
|
24
18
|
CORS_ORIGINS: string;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
LOG_LEVEL?: "info" | "debug" | "error" | "warn" | "http" | undefined;
|
|
19
|
+
GATEWAY_SIGNING_SECRET: string;
|
|
20
|
+
LOG_LEVEL?: "error" | "warn" | "info" | "http" | "debug" | undefined;
|
|
28
21
|
}, {
|
|
29
22
|
PORT: number;
|
|
30
23
|
SERVICE_NAME: string;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
NODE_ENV?: "production" | "test" | "development" | "staging" | undefined;
|
|
34
|
-
LOG_LEVEL?: "info" | "debug" | "error" | "warn" | "http" | undefined;
|
|
24
|
+
GATEWAY_SIGNING_SECRET: string;
|
|
25
|
+
NODE_ENV?: "development" | "test" | "staging" | "production" | undefined;
|
|
35
26
|
APP_NAME?: string | undefined;
|
|
27
|
+
LOG_LEVEL?: "error" | "warn" | "info" | "http" | "debug" | undefined;
|
|
36
28
|
CORS_ORIGINS?: string | undefined;
|
|
37
29
|
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Service-to-service credentials. Optional here because development may run without them;
|
|
32
|
+
* `assertInternalServiceAuthConfigured` enforces them in staging and production.
|
|
33
|
+
*/
|
|
34
|
+
export declare const internalServiceEnv: z.ZodObject<{
|
|
35
|
+
/** This service's own name (its compose service name), sent with every internal call. */
|
|
36
|
+
INTERNAL_SERVICE_NAME: z.ZodOptional<z.ZodString>;
|
|
37
|
+
/** This service's own secret (at least 32 characters), sent with every internal call. */
|
|
38
|
+
INTERNAL_SERVICE_CREDENTIAL: z.ZodOptional<z.ZodString>;
|
|
39
|
+
/** JSON map of caller name → secret this service accepts from that caller. */
|
|
40
|
+
INTERNAL_SERVICE_CREDENTIALS: z.ZodOptional<z.ZodString>;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
INTERNAL_SERVICE_NAME?: string | undefined;
|
|
43
|
+
INTERNAL_SERVICE_CREDENTIAL?: string | undefined;
|
|
44
|
+
INTERNAL_SERVICE_CREDENTIALS?: string | undefined;
|
|
45
|
+
}, {
|
|
46
|
+
INTERNAL_SERVICE_NAME?: string | undefined;
|
|
47
|
+
INTERNAL_SERVICE_CREDENTIAL?: string | undefined;
|
|
48
|
+
INTERNAL_SERVICE_CREDENTIALS?: string | undefined;
|
|
49
|
+
}>;
|
|
50
|
+
/** Database connection env vars (MySQL defaults). */
|
|
38
51
|
export declare const databaseEnv: z.ZodObject<{
|
|
39
52
|
DB_HOST: z.ZodDefault<z.ZodString>;
|
|
40
53
|
DB_PORT: z.ZodDefault<z.ZodNumber>;
|
|
@@ -57,6 +70,7 @@ export declare const databaseEnv: z.ZodObject<{
|
|
|
57
70
|
DB_PASSWORD?: string | undefined;
|
|
58
71
|
DB_POOL_MAX?: number | undefined;
|
|
59
72
|
}>;
|
|
73
|
+
/** RabbitMQ connection and queue-prefix env vars. */
|
|
60
74
|
export declare const messagingEnv: z.ZodObject<{
|
|
61
75
|
RABBITMQ_URL: z.ZodOptional<z.ZodString>;
|
|
62
76
|
RABBITMQ_HOST: z.ZodDefault<z.ZodString>;
|
|
@@ -86,30 +100,240 @@ export declare const messagingEnv: z.ZodObject<{
|
|
|
86
100
|
QUEUE_PREFIX?: string | undefined;
|
|
87
101
|
RABBITMQ_ENABLED?: "true" | "false" | undefined;
|
|
88
102
|
}>;
|
|
103
|
+
/** Redis connection env vars. Keys are prefixed by the keyspace (`createRedisKeyspace`), never by the client. */
|
|
89
104
|
export declare const redisEnv: z.ZodObject<{
|
|
105
|
+
/** Full connection URL; overrides host/port/password when set. */
|
|
90
106
|
REDIS_URL: z.ZodOptional<z.ZodString>;
|
|
107
|
+
REDIS_HOST: z.ZodDefault<z.ZodString>;
|
|
108
|
+
REDIS_PORT: z.ZodDefault<z.ZodNumber>;
|
|
109
|
+
REDIS_PASSWORD: z.ZodOptional<z.ZodString>;
|
|
91
110
|
REDIS_DB: z.ZodDefault<z.ZodNumber>;
|
|
92
|
-
/**
|
|
93
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Environment segment of every Redis key (`{app}:{env}:{service}:…`), e.g. `dev`, `staging`, `prod`.
|
|
113
|
+
* Required in staging and production; never share one between environments.
|
|
114
|
+
*/
|
|
115
|
+
CACHE_KEY_PREFIX: z.ZodOptional<z.ZodString>;
|
|
94
116
|
}, "strip", z.ZodTypeAny, {
|
|
117
|
+
REDIS_HOST: string;
|
|
118
|
+
REDIS_PORT: number;
|
|
95
119
|
REDIS_DB: number;
|
|
96
|
-
REDIS_PREFIX: string;
|
|
97
120
|
REDIS_URL?: string | undefined;
|
|
121
|
+
REDIS_PASSWORD?: string | undefined;
|
|
122
|
+
CACHE_KEY_PREFIX?: string | undefined;
|
|
98
123
|
}, {
|
|
99
124
|
REDIS_URL?: string | undefined;
|
|
125
|
+
REDIS_HOST?: string | undefined;
|
|
126
|
+
REDIS_PORT?: number | undefined;
|
|
127
|
+
REDIS_PASSWORD?: string | undefined;
|
|
100
128
|
REDIS_DB?: number | undefined;
|
|
101
|
-
|
|
129
|
+
CACHE_KEY_PREFIX?: string | undefined;
|
|
102
130
|
}>;
|
|
103
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Builds an AMQP URL from discrete env vars (or returns RABBITMQ_URL when set). User, password and vhost are URL-encoded.
|
|
133
|
+
*
|
|
134
|
+
* @param env Parsed {@link messagingEnv} values.
|
|
135
|
+
* @returns An `amqp://` URL.
|
|
136
|
+
* @example const url = amqpUrlFromEnv(parseEnv(messagingEnv));
|
|
137
|
+
*/
|
|
104
138
|
export declare function amqpUrlFromEnv(env: z.infer<typeof messagingEnv>): string;
|
|
105
|
-
/**
|
|
139
|
+
/**
|
|
140
|
+
* Reads `KEY=value` lines from a dotenv file into process.env without overriding set values. Missing file is a no-op.
|
|
141
|
+
*
|
|
142
|
+
* @param path Dotenv file (default `./.env`).
|
|
143
|
+
* @example loadDotEnv(resolve(__dirname, '../.env.test'));
|
|
144
|
+
*/
|
|
106
145
|
export declare function loadDotEnv(path?: string): void;
|
|
146
|
+
/** Thrown by the env loader when required variables are missing or invalid; lists every problem. */
|
|
107
147
|
export declare class ConfigError extends Error {
|
|
108
148
|
}
|
|
109
|
-
/**
|
|
110
|
-
|
|
149
|
+
/**
|
|
150
|
+
* The base environment every service validates: service identity, gateway secret, database, Redis,
|
|
151
|
+
* RabbitMQ and internal-service credentials. `loadEnv` merges a service's own schema onto it.
|
|
152
|
+
*/
|
|
153
|
+
export declare const baseEnv: z.ZodObject<{
|
|
154
|
+
NODE_ENV: z.ZodDefault<z.ZodEnum<["development", "test", "staging", "production"]>>;
|
|
155
|
+
PORT: z.ZodNumber;
|
|
156
|
+
SERVICE_NAME: z.ZodString;
|
|
157
|
+
/** Short app identifier used in exchange names and key prefixes (e.g. `myapp`). */
|
|
158
|
+
APP_NAME: z.ZodDefault<z.ZodString>;
|
|
159
|
+
LOG_LEVEL: z.ZodOptional<z.ZodEnum<["error", "warn", "info", "http", "debug"]>>;
|
|
160
|
+
CORS_ORIGINS: z.ZodDefault<z.ZodString>;
|
|
161
|
+
/** Verifies gateway-signed identity headers (v2); at least 32 characters, same value on the gateway and every service. */
|
|
162
|
+
GATEWAY_SIGNING_SECRET: z.ZodString;
|
|
163
|
+
} & {
|
|
164
|
+
DB_HOST: z.ZodDefault<z.ZodString>;
|
|
165
|
+
DB_PORT: z.ZodDefault<z.ZodNumber>;
|
|
166
|
+
DB_USER: z.ZodDefault<z.ZodString>;
|
|
167
|
+
DB_PASSWORD: z.ZodDefault<z.ZodString>;
|
|
168
|
+
DB_NAME: z.ZodString;
|
|
169
|
+
DB_POOL_MAX: z.ZodDefault<z.ZodNumber>;
|
|
170
|
+
} & {
|
|
171
|
+
/** Full connection URL; overrides host/port/password when set. */
|
|
172
|
+
REDIS_URL: z.ZodOptional<z.ZodString>;
|
|
173
|
+
REDIS_HOST: z.ZodDefault<z.ZodString>;
|
|
174
|
+
REDIS_PORT: z.ZodDefault<z.ZodNumber>;
|
|
175
|
+
REDIS_PASSWORD: z.ZodOptional<z.ZodString>;
|
|
176
|
+
REDIS_DB: z.ZodDefault<z.ZodNumber>;
|
|
177
|
+
/**
|
|
178
|
+
* Environment segment of every Redis key (`{app}:{env}:{service}:…`), e.g. `dev`, `staging`, `prod`.
|
|
179
|
+
* Required in staging and production; never share one between environments.
|
|
180
|
+
*/
|
|
181
|
+
CACHE_KEY_PREFIX: z.ZodOptional<z.ZodString>;
|
|
182
|
+
} & {
|
|
183
|
+
RABBITMQ_URL: z.ZodOptional<z.ZodString>;
|
|
184
|
+
RABBITMQ_HOST: z.ZodDefault<z.ZodString>;
|
|
185
|
+
RABBITMQ_PORT: z.ZodDefault<z.ZodNumber>;
|
|
186
|
+
RABBITMQ_USER: z.ZodDefault<z.ZodString>;
|
|
187
|
+
RABBITMQ_PASSWORD: z.ZodDefault<z.ZodString>;
|
|
188
|
+
RABBITMQ_VHOST: z.ZodDefault<z.ZodString>;
|
|
189
|
+
/** Environment prefix for queue and exchange names (`dev`, `staging`, `prod`). */
|
|
190
|
+
QUEUE_PREFIX: z.ZodDefault<z.ZodString>;
|
|
191
|
+
RABBITMQ_ENABLED: z.ZodEffects<z.ZodDefault<z.ZodEnum<["true", "false"]>>, boolean, "true" | "false" | undefined>;
|
|
192
|
+
} & {
|
|
193
|
+
/** This service's own name (its compose service name), sent with every internal call. */
|
|
194
|
+
INTERNAL_SERVICE_NAME: z.ZodOptional<z.ZodString>;
|
|
195
|
+
/** This service's own secret (at least 32 characters), sent with every internal call. */
|
|
196
|
+
INTERNAL_SERVICE_CREDENTIAL: z.ZodOptional<z.ZodString>;
|
|
197
|
+
/** JSON map of caller name → secret this service accepts from that caller. */
|
|
198
|
+
INTERNAL_SERVICE_CREDENTIALS: z.ZodOptional<z.ZodString>;
|
|
199
|
+
}, "strip", z.ZodTypeAny, {
|
|
200
|
+
NODE_ENV: "development" | "test" | "staging" | "production";
|
|
201
|
+
PORT: number;
|
|
202
|
+
SERVICE_NAME: string;
|
|
203
|
+
APP_NAME: string;
|
|
204
|
+
CORS_ORIGINS: string;
|
|
205
|
+
GATEWAY_SIGNING_SECRET: string;
|
|
206
|
+
DB_HOST: string;
|
|
207
|
+
DB_PORT: number;
|
|
208
|
+
DB_USER: string;
|
|
209
|
+
DB_PASSWORD: string;
|
|
210
|
+
DB_NAME: string;
|
|
211
|
+
DB_POOL_MAX: number;
|
|
212
|
+
RABBITMQ_HOST: string;
|
|
213
|
+
RABBITMQ_PORT: number;
|
|
214
|
+
RABBITMQ_USER: string;
|
|
215
|
+
RABBITMQ_PASSWORD: string;
|
|
216
|
+
RABBITMQ_VHOST: string;
|
|
217
|
+
QUEUE_PREFIX: string;
|
|
218
|
+
RABBITMQ_ENABLED: boolean;
|
|
219
|
+
REDIS_HOST: string;
|
|
220
|
+
REDIS_PORT: number;
|
|
221
|
+
REDIS_DB: number;
|
|
222
|
+
LOG_LEVEL?: "error" | "warn" | "info" | "http" | "debug" | undefined;
|
|
223
|
+
INTERNAL_SERVICE_NAME?: string | undefined;
|
|
224
|
+
INTERNAL_SERVICE_CREDENTIAL?: string | undefined;
|
|
225
|
+
INTERNAL_SERVICE_CREDENTIALS?: string | undefined;
|
|
226
|
+
RABBITMQ_URL?: string | undefined;
|
|
227
|
+
REDIS_URL?: string | undefined;
|
|
228
|
+
REDIS_PASSWORD?: string | undefined;
|
|
229
|
+
CACHE_KEY_PREFIX?: string | undefined;
|
|
230
|
+
}, {
|
|
231
|
+
PORT: number;
|
|
232
|
+
SERVICE_NAME: string;
|
|
233
|
+
GATEWAY_SIGNING_SECRET: string;
|
|
234
|
+
DB_NAME: string;
|
|
235
|
+
NODE_ENV?: "development" | "test" | "staging" | "production" | undefined;
|
|
236
|
+
APP_NAME?: string | undefined;
|
|
237
|
+
LOG_LEVEL?: "error" | "warn" | "info" | "http" | "debug" | undefined;
|
|
238
|
+
CORS_ORIGINS?: string | undefined;
|
|
239
|
+
INTERNAL_SERVICE_NAME?: string | undefined;
|
|
240
|
+
INTERNAL_SERVICE_CREDENTIAL?: string | undefined;
|
|
241
|
+
INTERNAL_SERVICE_CREDENTIALS?: string | undefined;
|
|
242
|
+
DB_HOST?: string | undefined;
|
|
243
|
+
DB_PORT?: number | undefined;
|
|
244
|
+
DB_USER?: string | undefined;
|
|
245
|
+
DB_PASSWORD?: string | undefined;
|
|
246
|
+
DB_POOL_MAX?: number | undefined;
|
|
247
|
+
RABBITMQ_URL?: string | undefined;
|
|
248
|
+
RABBITMQ_HOST?: string | undefined;
|
|
249
|
+
RABBITMQ_PORT?: number | undefined;
|
|
250
|
+
RABBITMQ_USER?: string | undefined;
|
|
251
|
+
RABBITMQ_PASSWORD?: string | undefined;
|
|
252
|
+
RABBITMQ_VHOST?: string | undefined;
|
|
253
|
+
QUEUE_PREFIX?: string | undefined;
|
|
254
|
+
RABBITMQ_ENABLED?: "true" | "false" | undefined;
|
|
255
|
+
REDIS_URL?: string | undefined;
|
|
256
|
+
REDIS_HOST?: string | undefined;
|
|
257
|
+
REDIS_PORT?: number | undefined;
|
|
258
|
+
REDIS_PASSWORD?: string | undefined;
|
|
259
|
+
REDIS_DB?: number | undefined;
|
|
260
|
+
CACHE_KEY_PREFIX?: string | undefined;
|
|
261
|
+
}>;
|
|
262
|
+
/** Variables that have a development default but must be set explicitly in staging and production. */
|
|
263
|
+
export declare const DEPLOYED_REQUIRED_ENV: readonly string[];
|
|
264
|
+
/**
|
|
265
|
+
* True for NODE_ENV values that must name their environments explicitly (staging, production).
|
|
266
|
+
*
|
|
267
|
+
* @param nodeEnv NODE_ENV value (default `process.env.NODE_ENV`).
|
|
268
|
+
* @returns Whether it is a deployed environment.
|
|
269
|
+
* @example isDeployedNodeEnv('production') // true
|
|
270
|
+
*/
|
|
271
|
+
export declare function isDeployedNodeEnv(nodeEnv?: string | undefined): boolean;
|
|
272
|
+
/** One problem with one variable. Holds the variable name and kind of problem only, never its value. */
|
|
273
|
+
export interface EnvProblem {
|
|
274
|
+
name: string;
|
|
275
|
+
problem: 'missing' | 'invalid';
|
|
276
|
+
}
|
|
277
|
+
type EnvSource = Record<string, string | undefined>;
|
|
278
|
+
/**
|
|
279
|
+
* Formats problems as `NAME: missing|invalid` lines (names only — values are never printed, because
|
|
280
|
+
* Zod's own messages can echo them).
|
|
281
|
+
*
|
|
282
|
+
* @param problems Problems from validation.
|
|
283
|
+
* @returns A multi-line message.
|
|
284
|
+
* @example formatEnvProblems([{ name: 'DB_NAME', problem: 'missing' }]) // 'Invalid environment configuration:\n DB_NAME: missing'
|
|
285
|
+
*/
|
|
286
|
+
export declare function formatEnvProblems(problems: EnvProblem[]): string;
|
|
287
|
+
/** Options for {@link parseEnv}. */
|
|
288
|
+
export interface ParseEnvOptions {
|
|
289
|
+
/** Read `./.env` first when `source` is `process.env` (default true). */
|
|
111
290
|
dotenv?: boolean;
|
|
112
|
-
})
|
|
113
|
-
|
|
291
|
+
/** Names that must be set when NODE_ENV is staging or production (default {@link DEPLOYED_REQUIRED_ENV}). */
|
|
292
|
+
deployedRequired?: readonly string[];
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Validates `source` against `schema` without merging the base or exiting. Use for partial configs
|
|
296
|
+
* (scripts, tests) and wherever the caller handles the error.
|
|
297
|
+
*
|
|
298
|
+
* @param schema Any Zod schema over the env object.
|
|
299
|
+
* @param source Values to validate (default process.env).
|
|
300
|
+
* @param options Dotenv and deployed-environment checks.
|
|
301
|
+
* @returns The parsed, typed config.
|
|
302
|
+
* @throws ConfigError listing every missing or invalid variable by name (never its value).
|
|
303
|
+
* @example const env = parseEnv(databaseEnv, { DB_NAME: 'app_test' });
|
|
304
|
+
*/
|
|
305
|
+
export declare function parseEnv<S extends z.ZodTypeAny>(schema: S, source?: EnvSource, options?: ParseEnvOptions): z.infer<S>;
|
|
306
|
+
/** Options for {@link loadEnv}: parse options plus source, base and injectable output/exit. */
|
|
307
|
+
export interface LoadEnvOptions extends ParseEnvOptions {
|
|
308
|
+
/** Values to validate (default process.env). */
|
|
309
|
+
source?: EnvSource;
|
|
310
|
+
/** Base schema merged under the service schema (default {@link baseEnv}). */
|
|
311
|
+
base?: z.AnyZodObject;
|
|
312
|
+
/** Where the problem list is written (default stderr). */
|
|
313
|
+
write?: (text: string) => void;
|
|
314
|
+
/** Called with exit code 1 on failure (default `process.exit`). */
|
|
315
|
+
exit?: (code: number) => never;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Service startup config: merges the base env schema with the service's own, validates, and on
|
|
319
|
+
* failure prints the missing/invalid variable **names** (never values) and exits non-zero.
|
|
320
|
+
*
|
|
321
|
+
* @param schema The service's own variables (default none).
|
|
322
|
+
* @param options Source, base override and injectable write/exit for tests.
|
|
323
|
+
* @returns The parsed, typed config (base + service variables).
|
|
324
|
+
* @example
|
|
325
|
+
* export const config = loadEnv(z.object({ UPSTREAM_INTERNAL_URL: z.string().url() }));
|
|
326
|
+
*/
|
|
327
|
+
export declare function loadEnv<S extends z.AnyZodObject = z.ZodObject<Record<string, never>>, B extends z.AnyZodObject = typeof baseEnv>(schema?: S, options?: LoadEnvOptions & {
|
|
328
|
+
base?: B;
|
|
329
|
+
}): z.infer<B> & z.infer<S>;
|
|
330
|
+
/**
|
|
331
|
+
* Comma-separated env value → trimmed, non-empty list.
|
|
332
|
+
*
|
|
333
|
+
* @param value Raw env value.
|
|
334
|
+
* @returns The list (empty when unset).
|
|
335
|
+
* @example listFromEnv(' a, b ,,c') // ['a', 'b', 'c']
|
|
336
|
+
*/
|
|
114
337
|
export declare const listFromEnv: (value: string | undefined) => string[];
|
|
338
|
+
export {};
|
|
115
339
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,7 +44,7 @@ export type DispatchValue = z.infer<typeof dispatchValueSchema>;
|
|
|
44
44
|
* Who receives a dispatch. `userId` is needed for per-user channels such as an in-app feed;
|
|
45
45
|
* addresses with no account behind them carry only `email`.
|
|
46
46
|
*
|
|
47
|
-
* @example { email: '
|
|
47
|
+
* @example { email: 'ada@example.com', name: 'Ada', userId: '01J…', timezone: 'Europe/Lisbon' }
|
|
48
48
|
*/
|
|
49
49
|
export declare const dispatchRecipientSchema: z.ZodObject<{
|
|
50
50
|
email: z.ZodString;
|
|
@@ -55,14 +55,14 @@ export declare const dispatchRecipientSchema: z.ZodObject<{
|
|
|
55
55
|
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
56
56
|
}, "strip", z.ZodTypeAny, {
|
|
57
57
|
email: string;
|
|
58
|
-
userId?: string | null | undefined;
|
|
59
58
|
name?: string | undefined;
|
|
59
|
+
userId?: string | null | undefined;
|
|
60
60
|
locale?: string | null | undefined;
|
|
61
61
|
timezone?: string | null | undefined;
|
|
62
62
|
}, {
|
|
63
63
|
email: string;
|
|
64
|
-
userId?: string | null | undefined;
|
|
65
64
|
name?: string | undefined;
|
|
65
|
+
userId?: string | null | undefined;
|
|
66
66
|
locale?: string | null | undefined;
|
|
67
67
|
timezone?: string | null | undefined;
|
|
68
68
|
}>;
|
|
@@ -116,14 +116,14 @@ export declare function createNotificationDispatchSchema<const C extends string,
|
|
|
116
116
|
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
117
117
|
}, "strip", z.ZodTypeAny, {
|
|
118
118
|
email: string;
|
|
119
|
-
userId?: string | null | undefined;
|
|
120
119
|
name?: string | undefined;
|
|
120
|
+
userId?: string | null | undefined;
|
|
121
121
|
locale?: string | null | undefined;
|
|
122
122
|
timezone?: string | null | undefined;
|
|
123
123
|
}, {
|
|
124
124
|
email: string;
|
|
125
|
-
userId?: string | null | undefined;
|
|
126
125
|
name?: string | undefined;
|
|
126
|
+
userId?: string | null | undefined;
|
|
127
127
|
locale?: string | null | undefined;
|
|
128
128
|
timezone?: string | null | undefined;
|
|
129
129
|
}>;
|
|
@@ -148,14 +148,14 @@ export declare function createNotificationDispatchSchema<const C extends string,
|
|
|
148
148
|
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
149
149
|
}, "strip", z.ZodTypeAny, {
|
|
150
150
|
email: string;
|
|
151
|
-
userId?: string | null | undefined;
|
|
152
151
|
name?: string | undefined;
|
|
152
|
+
userId?: string | null | undefined;
|
|
153
153
|
locale?: string | null | undefined;
|
|
154
154
|
timezone?: string | null | undefined;
|
|
155
155
|
}, {
|
|
156
156
|
email: string;
|
|
157
|
-
userId?: string | null | undefined;
|
|
158
157
|
name?: string | undefined;
|
|
158
|
+
userId?: string | null | undefined;
|
|
159
159
|
locale?: string | null | undefined;
|
|
160
160
|
timezone?: string | null | undefined;
|
|
161
161
|
}>;
|
|
@@ -180,14 +180,14 @@ export declare function createNotificationDispatchSchema<const C extends string,
|
|
|
180
180
|
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
181
181
|
}, "strip", z.ZodTypeAny, {
|
|
182
182
|
email: string;
|
|
183
|
-
userId?: string | null | undefined;
|
|
184
183
|
name?: string | undefined;
|
|
184
|
+
userId?: string | null | undefined;
|
|
185
185
|
locale?: string | null | undefined;
|
|
186
186
|
timezone?: string | null | undefined;
|
|
187
187
|
}, {
|
|
188
188
|
email: string;
|
|
189
|
-
userId?: string | null | undefined;
|
|
190
189
|
name?: string | undefined;
|
|
190
|
+
userId?: string | null | undefined;
|
|
191
191
|
locale?: string | null | undefined;
|
|
192
192
|
timezone?: string | null | undefined;
|
|
193
193
|
}>;
|
|
@@ -212,14 +212,14 @@ export declare function createNotificationDispatchSchema<const C extends string,
|
|
|
212
212
|
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
213
213
|
}, "strip", z.ZodTypeAny, {
|
|
214
214
|
email: string;
|
|
215
|
-
userId?: string | null | undefined;
|
|
216
215
|
name?: string | undefined;
|
|
216
|
+
userId?: string | null | undefined;
|
|
217
217
|
locale?: string | null | undefined;
|
|
218
218
|
timezone?: string | null | undefined;
|
|
219
219
|
}, {
|
|
220
220
|
email: string;
|
|
221
|
-
userId?: string | null | undefined;
|
|
222
221
|
name?: string | undefined;
|
|
222
|
+
userId?: string | null | undefined;
|
|
223
223
|
locale?: string | null | undefined;
|
|
224
224
|
timezone?: string | null | undefined;
|
|
225
225
|
}>;
|
|
@@ -244,14 +244,14 @@ export declare function createNotificationDispatchSchema<const C extends string,
|
|
|
244
244
|
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
245
245
|
}, "strip", z.ZodTypeAny, {
|
|
246
246
|
email: string;
|
|
247
|
-
userId?: string | null | undefined;
|
|
248
247
|
name?: string | undefined;
|
|
248
|
+
userId?: string | null | undefined;
|
|
249
249
|
locale?: string | null | undefined;
|
|
250
250
|
timezone?: string | null | undefined;
|
|
251
251
|
}, {
|
|
252
252
|
email: string;
|
|
253
|
-
userId?: string | null | undefined;
|
|
254
253
|
name?: string | undefined;
|
|
254
|
+
userId?: string | null | undefined;
|
|
255
255
|
locale?: string | null | undefined;
|
|
256
256
|
timezone?: string | null | undefined;
|
|
257
257
|
}>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
import { type MySql2Database } from 'drizzle-orm/mysql2';
|
|
3
|
+
import type mysql from 'mysql2/promise';
|
|
4
|
+
import type { databaseEnv } from '../config/index.js';
|
|
5
|
+
import type { z } from 'zod';
|
|
6
|
+
import { type MysqlConnectionOptions } from './pool.js';
|
|
7
|
+
/** The `DB_*` variables of `baseEnv` (see `databaseEnv` in the config module). */
|
|
8
|
+
export type DatabaseEnv = z.infer<typeof databaseEnv>;
|
|
9
|
+
/** A Drizzle database over a mysql2 pool. */
|
|
10
|
+
export type Database<TSchema extends Record<string, unknown> = Record<string, never>> = MySql2Database<TSchema>;
|
|
11
|
+
/** The transaction handle passed to `db.transaction(async (tx) => …)`. */
|
|
12
|
+
export type Tx<TSchema extends Record<string, unknown> = Record<string, never>> = Parameters<Parameters<Database<TSchema>['transaction']>[0]>[0];
|
|
13
|
+
/** What {@link createDb} returns. The service container owns it and closes it on shutdown. */
|
|
14
|
+
export interface DbHandle<TSchema extends Record<string, unknown>> {
|
|
15
|
+
db: Database<TSchema>;
|
|
16
|
+
/** Readiness probe (`SELECT 1`); rejects when the database is unreachable. */
|
|
17
|
+
ping(): Promise<void>;
|
|
18
|
+
/** Drains and closes the pool. */
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
/** Options for {@link createDb}. */
|
|
22
|
+
export interface CreateDbOptions<TSchema extends Record<string, unknown>> {
|
|
23
|
+
/** Validated env (`config` from `loadEnv`). */
|
|
24
|
+
env: DatabaseEnv;
|
|
25
|
+
/** The service's Drizzle schema (tables and relations). */
|
|
26
|
+
schema: TSchema;
|
|
27
|
+
/** Pre-built pool (tests). Default: a utf8mb4, UTC pool sized by `DB_POOL_MAX`. */
|
|
28
|
+
pool?: mysql.Pool;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates the service's Drizzle database. There is no module-level singleton: call it once in
|
|
32
|
+
* `container.ts` and inject `db` into repositories.
|
|
33
|
+
*
|
|
34
|
+
* @example const { db, ping, close } = createDb({ env: config, schema });
|
|
35
|
+
*/
|
|
36
|
+
export declare function createDb<TSchema extends Record<string, unknown>>(options: CreateDbOptions<TSchema>): DbHandle<TSchema>;
|
|
37
|
+
/**
|
|
38
|
+
* Knex config for a service's `knexfile.js`. Knex runs **migrations and seeds only** (`.cjs` files
|
|
39
|
+
* in `./migrations` and `./seeds`); repositories use Drizzle.
|
|
40
|
+
*
|
|
41
|
+
* @example module.exports = knexConfig(config);
|
|
42
|
+
*/
|
|
43
|
+
export declare function knexConfig(env: DatabaseEnv): Knex.Config;
|
|
44
|
+
/** Maps the validated `DB_*` env to connection options. */
|
|
45
|
+
export declare function connectionOptions(env: DatabaseEnv): MysqlConnectionOptions;
|
|
46
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/database/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAgD,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEtG,kFAAkF;AAClF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,6CAA6C;AAC7C,MAAM,MAAM,QAAQ,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;AAEhH,0EAA0E;AAC1E,MAAM,MAAM,EAAE,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjJ,8FAA8F;AAC9F,MAAM,WAAW,QAAQ,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/D,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACtB,8EAA8E;IAC9E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,kCAAkC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACtE,+CAA+C;IAC/C,GAAG,EAAE,WAAW,CAAC;IACjB,2DAA2D;IAC3D,MAAM,EAAE,OAAO,CAAC;IAChB,mFAAmF;IACnF,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAStH;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC,MAAM,CAExD;AAED,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,sBAAsB,CAE1E"}
|
|
@@ -1,25 +1,12 @@
|
|
|
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
1
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
2
|
+
* `@heavybit/shared-lib/database`: Drizzle data access for services. Repositories use Drizzle
|
|
3
|
+
* through {@link ScopedRepository} and the scopes in `scopes.ts`; raw scoped queries and Knex in
|
|
4
|
+
* `src/` are forbidden. Knex is for migrations and seeds only (`knexConfig`, `@heavybit/shared-lib/knex`).
|
|
14
5
|
*/
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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;
|
|
6
|
+
export * from './pool.js';
|
|
7
|
+
export * from './db.js';
|
|
8
|
+
export * from './scopes.js';
|
|
9
|
+
export * from './scoped-repository.js';
|
|
10
|
+
export * from './pagination.js';
|
|
11
|
+
export * from './tables.js';
|
|
25
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/database/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/database/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { CursorPage } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Cursor (keyset) pagination (D6). Clients send `?cursor=&limit=`; the cursor is an opaque
|
|
5
|
+
* base64url token of `{ sortKey, id }` (the last row's sort value plus an id tie-breaker).
|
|
6
|
+
* Dependency-light: usable from controllers without the database subpath.
|
|
7
|
+
*/
|
|
8
|
+
/** Largest page size a client may ask for. */
|
|
9
|
+
export declare const MAX_PAGE_LIMIT = 100;
|
|
10
|
+
/** Page size when the client sends none. */
|
|
11
|
+
export declare const DEFAULT_PAGE_LIMIT = 20;
|
|
12
|
+
/** `{ cursor?, limit }` query schema: limit 1–100, default 20; unknown keys are stripped. */
|
|
13
|
+
export declare const cursorQuerySchema: z.ZodObject<{
|
|
14
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
15
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
limit: number;
|
|
18
|
+
cursor?: string | undefined;
|
|
19
|
+
}, {
|
|
20
|
+
limit?: number | undefined;
|
|
21
|
+
cursor?: string | undefined;
|
|
22
|
+
}>;
|
|
23
|
+
/** Parsed cursor query. */
|
|
24
|
+
export type CursorQuery = z.infer<typeof cursorQuerySchema>;
|
|
25
|
+
/** Sort values a cursor can carry. Dates are carried as ISO strings. */
|
|
26
|
+
export type CursorSortKey = string | number | null;
|
|
27
|
+
/** The decoded content of a cursor. */
|
|
28
|
+
export interface DecodedCursor {
|
|
29
|
+
sortKey: CursorSortKey;
|
|
30
|
+
id: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Validates `{ cursor, limit }` from a query string.
|
|
34
|
+
*
|
|
35
|
+
* @throws ValidationError (422) with field errors when invalid.
|
|
36
|
+
* @example const { cursor, limit } = parseCursorQuery(req.query);
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseCursorQuery(input: {
|
|
39
|
+
cursor?: unknown;
|
|
40
|
+
limit?: unknown;
|
|
41
|
+
} | undefined): CursorQuery;
|
|
42
|
+
/**
|
|
43
|
+
* Encodes a cursor. Date sort keys become ISO strings.
|
|
44
|
+
*
|
|
45
|
+
* @example encodeCursor({ sortKey: row.createdAt, id: row.id })
|
|
46
|
+
*/
|
|
47
|
+
export declare function encodeCursor(cursor: {
|
|
48
|
+
sortKey: CursorSortKey | Date;
|
|
49
|
+
id: string;
|
|
50
|
+
}): string;
|
|
51
|
+
/**
|
|
52
|
+
* Decodes a cursor produced by {@link encodeCursor}.
|
|
53
|
+
*
|
|
54
|
+
* @throws ValidationError (422, field `cursor`) for anything malformed or tampered with.
|
|
55
|
+
*/
|
|
56
|
+
export declare function decodeCursor(token: string): DecodedCursor;
|
|
57
|
+
/**
|
|
58
|
+
* Builds a page from `limit + 1` fetched rows: the extra row only signals that more exist.
|
|
59
|
+
*
|
|
60
|
+
* @param rows Rows fetched with `limit + 1`.
|
|
61
|
+
* @param limit The page size.
|
|
62
|
+
* @param cursorOf Extracts `{ sortKey, id }` from a row for the next cursor.
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildCursorPage<T>(rows: T[], limit: number, cursorOf: (row: T) => {
|
|
65
|
+
sortKey: CursorSortKey | Date;
|
|
66
|
+
id: string;
|
|
67
|
+
}): CursorPage<T>;
|
|
68
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/database/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD;;;;GAIG;AAEH,8CAA8C;AAC9C,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAGrC,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB;;;;;;;;;EAG5B,CAAC;AAEH,2BAA2B;AAC3B,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAEnD,uCAAuC;AACvC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,GAAG,WAAW,CAItG;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAG1F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAczD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK;IAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAK/I"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
import mysql from 'mysql2/promise';
|
|
3
|
+
/** Connection settings for {@link createMysqlPool} and {@link createKnexConfig}. */
|
|
4
|
+
export interface MysqlConnectionOptions {
|
|
5
|
+
/** Server host name. */
|
|
6
|
+
host: string;
|
|
7
|
+
/** Server port. */
|
|
8
|
+
port: number;
|
|
9
|
+
/** Database user. */
|
|
10
|
+
user: string;
|
|
11
|
+
/** Database password (never logged). */
|
|
12
|
+
password: string;
|
|
13
|
+
/** The service's own database. */
|
|
14
|
+
database: string;
|
|
15
|
+
/** Maximum pool connections (default 10). */
|
|
16
|
+
poolMax?: number;
|
|
17
|
+
}
|
|
18
|
+
/** Knex-only options for {@link createKnexConfig}. */
|
|
19
|
+
export interface KnexConfigOptions extends MysqlConnectionOptions {
|
|
20
|
+
/** Migrations folder (default `./migrations`). */
|
|
21
|
+
migrationsDir?: string;
|
|
22
|
+
/** Seeds folder (default `./seeds`). */
|
|
23
|
+
seedsDir?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* mysql2 pool for Drizzle. Sessions run in UTC and utf8mb4 so timestamps and emoji round-trip
|
|
27
|
+
* unchanged regardless of server defaults.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createMysqlPool(options: MysqlConnectionOptions): mysql.Pool;
|
|
30
|
+
/**
|
|
31
|
+
* Knex config for migrations and seeds: mysql2, utf8mb4, UTC, `.cjs` files only. Services call it
|
|
32
|
+
* through `knexConfig(env)` in their `knexfile.js`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createKnexConfig(options: KnexConfigOptions): Knex.Config;
|
|
35
|
+
/** Readiness probe helper. */
|
|
36
|
+
export declare function pingMysql(pool: mysql.Pool): Promise<void>;
|
|
37
|
+
/** Escapes `%`, `_` and `\` for use inside a LIKE pattern. */
|
|
38
|
+
export declare function escapeLike(value: string): string;
|
|
39
|
+
//# sourceMappingURL=pool.d.ts.map
|