@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,7 +47,7 @@ exports.dispatchValueSchema = zod_1.z.union([zod_1.z.string().max(exports.DISPAT
|
|
|
47
47
|
* Who receives a dispatch. `userId` is needed for per-user channels such as an in-app feed;
|
|
48
48
|
* addresses with no account behind them carry only `email`.
|
|
49
49
|
*
|
|
50
|
-
* @example { email: '
|
|
50
|
+
* @example { email: 'ada@example.com', name: 'Ada', userId: '01J…', timezone: 'Europe/Lisbon' }
|
|
51
51
|
*/
|
|
52
52
|
exports.dispatchRecipientSchema = zod_1.z.object({
|
|
53
53
|
email: zod_1.z.string().trim().email().max(exports.DISPATCH_LIMITS.email),
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDb = createDb;
|
|
4
|
+
exports.knexConfig = knexConfig;
|
|
5
|
+
exports.connectionOptions = connectionOptions;
|
|
6
|
+
const mysql2_1 = require("drizzle-orm/mysql2");
|
|
7
|
+
const pool_js_1 = require("./pool.js");
|
|
8
|
+
/**
|
|
9
|
+
* Creates the service's Drizzle database. There is no module-level singleton: call it once in
|
|
10
|
+
* `container.ts` and inject `db` into repositories.
|
|
11
|
+
*
|
|
12
|
+
* @example const { db, ping, close } = createDb({ env: config, schema });
|
|
13
|
+
*/
|
|
14
|
+
function createDb(options) {
|
|
15
|
+
const { env, schema } = options;
|
|
16
|
+
const pool = options.pool ?? (0, pool_js_1.createMysqlPool)(connectionOptions(env));
|
|
17
|
+
const db = (0, mysql2_1.drizzle)(pool, { schema, mode: 'default' });
|
|
18
|
+
return {
|
|
19
|
+
db,
|
|
20
|
+
ping: () => (0, pool_js_1.pingMysql)(pool),
|
|
21
|
+
close: () => pool.end(),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Knex config for a service's `knexfile.js`. Knex runs **migrations and seeds only** (`.cjs` files
|
|
26
|
+
* in `./migrations` and `./seeds`); repositories use Drizzle.
|
|
27
|
+
*
|
|
28
|
+
* @example module.exports = knexConfig(config);
|
|
29
|
+
*/
|
|
30
|
+
function knexConfig(env) {
|
|
31
|
+
return (0, pool_js_1.createKnexConfig)(connectionOptions(env));
|
|
32
|
+
}
|
|
33
|
+
/** Maps the validated `DB_*` env to connection options. */
|
|
34
|
+
function connectionOptions(env) {
|
|
35
|
+
return { host: env.DB_HOST, port: env.DB_PORT, user: env.DB_USER, password: env.DB_PASSWORD, database: env.DB_NAME, poolMax: env.DB_POOL_MAX };
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/database/db.ts"],"names":[],"mappings":";;AAyCA,4BASC;AAQD,gCAEC;AAGD,8CAEC;AAhED,+CAAkE;AAIlE,uCAAsG;AA8BtG;;;;;GAKG;AACH,SAAgB,QAAQ,CAA0C,OAAiC;IACjG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAA,yBAAe,EAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,MAAM,EAAE,GAAG,IAAA,gBAAO,EAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAsB,CAAC;IAC3E,OAAO;QACL,EAAE;QACF,IAAI,EAAE,GAAG,EAAE,CAAC,IAAA,mBAAS,EAAC,IAAI,CAAC;QAC3B,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;KACxB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,GAAgB;IACzC,OAAO,IAAA,0BAAgB,EAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,2DAA2D;AAC3D,SAAgB,iBAAiB,CAAC,GAAgB;IAChD,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC;AACjJ,CAAC"}
|
|
@@ -1,57 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
4
15
|
};
|
|
5
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.createMysqlPool = createMysqlPool;
|
|
7
|
-
exports.createKnexConfig = createKnexConfig;
|
|
8
|
-
exports.pingMysql = pingMysql;
|
|
9
|
-
exports.escapeLike = escapeLike;
|
|
10
|
-
const promise_1 = __importDefault(require("mysql2/promise"));
|
|
11
17
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
18
|
+
* `@heavybit/shared-lib/database`: Drizzle data access for services. Repositories use Drizzle
|
|
19
|
+
* through {@link ScopedRepository} and the scopes in `scopes.ts`; raw scoped queries and Knex in
|
|
20
|
+
* `src/` are forbidden. Knex is for migrations and seeds only (`knexConfig`, `@heavybit/shared-lib/knex`).
|
|
14
21
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
database: options.database,
|
|
22
|
-
connectionLimit: options.poolMax ?? 10,
|
|
23
|
-
waitForConnections: true,
|
|
24
|
-
enableKeepAlive: true,
|
|
25
|
-
timezone: 'Z',
|
|
26
|
-
charset: 'utf8mb4_unicode_ci',
|
|
27
|
-
dateStrings: false,
|
|
28
|
-
supportBigNumbers: true,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
/** Knex config for migrations/seeds and query-builder use (same session settings as the pool). */
|
|
32
|
-
function createKnexConfig(options) {
|
|
33
|
-
return {
|
|
34
|
-
client: 'mysql2',
|
|
35
|
-
connection: {
|
|
36
|
-
host: options.host,
|
|
37
|
-
port: options.port,
|
|
38
|
-
user: options.user,
|
|
39
|
-
password: options.password,
|
|
40
|
-
database: options.database,
|
|
41
|
-
timezone: 'Z',
|
|
42
|
-
charset: 'utf8mb4',
|
|
43
|
-
},
|
|
44
|
-
pool: { min: 0, max: options.poolMax ?? 10 },
|
|
45
|
-
migrations: { directory: options.migrationsDir ?? './migrations', tableName: 'knex_migrations', loadExtensions: ['.cjs', '.js'] },
|
|
46
|
-
seeds: { directory: options.seedsDir ?? './seeds', loadExtensions: ['.cjs', '.js'] },
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
/** Readiness probe helper. */
|
|
50
|
-
async function pingMysql(pool) {
|
|
51
|
-
await pool.query('SELECT 1');
|
|
52
|
-
}
|
|
53
|
-
/** Escapes `%`, `_` and `\` for use inside a LIKE pattern. */
|
|
54
|
-
function escapeLike(value) {
|
|
55
|
-
return value.replace(/[\\%_]/g, (ch) => `\\${ch}`);
|
|
56
|
-
}
|
|
22
|
+
__exportStar(require("./pool.js"), exports);
|
|
23
|
+
__exportStar(require("./db.js"), exports);
|
|
24
|
+
__exportStar(require("./scopes.js"), exports);
|
|
25
|
+
__exportStar(require("./scoped-repository.js"), exports);
|
|
26
|
+
__exportStar(require("./pagination.js"), exports);
|
|
27
|
+
__exportStar(require("./tables.js"), exports);
|
|
57
28
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/database/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/database/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;GAIG;AACH,4CAA0B;AAC1B,0CAAwB;AACxB,8CAA4B;AAC5B,yDAAuC;AACvC,kDAAgC;AAChC,8CAA4B"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cursorQuerySchema = exports.DEFAULT_PAGE_LIMIT = exports.MAX_PAGE_LIMIT = void 0;
|
|
4
|
+
exports.parseCursorQuery = parseCursorQuery;
|
|
5
|
+
exports.encodeCursor = encodeCursor;
|
|
6
|
+
exports.decodeCursor = decodeCursor;
|
|
7
|
+
exports.buildCursorPage = buildCursorPage;
|
|
8
|
+
const zod_1 = require("zod");
|
|
9
|
+
const errors_js_1 = require("../common/errors.js");
|
|
10
|
+
const response_js_1 = require("../common/response.js");
|
|
11
|
+
const index_js_1 = require("../validation/index.js");
|
|
12
|
+
/**
|
|
13
|
+
* Cursor (keyset) pagination (D6). Clients send `?cursor=&limit=`; the cursor is an opaque
|
|
14
|
+
* base64url token of `{ sortKey, id }` (the last row's sort value plus an id tie-breaker).
|
|
15
|
+
* Dependency-light: usable from controllers without the database subpath.
|
|
16
|
+
*/
|
|
17
|
+
/** Largest page size a client may ask for. */
|
|
18
|
+
exports.MAX_PAGE_LIMIT = 100;
|
|
19
|
+
/** Page size when the client sends none. */
|
|
20
|
+
exports.DEFAULT_PAGE_LIMIT = 20;
|
|
21
|
+
const MAX_CURSOR_LENGTH = 512;
|
|
22
|
+
/** `{ cursor?, limit }` query schema: limit 1–100, default 20; unknown keys are stripped. */
|
|
23
|
+
exports.cursorQuerySchema = zod_1.z.object({
|
|
24
|
+
cursor: zod_1.z.string().trim().min(1).max(MAX_CURSOR_LENGTH).optional(),
|
|
25
|
+
limit: zod_1.z.coerce.number().int().min(1).max(exports.MAX_PAGE_LIMIT).default(exports.DEFAULT_PAGE_LIMIT),
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Validates `{ cursor, limit }` from a query string.
|
|
29
|
+
*
|
|
30
|
+
* @throws ValidationError (422) with field errors when invalid.
|
|
31
|
+
* @example const { cursor, limit } = parseCursorQuery(req.query);
|
|
32
|
+
*/
|
|
33
|
+
function parseCursorQuery(input) {
|
|
34
|
+
const result = exports.cursorQuerySchema.safeParse({ cursor: emptyToUndefined(input?.cursor), limit: emptyToUndefined(input?.limit) });
|
|
35
|
+
if (result.success)
|
|
36
|
+
return result.data;
|
|
37
|
+
throw new errors_js_1.ValidationError((0, index_js_1.zodIssuesToErrors)(result.error), 'Invalid pagination parameters');
|
|
38
|
+
}
|
|
39
|
+
function emptyToUndefined(value) {
|
|
40
|
+
return value === '' || value === null ? undefined : value;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Encodes a cursor. Date sort keys become ISO strings.
|
|
44
|
+
*
|
|
45
|
+
* @example encodeCursor({ sortKey: row.createdAt, id: row.id })
|
|
46
|
+
*/
|
|
47
|
+
function encodeCursor(cursor) {
|
|
48
|
+
const sortKey = cursor.sortKey instanceof Date ? cursor.sortKey.toISOString() : cursor.sortKey;
|
|
49
|
+
return Buffer.from(JSON.stringify({ k: sortKey, i: cursor.id }), 'utf8').toString('base64url');
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Decodes a cursor produced by {@link encodeCursor}.
|
|
53
|
+
*
|
|
54
|
+
* @throws ValidationError (422, field `cursor`) for anything malformed or tampered with.
|
|
55
|
+
*/
|
|
56
|
+
function decodeCursor(token) {
|
|
57
|
+
const invalid = () => new errors_js_1.ValidationError({ cursor: ['Invalid cursor'] }, 'Invalid cursor');
|
|
58
|
+
if (typeof token !== 'string' || token.length === 0 || token.length > MAX_CURSOR_LENGTH || !/^[A-Za-z0-9_-]+$/.test(token))
|
|
59
|
+
throw invalid();
|
|
60
|
+
let parsed;
|
|
61
|
+
try {
|
|
62
|
+
parsed = JSON.parse(Buffer.from(token, 'base64url').toString('utf8'));
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
throw invalid();
|
|
66
|
+
}
|
|
67
|
+
if (!parsed || typeof parsed !== 'object')
|
|
68
|
+
throw invalid();
|
|
69
|
+
const { k, i } = parsed;
|
|
70
|
+
const validKey = k === null || typeof k === 'string' || (typeof k === 'number' && Number.isFinite(k));
|
|
71
|
+
if (!validKey || typeof i !== 'string' || i.length === 0 || i.length > 64)
|
|
72
|
+
throw invalid();
|
|
73
|
+
return { sortKey: k, id: i };
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Builds a page from `limit + 1` fetched rows: the extra row only signals that more exist.
|
|
77
|
+
*
|
|
78
|
+
* @param rows Rows fetched with `limit + 1`.
|
|
79
|
+
* @param limit The page size.
|
|
80
|
+
* @param cursorOf Extracts `{ sortKey, id }` from a row for the next cursor.
|
|
81
|
+
*/
|
|
82
|
+
function buildCursorPage(rows, limit, cursorOf) {
|
|
83
|
+
const data = rows.slice(0, limit);
|
|
84
|
+
const hasMore = rows.length > limit && data.length > 0;
|
|
85
|
+
const nextCursor = hasMore ? encodeCursor(cursorOf(data[data.length - 1])) : null;
|
|
86
|
+
return { data, meta: (0, response_js_1.buildCursorPageMeta)(limit, nextCursor) };
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../src/database/pagination.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createMysqlPool = createMysqlPool;
|
|
7
|
+
exports.createKnexConfig = createKnexConfig;
|
|
8
|
+
exports.pingMysql = pingMysql;
|
|
9
|
+
exports.escapeLike = escapeLike;
|
|
10
|
+
const promise_1 = __importDefault(require("mysql2/promise"));
|
|
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
|
+
function createMysqlPool(options) {
|
|
16
|
+
return promise_1.default.createPool({
|
|
17
|
+
host: options.host,
|
|
18
|
+
port: options.port,
|
|
19
|
+
user: options.user,
|
|
20
|
+
password: options.password,
|
|
21
|
+
database: options.database,
|
|
22
|
+
connectionLimit: options.poolMax ?? 10,
|
|
23
|
+
waitForConnections: true,
|
|
24
|
+
enableKeepAlive: true,
|
|
25
|
+
timezone: '+00:00',
|
|
26
|
+
charset: 'utf8mb4_unicode_ci',
|
|
27
|
+
dateStrings: false,
|
|
28
|
+
supportBigNumbers: true,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Knex config for migrations and seeds: mysql2, utf8mb4, UTC, `.cjs` files only. Services call it
|
|
33
|
+
* through `knexConfig(env)` in their `knexfile.js`.
|
|
34
|
+
*/
|
|
35
|
+
function createKnexConfig(options) {
|
|
36
|
+
return {
|
|
37
|
+
client: 'mysql2',
|
|
38
|
+
connection: {
|
|
39
|
+
host: options.host,
|
|
40
|
+
port: options.port,
|
|
41
|
+
user: options.user,
|
|
42
|
+
password: options.password,
|
|
43
|
+
database: options.database,
|
|
44
|
+
timezone: '+00:00',
|
|
45
|
+
charset: 'utf8mb4',
|
|
46
|
+
},
|
|
47
|
+
pool: { min: 0, max: options.poolMax ?? 10 },
|
|
48
|
+
migrations: { directory: options.migrationsDir ?? './migrations', tableName: 'knex_migrations', extension: 'cjs', loadExtensions: ['.cjs'] },
|
|
49
|
+
seeds: { directory: options.seedsDir ?? './seeds', extension: 'cjs', loadExtensions: ['.cjs'] },
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Readiness probe helper. */
|
|
53
|
+
async function pingMysql(pool) {
|
|
54
|
+
await pool.query('SELECT 1');
|
|
55
|
+
}
|
|
56
|
+
/** Escapes `%`, `_` and `\` for use inside a LIKE pattern. */
|
|
57
|
+
function escapeLike(value) {
|
|
58
|
+
return value.replace(/[\\%_]/g, (ch) => `\\${ch}`);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.js","sourceRoot":"","sources":["../../../src/database/pool.ts"],"names":[],"mappings":";;;;;AA+BA,0CAeC;AAMD,4CAgBC;AAGD,8BAEC;AAGD,gCAEC;AA7ED,6DAAmC;AA0BnC;;;GAGG;AACH,SAAgB,eAAe,CAAC,OAA+B;IAC7D,OAAO,iBAAK,CAAC,UAAU,CAAC;QACtB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,eAAe,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;QACtC,kBAAkB,EAAE,IAAI;QACxB,eAAe,EAAE,IAAI;QACrB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE,oBAAoB;QAC7B,WAAW,EAAE,KAAK;QAClB,iBAAiB,EAAE,IAAI;KACxB,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,OAA0B;IACzD,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE;YACV,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,SAAS;SACnB;QACD,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE;QAC5C,UAAU,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,aAAa,IAAI,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE;QAC5I,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,IAAI,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE;KAChG,CAAC;AACJ,CAAC;AAED,8BAA8B;AACvB,KAAK,UAAU,SAAS,CAAC,IAAgB;IAC9C,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAC/B,CAAC;AAED,8DAA8D;AAC9D,SAAgB,UAAU,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScopedRepository = void 0;
|
|
4
|
+
const drizzle_orm_1 = require("drizzle-orm");
|
|
5
|
+
const errors_js_1 = require("../common/errors.js");
|
|
6
|
+
const pagination_js_1 = require("./pagination.js");
|
|
7
|
+
const scopes_js_1 = require("./scopes.js");
|
|
8
|
+
/**
|
|
9
|
+
* Base for every repository over scoped data (Drizzle). Every read, count, update and delete is
|
|
10
|
+
* AND-ed with the scope's condition, and every insert is stamped with the scope value; there is no
|
|
11
|
+
* method that returns an unscoped query. Subclasses add queries only through {@link scoped} and
|
|
12
|
+
* {@link executor}.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* class NoteRepository extends ScopedRepository<typeof notes, ScopeContext<'workspaceId'>> {
|
|
16
|
+
* findByTitle(ctx: ScopeContext<'workspaceId'>, title: string) {
|
|
17
|
+
* return this.executor().select().from(this.table).where(this.scoped(ctx, eq(this.table.title, title)));
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* const repo = new NoteRepository(db, notes, workspaceScope);
|
|
21
|
+
*/
|
|
22
|
+
class ScopedRepository {
|
|
23
|
+
#db;
|
|
24
|
+
table;
|
|
25
|
+
scope;
|
|
26
|
+
idColumn;
|
|
27
|
+
constructor(db, table, scope, options = {}) {
|
|
28
|
+
this.#db = db;
|
|
29
|
+
this.table = table;
|
|
30
|
+
this.scope = scope;
|
|
31
|
+
this.idColumn = (0, scopes_js_1.resolveColumn)(table, options.idColumn ?? 'id').column;
|
|
32
|
+
(0, scopes_js_1.resolveColumn)(table, scope.column); // fail fast when the table lacks the scope column
|
|
33
|
+
}
|
|
34
|
+
/** The row with `id` inside the caller's scope, or null (absent and out-of-scope look the same). */
|
|
35
|
+
async findById(ctx, id, options = {}) {
|
|
36
|
+
const rows = await this.executor(options.tx).select().from(this.table)
|
|
37
|
+
.where(this.scoped(ctx, (0, drizzle_orm_1.eq)(this.idColumn, id))).limit(1);
|
|
38
|
+
return rows[0] ?? null;
|
|
39
|
+
}
|
|
40
|
+
/** Rows inside the caller's scope, keyset-paginated by `orderBy` then id. */
|
|
41
|
+
async findMany(ctx, options = {}) {
|
|
42
|
+
return this.selectPage(ctx, options, clampLimit(options.limit));
|
|
43
|
+
}
|
|
44
|
+
/** Like {@link findMany}, returning `{ data, meta: { limit, nextCursor, hasMore } }`. */
|
|
45
|
+
async findPage(ctx, options = {}) {
|
|
46
|
+
const limit = clampLimit(options.limit);
|
|
47
|
+
const rows = await this.selectPage(ctx, options, limit + 1);
|
|
48
|
+
const { key: sortKey } = (0, scopes_js_1.resolveColumn)(this.table, options.orderBy?.column ?? this.idColumn.name);
|
|
49
|
+
const { key: idKey } = (0, scopes_js_1.resolveColumn)(this.table, this.idColumn.name);
|
|
50
|
+
return (0, pagination_js_1.buildCursorPage)(rows, limit, (row) => {
|
|
51
|
+
const record = row;
|
|
52
|
+
return { sortKey: record[sortKey], id: String(record[idKey]) };
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** Number of rows inside the caller's scope matching `where`. */
|
|
56
|
+
async count(ctx, where, options = {}) {
|
|
57
|
+
const rows = await this.executor(options.tx).select({ n: (0, drizzle_orm_1.count)() }).from(this.table).where(this.scoped(ctx, where));
|
|
58
|
+
return Number(rows[0]?.n ?? 0);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Inserts rows stamped with the caller's scope value.
|
|
62
|
+
*
|
|
63
|
+
* @throws ForbiddenError (`SCOPE_MISMATCH`) when a row names another scope.
|
|
64
|
+
* @returns The stamped rows as written.
|
|
65
|
+
*/
|
|
66
|
+
async insert(ctx, rows, options = {}) {
|
|
67
|
+
const list = (Array.isArray(rows) ? rows : [rows]).map((row) => this.scope.stamp(this.table, row, ctx));
|
|
68
|
+
if (list.length === 0)
|
|
69
|
+
return [];
|
|
70
|
+
await this.executor(options.tx).insert(this.table).values(list);
|
|
71
|
+
return list;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Updates rows inside the caller's scope. Rows never move between scopes.
|
|
75
|
+
*
|
|
76
|
+
* @throws ForbiddenError (`SCOPE_IMMUTABLE`) when `values` sets the scope column.
|
|
77
|
+
* @returns Number of rows changed.
|
|
78
|
+
*/
|
|
79
|
+
async update(ctx, where, values, options = {}) {
|
|
80
|
+
if ((0, scopes_js_1.resolveColumn)(this.table, this.scope.column).key in values) {
|
|
81
|
+
throw new errors_js_1.ForbiddenError(`The ${this.scope.name} of a row cannot be changed`, { code: 'SCOPE_IMMUTABLE' });
|
|
82
|
+
}
|
|
83
|
+
const result = await this.executor(options.tx).update(this.table).set(values).where(this.scoped(ctx, where));
|
|
84
|
+
return affectedRows(result);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Deletes rows inside the caller's scope.
|
|
88
|
+
*
|
|
89
|
+
* @returns Number of rows deleted.
|
|
90
|
+
*/
|
|
91
|
+
async delete(ctx, where, options = {}) {
|
|
92
|
+
const result = await this.executor(options.tx).delete(this.table).where(this.scoped(ctx, where));
|
|
93
|
+
return affectedRows(result);
|
|
94
|
+
}
|
|
95
|
+
/** The scope condition AND-ed with `conditions`. The only way subclasses may build a WHERE. */
|
|
96
|
+
scoped(ctx, ...conditions) {
|
|
97
|
+
return (0, drizzle_orm_1.and)(this.scope.condition(this.table, ctx), ...conditions);
|
|
98
|
+
}
|
|
99
|
+
/** The executor for a call: `tx` when given, otherwise the pool. Always pair with {@link scoped}. */
|
|
100
|
+
executor(tx) {
|
|
101
|
+
return tx ?? this.#db;
|
|
102
|
+
}
|
|
103
|
+
async selectPage(ctx, options, take) {
|
|
104
|
+
const sort = (0, scopes_js_1.resolveColumn)(this.table, options.orderBy?.column ?? this.idColumn.name).column;
|
|
105
|
+
const descending = (options.orderBy?.direction ?? 'desc') === 'desc';
|
|
106
|
+
const after = options.cursor ? this.afterCursor(options.cursor, sort, descending) : undefined;
|
|
107
|
+
const order = descending ? [(0, drizzle_orm_1.desc)(sort), (0, drizzle_orm_1.desc)(this.idColumn)] : [(0, drizzle_orm_1.asc)(sort), (0, drizzle_orm_1.asc)(this.idColumn)];
|
|
108
|
+
const rows = await this.executor(options.tx).select().from(this.table)
|
|
109
|
+
.where(this.scoped(ctx, options.where, after)).orderBy(...order).limit(take);
|
|
110
|
+
return rows;
|
|
111
|
+
}
|
|
112
|
+
/** Keyset condition: rows strictly after the cursor's (sortKey, id) in the sort direction. */
|
|
113
|
+
afterCursor(token, sort, descending) {
|
|
114
|
+
const { sortKey, id } = (0, pagination_js_1.decodeCursor)(token);
|
|
115
|
+
const past = descending ? drizzle_orm_1.lt : drizzle_orm_1.gt;
|
|
116
|
+
if (sort === this.idColumn)
|
|
117
|
+
return past(this.idColumn, id);
|
|
118
|
+
const value = sort.dataType === 'date' && typeof sortKey === 'string' ? new Date(sortKey) : sortKey;
|
|
119
|
+
return (0, drizzle_orm_1.or)(past(sort, value), (0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(sort, value), past(this.idColumn, id)));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.ScopedRepository = ScopedRepository;
|
|
123
|
+
function clampLimit(limit) {
|
|
124
|
+
if (limit === undefined || !Number.isFinite(limit))
|
|
125
|
+
return pagination_js_1.DEFAULT_PAGE_LIMIT;
|
|
126
|
+
return Math.min(pagination_js_1.MAX_PAGE_LIMIT, Math.max(1, Math.trunc(limit)));
|
|
127
|
+
}
|
|
128
|
+
function affectedRows(result) {
|
|
129
|
+
const header = (Array.isArray(result) ? result[0] : result);
|
|
130
|
+
return Number(header?.affectedRows ?? 0);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=scoped-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoped-repository.js","sourceRoot":"","sources":["../../../src/database/scoped-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlatformScopeDefinition = exports.PlatformScope = exports.OwnerScope = void 0;
|
|
4
|
+
exports.resolveColumn = resolveColumn;
|
|
5
|
+
exports.defineScope = defineScope;
|
|
6
|
+
exports.definePlatformScope = definePlatformScope;
|
|
7
|
+
const drizzle_orm_1 = require("drizzle-orm");
|
|
8
|
+
const errors_js_1 = require("../common/errors.js");
|
|
9
|
+
/**
|
|
10
|
+
* Finds a table column by its database name.
|
|
11
|
+
*
|
|
12
|
+
* @throws Error when the table has no such column (a wiring bug, caught at startup or in tests).
|
|
13
|
+
*/
|
|
14
|
+
function resolveColumn(table, dbName) {
|
|
15
|
+
const columns = (0, drizzle_orm_1.getTableColumns)(table);
|
|
16
|
+
for (const [key, column] of Object.entries(columns)) {
|
|
17
|
+
if (column.name === dbName)
|
|
18
|
+
return { key, column };
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Table has no column "${dbName}"`);
|
|
21
|
+
}
|
|
22
|
+
function requireValue(value, scopeName, code) {
|
|
23
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
24
|
+
throw new errors_js_1.ForbiddenError(`A ${scopeName} scope is required`, { code });
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
/** Sets `column` on `row` to `value`; refuses a row that carries a different value. */
|
|
29
|
+
function stampColumn(table, row, dbName, value, scopeName) {
|
|
30
|
+
const { key } = resolveColumn(table, dbName);
|
|
31
|
+
const current = row[key];
|
|
32
|
+
if (current !== undefined && current !== null && current !== value) {
|
|
33
|
+
throw new errors_js_1.ForbiddenError(`Row belongs to another ${scopeName}`, { code: 'SCOPE_MISMATCH' });
|
|
34
|
+
}
|
|
35
|
+
return { ...row, [key]: value };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Defines a scope whose value comes from the request context (the gateway-signed identity, never a
|
|
39
|
+
* request body).
|
|
40
|
+
*
|
|
41
|
+
* @example const workspaceScope = defineScope({ name: 'workspace', column: 'workspace_id', contextKey: 'workspaceId' });
|
|
42
|
+
*/
|
|
43
|
+
function defineScope(options) {
|
|
44
|
+
const { name, column, contextKey } = options;
|
|
45
|
+
const valueOf = (ctx) => requireValue(ctx?.[contextKey], name, 'SCOPE_REQUIRED');
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
name,
|
|
48
|
+
column,
|
|
49
|
+
contextKey,
|
|
50
|
+
valueOf,
|
|
51
|
+
condition: (table, ctx) => (0, drizzle_orm_1.eq)(resolveColumn(table, column).column, valueOf(ctx)),
|
|
52
|
+
stamp: (table, row, ctx) => stampColumn(table, row, column, valueOf(ctx), name),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Rows owned by one principal (e.g. a user's own records). Refuses a missing owner id, so an
|
|
57
|
+
* anonymous call can never fall through to "all owners".
|
|
58
|
+
*
|
|
59
|
+
* @example const ownerScope = new OwnerScope({ name: 'owner', column: 'user_id' });
|
|
60
|
+
*/
|
|
61
|
+
class OwnerScope {
|
|
62
|
+
/** Readable name (e.g. `owner`). */
|
|
63
|
+
name;
|
|
64
|
+
/** Database name of the owner column (e.g. `user_id`). */
|
|
65
|
+
column;
|
|
66
|
+
/** @param options `name` for messages, `column` = database name of the owner column. */
|
|
67
|
+
constructor(options) {
|
|
68
|
+
this.name = options.name;
|
|
69
|
+
this.column = options.column;
|
|
70
|
+
}
|
|
71
|
+
/** The owner id from `ctx`; throws ForbiddenError (`OWNER_REQUIRED`) when it is missing. */
|
|
72
|
+
ownerIdOf(ctx) {
|
|
73
|
+
return requireValue(ctx?.ownerId, this.name, 'OWNER_REQUIRED');
|
|
74
|
+
}
|
|
75
|
+
/** `owner column = ownerId`. @throws ForbiddenError (`OWNER_REQUIRED`) without an owner id. */
|
|
76
|
+
condition(table, ctx) {
|
|
77
|
+
return (0, drizzle_orm_1.eq)(resolveColumn(table, this.column).column, this.ownerIdOf(ctx));
|
|
78
|
+
}
|
|
79
|
+
/** Sets the owner column. @throws ForbiddenError (`OWNER_REQUIRED`, `SCOPE_MISMATCH`). */
|
|
80
|
+
stamp(table, row, ctx) {
|
|
81
|
+
return stampColumn(table, row, this.column, this.ownerIdOf(ctx), this.name);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.OwnerScope = OwnerScope;
|
|
85
|
+
const ISSUE = Symbol('PlatformScope.issue');
|
|
86
|
+
/**
|
|
87
|
+
* Proof that an identity may act across scopes. Only {@link PlatformScopeDefinition.authorize} can
|
|
88
|
+
* create one, and only when the definition's predicate approves the identity.
|
|
89
|
+
*/
|
|
90
|
+
class PlatformScope {
|
|
91
|
+
#definition;
|
|
92
|
+
/** @internal Use `definePlatformScope(...).authorize(identity)`. */
|
|
93
|
+
constructor(token, definition) {
|
|
94
|
+
if (token !== ISSUE)
|
|
95
|
+
throw new errors_js_1.ForbiddenError('Platform scope must be authorized', { code: 'PLATFORM_SCOPE_REQUIRED' });
|
|
96
|
+
this.#definition = definition;
|
|
97
|
+
}
|
|
98
|
+
/** True when this grant was issued by `definition`. */
|
|
99
|
+
issuedBy(definition) {
|
|
100
|
+
return this.#definition === definition;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.PlatformScope = PlatformScope;
|
|
104
|
+
/**
|
|
105
|
+
* Cross-scope access for platform operators. Rows of every scope are reachable, but the query still
|
|
106
|
+
* filters on the scope column (`IS NOT NULL`) and inserts must name their scope explicitly.
|
|
107
|
+
*/
|
|
108
|
+
class PlatformScopeDefinition {
|
|
109
|
+
/** Readable name (e.g. `platform`). */
|
|
110
|
+
name;
|
|
111
|
+
/** Database name of the scope column the platform scope spans. */
|
|
112
|
+
column;
|
|
113
|
+
#predicate;
|
|
114
|
+
/** Prefer {@link definePlatformScope}. */
|
|
115
|
+
constructor(options) {
|
|
116
|
+
this.name = options.name;
|
|
117
|
+
this.column = options.column;
|
|
118
|
+
this.#predicate = options.predicate;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Issues a {@link PlatformScope} for `identity`.
|
|
122
|
+
*
|
|
123
|
+
* @throws ForbiddenError (`PLATFORM_SCOPE_DENIED`) when the predicate refuses (or throws).
|
|
124
|
+
*/
|
|
125
|
+
authorize(identity) {
|
|
126
|
+
let allowed = false;
|
|
127
|
+
try {
|
|
128
|
+
allowed = identity != null && this.#predicate(identity);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
allowed = false;
|
|
132
|
+
}
|
|
133
|
+
if (!allowed)
|
|
134
|
+
throw new errors_js_1.ForbiddenError('Platform access is required', { code: 'PLATFORM_SCOPE_DENIED' });
|
|
135
|
+
return new PlatformScope(ISSUE, this);
|
|
136
|
+
}
|
|
137
|
+
/** `scope column IS NOT NULL`. @throws ForbiddenError (`PLATFORM_SCOPE_REQUIRED`) without a grant from this scope. */
|
|
138
|
+
condition(table, ctx) {
|
|
139
|
+
this.assertGrant(ctx);
|
|
140
|
+
return (0, drizzle_orm_1.isNotNull)(resolveColumn(table, this.column).column);
|
|
141
|
+
}
|
|
142
|
+
/** Requires the row to name its scope. @throws ForbiddenError (`PLATFORM_SCOPE_REQUIRED`, `SCOPE_REQUIRED`). */
|
|
143
|
+
stamp(table, row, ctx) {
|
|
144
|
+
this.assertGrant(ctx);
|
|
145
|
+
const { key } = resolveColumn(table, this.column);
|
|
146
|
+
requireValue(row[key], this.name, 'SCOPE_REQUIRED');
|
|
147
|
+
return row;
|
|
148
|
+
}
|
|
149
|
+
assertGrant(ctx) {
|
|
150
|
+
if (!(ctx instanceof PlatformScope) || !ctx.issuedBy(this)) {
|
|
151
|
+
throw new errors_js_1.ForbiddenError('Platform access is required', { code: 'PLATFORM_SCOPE_REQUIRED' });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
exports.PlatformScopeDefinition = PlatformScopeDefinition;
|
|
156
|
+
/**
|
|
157
|
+
* Defines the platform (cross-scope) scope.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* const platformScope = definePlatformScope({ name: 'platform', column: 'workspace_id', predicate: (u: AuthUser) => u.isSuperAdmin });
|
|
161
|
+
* const grant = platformScope.authorize(req.user); // throws 403 for anyone else
|
|
162
|
+
*/
|
|
163
|
+
function definePlatformScope(options) {
|
|
164
|
+
return new PlatformScopeDefinition(options);
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=scopes.js.map
|