@heavybit/shared-lib 1.3.2 → 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 +261 -0
- 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/errors.js +44 -5
- package/dist/cjs/common/errors.js.map +1 -1
- 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 +63 -11
- package/dist/cjs/common/phone.js.map +1 -1
- package/dist/cjs/common/response.js +78 -5
- package/dist/cjs/common/response.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 +140 -20
- package/dist/cjs/config/index.js.map +1 -1
- package/dist/cjs/context/index.js +49 -0
- package/dist/cjs/context/index.js.map +1 -0
- package/dist/cjs/contracts/index.js +0 -2
- package/dist/cjs/contracts/index.js.map +1 -1
- package/dist/cjs/contracts/notification-dispatch.js +87 -63
- package/dist/cjs/contracts/notification-dispatch.js.map +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 +88 -41
- package/dist/cjs/express/auth.js.map +1 -1
- package/dist/cjs/express/index.js +3 -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/middleware.js +154 -34
- package/dist/cjs/express/middleware.js.map +1 -1
- package/dist/cjs/express/respond.js +47 -0
- package/dist/cjs/express/respond.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 +7 -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/index.js +76 -40
- package/dist/cjs/logging/index.js.map +1 -1
- package/dist/cjs/logging/redact.js +112 -0
- package/dist/cjs/logging/redact.js.map +1 -0
- 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 +3 -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 +36 -44
- package/dist/cjs/messaging/staff-notifier.js.map +1 -1
- package/dist/cjs/messaging/staff-recipients.js +57 -0
- package/dist/cjs/messaging/staff-recipients.js.map +1 -0
- 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/cjs/validation/index.js +27 -3
- package/dist/cjs/validation/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/errors.js +42 -4
- package/dist/esm/common/errors.js.map +1 -1
- 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 +63 -11
- package/dist/esm/common/phone.js.map +1 -1
- package/dist/esm/common/response.js +75 -5
- package/dist/esm/common/response.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 +136 -19
- package/dist/esm/config/index.js.map +1 -1
- package/dist/esm/context/index.js +44 -0
- package/dist/esm/context/index.js.map +1 -0
- package/dist/esm/contracts/index.js +0 -2
- package/dist/esm/contracts/index.js.map +1 -1
- package/dist/esm/contracts/notification-dispatch.js +85 -62
- package/dist/esm/contracts/notification-dispatch.js.map +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 +87 -40
- package/dist/esm/express/auth.js.map +1 -1
- package/dist/esm/express/index.js +3 -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/middleware.js +146 -27
- package/dist/esm/express/middleware.js.map +1 -1
- package/dist/esm/express/respond.js +42 -0
- package/dist/esm/express/respond.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 +7 -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/index.js +68 -39
- package/dist/esm/logging/index.js.map +1 -1
- package/dist/esm/logging/redact.js +106 -0
- package/dist/esm/logging/redact.js.map +1 -0
- 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 +3 -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 +36 -43
- package/dist/esm/messaging/staff-notifier.js.map +1 -1
- package/dist/esm/messaging/staff-recipients.js +53 -0
- package/dist/esm/messaging/staff-recipients.js.map +1 -0
- 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/esm/validation/index.js +27 -2
- package/dist/esm/validation/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/alerting/index.d.ts +1 -1
- package/dist/types/alerting/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/errors.d.ts +48 -7
- package/dist/types/common/errors.d.ts.map +1 -1
- 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 +45 -6
- package/dist/types/common/phone.d.ts.map +1 -1
- package/dist/types/common/response.d.ts +66 -5
- package/dist/types/common/response.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 +252 -28
- package/dist/types/config/index.d.ts.map +1 -1
- package/dist/types/context/index.d.ts +39 -0
- package/dist/types/context/index.d.ts.map +1 -0
- package/dist/types/contracts/index.d.ts +0 -2
- package/dist/types/contracts/index.d.ts.map +1 -1
- package/dist/types/contracts/notification-dispatch.d.ts +204 -86
- package/dist/types/contracts/notification-dispatch.d.ts.map +1 -1
- 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 +63 -11
- package/dist/types/express/auth.d.ts.map +1 -1
- package/dist/types/express/index.d.ts +3 -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/middleware.d.ts +86 -7
- package/dist/types/express/middleware.d.ts.map +1 -1
- package/dist/types/express/respond.d.ts +41 -0
- package/dist/types/express/respond.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 +7 -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/index.d.ts +30 -4
- package/dist/types/logging/index.d.ts.map +1 -1
- package/dist/types/logging/redact.d.ts +54 -0
- package/dist/types/logging/redact.d.ts.map +1 -0
- 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 +8 -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 +69 -38
- package/dist/types/messaging/staff-notifier.d.ts.map +1 -1
- package/dist/types/messaging/staff-recipients.d.ts +50 -0
- package/dist/types/messaging/staff-recipients.d.ts.map +1 -0
- 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 +62 -15
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/validation/index.d.ts +33 -2
- package/dist/types/validation/index.d.ts.map +1 -1
- package/package.json +3 -1
- package/dist/cjs/contracts/editorial-draft.js +0 -120
- package/dist/cjs/contracts/editorial-draft.js.map +0 -1
- package/dist/cjs/contracts/upload-import.js +0 -54
- package/dist/cjs/contracts/upload-import.js.map +0 -1
- package/dist/esm/contracts/editorial-draft.js +0 -117
- package/dist/esm/contracts/editorial-draft.js.map +0 -1
- package/dist/esm/contracts/upload-import.js +0 -51
- package/dist/esm/contracts/upload-import.js.map +0 -1
- package/dist/types/contracts/editorial-draft.d.ts +0 -610
- package/dist/types/contracts/editorial-draft.d.ts.map +0 -1
- package/dist/types/contracts/upload-import.d.ts +0 -96
- package/dist/types/contracts/upload-import.d.ts.map +0 -1
package/dist/esm/knex/index.js
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
|
+
import { DEFAULT_OUTBOX_TABLE } from '../database/table-names.js';
|
|
2
|
+
import { actorColumns, timestamps, ulidColumn, ulidPrimary } from './columns.js';
|
|
3
|
+
import { outboxColumns } from './migration-helpers.js';
|
|
4
|
+
export * from './columns.js';
|
|
5
|
+
export * from './migration-helpers.js';
|
|
1
6
|
/**
|
|
2
7
|
* Migration helpers (usable from CommonJS `.cjs` migrations via `require('@heavybit/shared-lib/knex')`).
|
|
3
8
|
* They keep ID, timestamp and audit column definitions identical across services.
|
|
4
9
|
*/
|
|
5
|
-
/** `id CHAR(26)` primary key for ULIDs. */
|
|
6
|
-
export function ulidPrimary(table, name = 'id') {
|
|
7
|
-
table.specificType(name, 'char(26)').notNullable().primary();
|
|
8
|
-
}
|
|
9
|
-
/** `CHAR(26)` column referencing another ULID (FK constraints only within the same database). */
|
|
10
|
-
export function ulidColumn(table, name) {
|
|
11
|
-
return table.specificType(name, 'char(26)');
|
|
12
|
-
}
|
|
13
|
-
/** `created_at` / `updated_at` as `DATETIME(3)` in UTC, maintained by MySQL. */
|
|
14
|
-
export function timestamps(table, knex) {
|
|
15
|
-
table.specificType('created_at', 'datetime(3)').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP(3)'));
|
|
16
|
-
table.specificType('updated_at', 'datetime(3)').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)'));
|
|
17
|
-
}
|
|
18
|
-
/** `created_by` / `updated_by` actor columns (null for system operations). */
|
|
19
|
-
export function actorColumns(table) {
|
|
20
|
-
ulidColumn(table, 'created_by').nullable();
|
|
21
|
-
ulidColumn(table, 'updated_by').nullable();
|
|
22
|
-
}
|
|
23
|
-
/** Nullable `DATETIME(3)` column. */
|
|
24
|
-
export function datetime(table, name) {
|
|
25
|
-
return table.specificType(name, 'datetime(3)');
|
|
26
|
-
}
|
|
27
10
|
/**
|
|
28
11
|
* Creates `<parent>_audits`: every parent column (defined again by `columns`) plus `parent_id`
|
|
29
12
|
* and `action`. Audit rows are append-only history, so no unique constraints are copied.
|
|
@@ -42,20 +25,11 @@ export async function createAuditTable(knex, parentTable, columns) {
|
|
|
42
25
|
table.index(['parent_id', 'created_at']);
|
|
43
26
|
});
|
|
44
27
|
}
|
|
45
|
-
/** Transactional outbox table used by `OutboxRelay
|
|
46
|
-
export async function createOutboxTable(knex, name =
|
|
28
|
+
/** Transactional outbox table used by `OutboxRelay` (columns from {@link outboxColumns}). */
|
|
29
|
+
export async function createOutboxTable(knex, name = DEFAULT_OUTBOX_TABLE) {
|
|
47
30
|
if (await knex.schema.hasTable(name))
|
|
48
31
|
return;
|
|
49
|
-
await knex.schema.createTable(name, (table) =>
|
|
50
|
-
ulidPrimary(table);
|
|
51
|
-
table.string('routing_key', 191).notNullable();
|
|
52
|
-
table.json('payload').notNullable();
|
|
53
|
-
table.integer('attempts').unsigned().notNullable().defaultTo(0);
|
|
54
|
-
table.string('last_error', 500).nullable();
|
|
55
|
-
table.specificType('created_at', 'datetime(3)').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP(3)'));
|
|
56
|
-
datetime(table, 'published_at').nullable();
|
|
57
|
-
table.index(['published_at', 'id']);
|
|
58
|
-
});
|
|
32
|
+
await knex.schema.createTable(name, (table) => outboxColumns(table, knex));
|
|
59
33
|
}
|
|
60
34
|
/** Standard table options: InnoDB, utf8mb4. Call inside `createTable`. */
|
|
61
35
|
export function utf8mb4(table) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/knex/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/knex/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAY,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AAEvC;;;GAGG;AAEH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAU,EAAE,WAAmB,EAAE,OAAiD;IACvH,MAAM,IAAI,GAAG,GAAG,WAAW,SAAS,CAAC;IACrC,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO;IAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;QAC5C,WAAW,CAAC,KAAK,CAAC,CAAC;QACnB,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;QACrD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAClE,OAAO,CAAC,KAAK,CAAC,CAAC;QACf,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACxB,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,6FAA6F;AAC7F,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAU,EAAE,IAAI,GAAG,oBAAoB;IAC7E,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO;IAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,OAAO,CAAC,KAA8B;IACpD,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvB,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzB,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { OUTBOX_EXCHANGES, SCHEDULER_RUN_STATUSES } from '../database/table-names.js';
|
|
2
|
+
import { createdAtColumn, datetime, ulidPrimary } from './columns.js';
|
|
3
|
+
/**
|
|
4
|
+
* Outbox columns: id, routing_key, exchange, payload, correlation_id, attempts, last_error, created_at,
|
|
5
|
+
* published_at (+ relay index).
|
|
6
|
+
*/
|
|
7
|
+
export function outboxColumns(t, knex) {
|
|
8
|
+
ulidPrimary(t);
|
|
9
|
+
t.string('routing_key', 191).notNullable();
|
|
10
|
+
t.enu('exchange', [...OUTBOX_EXCHANGES]).notNullable().defaultTo('events');
|
|
11
|
+
t.json('payload').notNullable();
|
|
12
|
+
t.string('correlation_id', 64).nullable();
|
|
13
|
+
t.integer('attempts').unsigned().notNullable().defaultTo(0);
|
|
14
|
+
t.string('last_error', 500).nullable();
|
|
15
|
+
createdAtColumn(t, knex, 'created_at');
|
|
16
|
+
datetime(t, 'published_at').nullable();
|
|
17
|
+
t.index(['published_at', 'id']);
|
|
18
|
+
}
|
|
19
|
+
/** Consumer idempotency columns: id, consumer, event_id (unique together), processed_at. */
|
|
20
|
+
export function processedEventsColumns(t, knex) {
|
|
21
|
+
ulidPrimary(t);
|
|
22
|
+
t.string('consumer', 191).notNullable();
|
|
23
|
+
t.string('event_id', 64).notNullable();
|
|
24
|
+
createdAtColumn(t, knex, 'processed_at');
|
|
25
|
+
t.unique(['consumer', 'event_id']);
|
|
26
|
+
t.index(['processed_at']);
|
|
27
|
+
}
|
|
28
|
+
/** Scheduler run columns: id, job, run_key (unique together), status, error, started_at, finished_at. */
|
|
29
|
+
export function schedulerRunsColumns(t, knex) {
|
|
30
|
+
ulidPrimary(t);
|
|
31
|
+
t.string('job', 191).notNullable();
|
|
32
|
+
t.string('run_key', 191).notNullable();
|
|
33
|
+
t.enu('status', [...SCHEDULER_RUN_STATUSES]).notNullable().defaultTo('running');
|
|
34
|
+
t.string('error', 500).nullable();
|
|
35
|
+
createdAtColumn(t, knex, 'started_at');
|
|
36
|
+
datetime(t, 'finished_at').nullable();
|
|
37
|
+
t.unique(['job', 'run_key']);
|
|
38
|
+
t.index(['job', 'started_at']);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Index that always leads with the scope column (TEN-4); `columns` follow in order, duplicates of
|
|
42
|
+
* the scope column are dropped.
|
|
43
|
+
*
|
|
44
|
+
* @example scopedIndex(t, 'workspace_id', ['status', 'created_at'])
|
|
45
|
+
*/
|
|
46
|
+
export function scopedIndex(t, scopeColumn, columns = [], indexName) {
|
|
47
|
+
if (!scopeColumn)
|
|
48
|
+
throw new Error('scopedIndex needs a scope column');
|
|
49
|
+
t.index([scopeColumn, ...columns.filter((c) => c !== scopeColumn)], indexName);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=migration-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-helpers.js","sourceRoot":"","sources":["../../../src/knex/migration-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,54 +1,78 @@
|
|
|
1
1
|
import winston from 'winston';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
];
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (
|
|
14
|
-
return
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
2
|
+
import { getRequestContext } from '../context/index.js';
|
|
3
|
+
import { createKeyClassifier, maskPhonesInText, redactValue } from './redact.js';
|
|
4
|
+
export { DEFAULT_ALLOW_KEYS, DEFAULT_REDACT_KEYS, REDACTED, createKeyClassifier, maskPhoneForLog, maskPhonesInText, redactValue } from './redact.js';
|
|
5
|
+
const { combine, timestamp, errors, colorize, printf, splat } = winston.format;
|
|
6
|
+
/** Winston bookkeeping keys that never appear as metadata. */
|
|
7
|
+
const RESERVED_KEYS = new Set(['level', 'message', 'timestamp', 'splat']);
|
|
8
|
+
/** Ids the library itself puts on a line; never redacted or phone-masked. */
|
|
9
|
+
const CONTEXT_KEYS = new Set(['service', 'correlationId', 'userId', 'scopes']);
|
|
10
|
+
/** Adds the request context (correlation id, user id, scopes, service) unless the line already has it. */
|
|
11
|
+
const withContext = winston.format((info) => {
|
|
12
|
+
const ctx = getRequestContext();
|
|
13
|
+
if (!ctx)
|
|
14
|
+
return info;
|
|
15
|
+
const line = info;
|
|
16
|
+
line.correlationId ??= ctx.correlationId;
|
|
17
|
+
if (ctx.userId !== undefined)
|
|
18
|
+
line.userId ??= ctx.userId;
|
|
19
|
+
if (ctx.scopes && Object.keys(ctx.scopes).length > 0)
|
|
20
|
+
line.scopes ??= ctx.scopes;
|
|
21
|
+
if (ctx.service !== undefined)
|
|
22
|
+
line.service ??= ctx.service;
|
|
23
|
+
return info;
|
|
24
|
+
});
|
|
25
|
+
/** Redacts secrets and masks phones in the message and every metadata value. */
|
|
26
|
+
const redact = (classifier) => winston.format((info) => {
|
|
27
|
+
const line = info;
|
|
28
|
+
if (typeof line.message === 'string')
|
|
29
|
+
line.message = maskPhonesInText(line.message);
|
|
30
|
+
const meta = Object.fromEntries(Object.entries(line).filter(([key]) => !RESERVED_KEYS.has(key) && !CONTEXT_KEYS.has(key)));
|
|
31
|
+
Object.assign(line, redactValue(meta, classifier));
|
|
28
32
|
return info;
|
|
29
|
-
})
|
|
30
|
-
|
|
33
|
+
});
|
|
34
|
+
/** One JSON object per line: `{ level, time, msg, service, correlationId, userId, scopes, ...meta }`. */
|
|
35
|
+
const jsonLine = printf((info) => {
|
|
36
|
+
const { level, message, timestamp: time, service, correlationId, userId, scopes, ...meta } = info;
|
|
37
|
+
return JSON.stringify({ level, time, msg: message, service, correlationId, userId, scopes, ...meta });
|
|
38
|
+
});
|
|
39
|
+
const prettyLine = printf((info) => {
|
|
31
40
|
const { level, message, timestamp: ts, service, stack, ...rest } = info;
|
|
32
|
-
const
|
|
33
|
-
const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';
|
|
41
|
+
const metaStr = Object.keys(rest).length ? ` ${JSON.stringify(rest)}` : '';
|
|
34
42
|
return `${String(ts ?? '')} ${String(level)}: ${service ? `[${String(service)}] ` : ''}${String(message)}${metaStr}${stack ? `\n${String(stack)}` : ''}`;
|
|
35
43
|
});
|
|
36
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Structured logger. Every line carries `service` and, inside a request or {@link runWithContext}, the
|
|
46
|
+
* context's `correlationId`, `userId` and `scopes`. Secrets are redacted by key word (see
|
|
47
|
+
* {@link DEFAULT_REDACT_KEYS}) and phone numbers are masked to their last 4 digits, in the message and
|
|
48
|
+
* at any depth of the metadata. Writes to stdout (JSON in production, pretty otherwise; silent under
|
|
49
|
+
* `NODE_ENV=test` unless `LOG_IN_TESTS` is set) plus an optional file and stream.
|
|
50
|
+
*
|
|
51
|
+
* @param service Service name on every line.
|
|
52
|
+
* @param options Level, format, extra redact/allow keys, file path, stream.
|
|
53
|
+
* @returns A winston logger that satisfies {@link Logger}.
|
|
54
|
+
* @example const logger = createLogger('api', { filePath: 'logs/api.log' });
|
|
55
|
+
*/
|
|
37
56
|
export function createLogger(service, options = {}) {
|
|
38
57
|
const isProduction = process.env.NODE_ENV === 'production';
|
|
39
58
|
const level = options.level ?? process.env.LOG_LEVEL ?? (isProduction ? 'info' : 'debug');
|
|
40
59
|
const format = options.format ?? process.env.LOG_FORMAT ?? (isProduction ? 'json' : 'pretty');
|
|
41
|
-
const
|
|
60
|
+
const classifier = createKeyClassifier(options.redactKeys, options.allowKeys);
|
|
61
|
+
const transports = [
|
|
62
|
+
new winston.transports.Console({
|
|
63
|
+
silent: process.env.NODE_ENV === 'test' && !process.env.LOG_IN_TESTS,
|
|
64
|
+
format: format === 'json' ? jsonLine : combine(colorize({ level: true }), prettyLine),
|
|
65
|
+
}),
|
|
66
|
+
];
|
|
67
|
+
if (options.filePath)
|
|
68
|
+
transports.push(new winston.transports.File({ filename: options.filePath, format: jsonLine }));
|
|
69
|
+
if (options.stream)
|
|
70
|
+
transports.push(new winston.transports.Stream({ stream: options.stream, format: jsonLine }));
|
|
42
71
|
return winston.createLogger({
|
|
43
72
|
level,
|
|
44
73
|
defaultMeta: { service },
|
|
45
|
-
format: combine(errors({ stack: true }), splat(), redact(
|
|
46
|
-
transports
|
|
47
|
-
new winston.transports.Console({
|
|
48
|
-
silent: process.env.NODE_ENV === 'test' && !process.env.LOG_IN_TESTS,
|
|
49
|
-
format: format === 'json' ? json() : combine(colorize({ level: true }), devFormat),
|
|
50
|
-
}),
|
|
51
|
-
],
|
|
74
|
+
format: combine(errors({ stack: true }), splat(), withContext(), redact(classifier)(), timestamp()),
|
|
75
|
+
transports,
|
|
52
76
|
});
|
|
53
77
|
}
|
|
54
78
|
/** Logger that discards everything — handy default for libraries and tests. */
|
|
@@ -58,6 +82,11 @@ export const silentLogger = { debug: () => { }, info: () => { }, warn: () => { }
|
|
|
58
82
|
* meta wins on a key clash. `undefined` context values are dropped so lines never carry empty keys.
|
|
59
83
|
* Works over any {@link Logger} (winston, a test spy, or another child), so handlers can create one
|
|
60
84
|
* per message and pass it down.
|
|
85
|
+
*
|
|
86
|
+
* @param logger The logger to write through.
|
|
87
|
+
* @param context Values added to every line.
|
|
88
|
+
* @returns A {@link Logger}.
|
|
89
|
+
* @example const log = childLogger(logger, { jobId });
|
|
61
90
|
*/
|
|
62
91
|
export function childLogger(logger, context) {
|
|
63
92
|
const base = Object.fromEntries(Object.entries(context).filter(([, v]) => v !== undefined));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/logging/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/logging/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret redaction and phone masking for log lines. Matching is by key *word*, not substring: a key is
|
|
3
|
+
* split on camelCase and separators (`refresh_token` → `refresh`, `token`; `OTPCode` → `otp`, `code`),
|
|
4
|
+
* and it is sensitive when a word (or two adjacent words joined, e.g. `api`+`key`) equals a listed term
|
|
5
|
+
* or its plural. So `accessToken` and `Set-Cookie` are redacted while `pinned` or `spinner` are not.
|
|
6
|
+
*/
|
|
7
|
+
import { maskPhone } from '../common/phone.js';
|
|
8
|
+
/** Words whose values are always replaced with `[REDACTED]`. Apps add their own via `redactKeys`. */
|
|
9
|
+
export const DEFAULT_REDACT_KEYS = [
|
|
10
|
+
'password', 'pass', 'passphrase', 'token', 'secret', 'code', 'otp', 'authorization', 'cookie', 'credential',
|
|
11
|
+
'pin', 'apikey', 'jwt', 'signature',
|
|
12
|
+
];
|
|
13
|
+
/** Keys that are never redacted although they contain a listed word (error, status and reference codes). */
|
|
14
|
+
export const DEFAULT_ALLOW_KEYS = ['errorCode', 'statusCode', 'countryCode', 'currencyCode', 'postalCode', 'zipCode'];
|
|
15
|
+
/** Words that mark a value as a phone number, masked to its last 4 digits. */
|
|
16
|
+
const PHONE_KEY_WORDS = new Set(['phone', 'msisdn', 'mobile', 'tel']);
|
|
17
|
+
/** 9–15 digits, optionally with a leading `+`, not part of a longer word or number. */
|
|
18
|
+
const PHONE_IN_TEXT = /(?<![\w+]|\d\.)\+?\d{9,15}(?!\w|\.\d)/g;
|
|
19
|
+
/** The marker that replaces a secret value. */
|
|
20
|
+
export const REDACTED = '[REDACTED]';
|
|
21
|
+
const MAX_DEPTH = 8;
|
|
22
|
+
/**
|
|
23
|
+
* Masks every digit except the last four; the same rule as `maskPhone` in common (one rule for logs and UI).
|
|
24
|
+
*
|
|
25
|
+
* @param value A phone number in any format.
|
|
26
|
+
* @returns e.g. `********5678`; values with fewer than 5 digits are fully masked.
|
|
27
|
+
* @example maskPhoneForLog('15551234567') // '*******4567'
|
|
28
|
+
*/
|
|
29
|
+
export const maskPhoneForLog = maskPhone;
|
|
30
|
+
/**
|
|
31
|
+
* Masks phone-number-looking runs inside free text.
|
|
32
|
+
*
|
|
33
|
+
* @param text Any string (a log message or value).
|
|
34
|
+
* @returns The text with each 9–15 digit run masked to its last 4 digits.
|
|
35
|
+
* @example maskPhonesInText('OTP sent to 15551234567') // 'OTP sent to *******4567'
|
|
36
|
+
*/
|
|
37
|
+
export function maskPhonesInText(text) {
|
|
38
|
+
return text.replace(PHONE_IN_TEXT, maskPhoneForLog);
|
|
39
|
+
}
|
|
40
|
+
function keyWords(key) {
|
|
41
|
+
return key
|
|
42
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
43
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')
|
|
44
|
+
.toLowerCase()
|
|
45
|
+
.split(/[^a-z0-9]+/)
|
|
46
|
+
.filter(Boolean);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Builds a key classifier from the default terms plus app-specific ones.
|
|
50
|
+
*
|
|
51
|
+
* @param extraKeys Extra words (matched like the defaults, case-insensitive).
|
|
52
|
+
* @param allowKeys Exact keys never treated as secret (defaults to {@link DEFAULT_ALLOW_KEYS}).
|
|
53
|
+
* @returns The classifier.
|
|
54
|
+
* @example createKeyClassifier(['nationalId']).isSecret('nationalId') // true
|
|
55
|
+
*/
|
|
56
|
+
export function createKeyClassifier(extraKeys = [], allowKeys = DEFAULT_ALLOW_KEYS) {
|
|
57
|
+
const terms = new Set([...DEFAULT_REDACT_KEYS, ...extraKeys].map((k) => keyWords(k).join('')));
|
|
58
|
+
const allow = new Set(allowKeys);
|
|
59
|
+
const matches = (word) => terms.has(word) || (word.endsWith('s') && terms.has(word.slice(0, -1)));
|
|
60
|
+
return {
|
|
61
|
+
isSecret(key) {
|
|
62
|
+
if (allow.has(key))
|
|
63
|
+
return false;
|
|
64
|
+
if (key.endsWith('Enc') || key.endsWith('_enc'))
|
|
65
|
+
return true;
|
|
66
|
+
const words = keyWords(key);
|
|
67
|
+
if (matches(words.join('')))
|
|
68
|
+
return true;
|
|
69
|
+
return words.some((word, i) => matches(word) || (i > 0 && matches(`${words[i - 1]}${word}`)));
|
|
70
|
+
},
|
|
71
|
+
isPhone(key) {
|
|
72
|
+
return keyWords(key).some((word) => PHONE_KEY_WORDS.has(word));
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Returns a copy of `value` with secrets replaced by `[REDACTED]` and phone numbers masked, at any depth
|
|
78
|
+
* (up to 8 levels; deeper values are dropped as `[TRUNCATED]`). Errors are kept as-is.
|
|
79
|
+
*
|
|
80
|
+
* @param value Log metadata (object, array or scalar).
|
|
81
|
+
* @param classifier From {@link createKeyClassifier}.
|
|
82
|
+
* @param depth Internal recursion depth; callers omit it.
|
|
83
|
+
* @returns The redacted copy; the input is not modified.
|
|
84
|
+
* @example redactValue({ user: { otp: '1234', phone: '15551234567' } }, createKeyClassifier())
|
|
85
|
+
*/
|
|
86
|
+
export function redactValue(value, classifier, depth = 0) {
|
|
87
|
+
if (typeof value === 'string')
|
|
88
|
+
return maskPhonesInText(value);
|
|
89
|
+
if (value === null || typeof value !== 'object' || value instanceof Error || value instanceof Date)
|
|
90
|
+
return value;
|
|
91
|
+
if (depth >= MAX_DEPTH)
|
|
92
|
+
return '[TRUNCATED]';
|
|
93
|
+
if (Array.isArray(value))
|
|
94
|
+
return value.map((v) => redactValue(v, classifier, depth + 1));
|
|
95
|
+
const out = {};
|
|
96
|
+
for (const [key, v] of Object.entries(value)) {
|
|
97
|
+
if (classifier.isSecret(key))
|
|
98
|
+
out[key] = REDACTED;
|
|
99
|
+
else if (classifier.isPhone(key) && (typeof v === 'string' || typeof v === 'number'))
|
|
100
|
+
out[key] = maskPhoneForLog(String(v));
|
|
101
|
+
else
|
|
102
|
+
out[key] = redactValue(v, classifier, depth + 1);
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/logging/redact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base for a service's queue consumers (one class per queue in `src/consumers/`). The subclass declares
|
|
3
|
+
* its queue, bindings, payload schema, retry policy, dedupe and scope in the constructor and implements
|
|
4
|
+
* {@link BaseConsumer.handle}; `worker.ts` registers it. Validation, dedupe, retries, dead-lettering and
|
|
5
|
+
* context restore are done by {@link MessageConsumer}.
|
|
6
|
+
*
|
|
7
|
+
* @typeParam T Validated payload type.
|
|
8
|
+
* @typeParam TTx Dedupe transaction type (`DbExecutor` with `ProcessedEventsDeduper`).
|
|
9
|
+
* @example
|
|
10
|
+
* class ThingCreatedConsumer extends BaseConsumer<ThingCreated, DbExecutor> {
|
|
11
|
+
* constructor(private readonly things: ThingService, dedupe: ProcessedEventsDeduper) {
|
|
12
|
+
* super({ queue: 'thing-created', bindings: [{ exchange: 'events', routingKey: 'thing.created' }],
|
|
13
|
+
* schema: thingCreatedSchema, dedupe, scopeFrom: (d) => ({ tenantId: d.tenantId }) });
|
|
14
|
+
* }
|
|
15
|
+
* protected handle({ data, tx, scope }: InboundMessage<ThingCreated, DbExecutor>) { return this.things.onCreated(scope!, data, tx!); }
|
|
16
|
+
* }
|
|
17
|
+
*/
|
|
18
|
+
export class BaseConsumer {
|
|
19
|
+
definition;
|
|
20
|
+
constructor(definition) {
|
|
21
|
+
this.definition = definition;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Subscribes this consumer.
|
|
25
|
+
*
|
|
26
|
+
* @param consumer The service's {@link MessageConsumer}.
|
|
27
|
+
*/
|
|
28
|
+
register(consumer) {
|
|
29
|
+
return consumer.subscribe({ ...this.definition, handler: (message) => this.handle(message) });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=base-consumer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-consumer.js","sourceRoot":"","sources":["../../../src/messaging/base-consumer.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAgB,YAAY;IACS;IAAzC,YAAyC,UAAsC;QAAtC,eAAU,GAAV,UAAU,CAA4B;IAAG,CAAC;IAKnF;;;;OAIG;IACH,QAAQ,CAAC,QAAyB;QAChC,OAAO,QAAQ,CAAC,SAAS,CAAS,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxG,CAAC;CACF"}
|