@ddd-ts-kit/knex 0.7.0 → 0.9.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 +91 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/outbox/add-outbox-tenant-column.d.ts +9 -0
- package/dist/outbox/add-outbox-tenant-column.d.ts.map +1 -0
- package/dist/outbox/add-outbox-tenant-column.js +14 -0
- package/dist/outbox/add-outbox-tenant-column.js.map +1 -0
- package/dist/outbox/create-outbox-tables.js +3 -0
- package/dist/outbox/create-outbox-tables.js.map +1 -1
- package/dist/outbox/knex-outbox-store.d.ts +7 -0
- package/dist/outbox/knex-outbox-store.d.ts.map +1 -1
- package/dist/outbox/knex-outbox-store.js +4 -0
- package/dist/outbox/knex-outbox-store.js.map +1 -1
- package/dist/outbox/outbox-tables-options.d.ts +2 -0
- package/dist/outbox/outbox-tables-options.d.ts.map +1 -1
- package/dist/read-model/knex-read-model-options.d.ts +11 -0
- package/dist/read-model/knex-read-model-options.d.ts.map +1 -1
- package/dist/read-model/knex-read-model-table.js +1 -1
- package/dist/read-model/knex-read-model-table.js.map +1 -1
- package/dist/read-model/knex-stamped-rows.d.ts +4 -1
- package/dist/read-model/knex-stamped-rows.d.ts.map +1 -1
- package/dist/read-model/knex-stamped-rows.js +15 -2
- package/dist/read-model/knex-stamped-rows.js.map +1 -1
- package/dist/tenancy/create-tenant-routed-unit-of-work.d.ts +13 -0
- package/dist/tenancy/create-tenant-routed-unit-of-work.d.ts.map +1 -0
- package/dist/tenancy/create-tenant-routed-unit-of-work.js +37 -0
- package/dist/tenancy/create-tenant-routed-unit-of-work.js.map +1 -0
- package/dist/tenancy/cross-tenant-unit-of-work-error.d.ts +8 -0
- package/dist/tenancy/cross-tenant-unit-of-work-error.d.ts.map +1 -0
- package/dist/tenancy/cross-tenant-unit-of-work-error.js +11 -0
- package/dist/tenancy/cross-tenant-unit-of-work-error.js.map +1 -0
- package/dist/tenancy/enable-tenant-isolation.d.ts +8 -0
- package/dist/tenancy/enable-tenant-isolation.d.ts.map +1 -0
- package/dist/tenancy/enable-tenant-isolation.js +11 -0
- package/dist/tenancy/enable-tenant-isolation.js.map +1 -0
- package/dist/tenancy/invalid-tenant-identifier-error.d.ts +5 -0
- package/dist/tenancy/invalid-tenant-identifier-error.d.ts.map +1 -0
- package/dist/tenancy/invalid-tenant-identifier-error.js +8 -0
- package/dist/tenancy/invalid-tenant-identifier-error.js.map +1 -0
- package/dist/tenancy/migrate-every-tenant.d.ts +10 -0
- package/dist/tenancy/migrate-every-tenant.d.ts.map +1 -0
- package/dist/tenancy/migrate-every-tenant.js +16 -0
- package/dist/tenancy/migrate-every-tenant.js.map +1 -0
- package/dist/tenancy/migrate-tenant-schema.d.ts +9 -0
- package/dist/tenancy/migrate-tenant-schema.d.ts.map +1 -0
- package/dist/tenancy/migrate-tenant-schema.js +15 -0
- package/dist/tenancy/migrate-tenant-schema.js.map +1 -0
- package/dist/tenancy/own-tenant-table.d.ts +10 -0
- package/dist/tenancy/own-tenant-table.d.ts.map +1 -0
- package/dist/tenancy/own-tenant-table.js +11 -0
- package/dist/tenancy/own-tenant-table.js.map +1 -0
- package/dist/tenancy/statement-outside-unit-of-work-error.d.ts +5 -0
- package/dist/tenancy/statement-outside-unit-of-work-error.d.ts.map +1 -0
- package/dist/tenancy/statement-outside-unit-of-work-error.js +8 -0
- package/dist/tenancy/statement-outside-unit-of-work-error.js.map +1 -0
- package/dist/tenancy/table-in.d.ts +6 -0
- package/dist/tenancy/table-in.d.ts.map +1 -0
- package/dist/tenancy/table-in.js +6 -0
- package/dist/tenancy/table-in.js.map +1 -0
- package/dist/tenancy/tenant-databases-options.d.ts +15 -0
- package/dist/tenancy/tenant-databases-options.d.ts.map +1 -0
- package/dist/tenancy/tenant-databases-options.js +2 -0
- package/dist/tenancy/tenant-databases-options.js.map +1 -0
- package/dist/tenancy/tenant-databases.d.ts +29 -0
- package/dist/tenancy/tenant-databases.d.ts.map +1 -0
- package/dist/tenancy/tenant-databases.js +80 -0
- package/dist/tenancy/tenant-databases.js.map +1 -0
- package/dist/tenancy/tenant-isolation-statements.d.ts +12 -0
- package/dist/tenancy/tenant-isolation-statements.d.ts.map +1 -0
- package/dist/tenancy/tenant-isolation-statements.js +31 -0
- package/dist/tenancy/tenant-isolation-statements.js.map +1 -0
- package/dist/tenancy/tenant-of-migration.d.ts +7 -0
- package/dist/tenancy/tenant-of-migration.d.ts.map +1 -0
- package/dist/tenancy/tenant-of-migration.js +12 -0
- package/dist/tenancy/tenant-of-migration.js.map +1 -0
- package/dist/tenancy/tenant-schema-of.d.ts +8 -0
- package/dist/tenancy/tenant-schema-of.d.ts.map +1 -0
- package/dist/tenancy/tenant-schema-of.js +21 -0
- package/dist/tenancy/tenant-schema-of.js.map +1 -0
- package/dist/tenancy/tenant-schema-table.d.ts +11 -0
- package/dist/tenancy/tenant-schema-table.d.ts.map +1 -0
- package/dist/tenancy/tenant-schema-table.js +13 -0
- package/dist/tenancy/tenant-schema-table.js.map +1 -0
- package/dist/tenancy/tenant-schema-target.d.ts +6 -0
- package/dist/tenancy/tenant-schema-target.d.ts.map +1 -0
- package/dist/tenancy/tenant-schema-target.js +2 -0
- package/dist/tenancy/tenant-schema-target.js.map +1 -0
- package/dist/tenancy/tenant-search-path.d.ts +11 -0
- package/dist/tenancy/tenant-search-path.d.ts.map +1 -0
- package/dist/tenancy/tenant-search-path.js +16 -0
- package/dist/tenancy/tenant-search-path.js.map +1 -0
- package/dist/tenancy/tenant-session.d.ts +10 -0
- package/dist/tenancy/tenant-session.d.ts.map +1 -0
- package/dist/tenancy/tenant-session.js +21 -0
- package/dist/tenancy/tenant-session.js.map +1 -0
- package/dist/tenancy/tenant-table-target.d.ts +7 -0
- package/dist/tenancy/tenant-table-target.d.ts.map +1 -0
- package/dist/tenancy/tenant-table-target.js +2 -0
- package/dist/tenancy/tenant-table-target.js.map +1 -0
- package/dist/tenancy/tenant-table.d.ts +12 -0
- package/dist/tenancy/tenant-table.d.ts.map +1 -0
- package/dist/tenancy/tenant-table.js +12 -0
- package/dist/tenancy/tenant-table.js.map +1 -0
- package/dist/tenancy/where-tenant.d.ts +10 -0
- package/dist/tenancy/where-tenant.d.ts.map +1 -0
- package/dist/tenancy/where-tenant.js +15 -0
- package/dist/tenancy/where-tenant.js.map +1 -0
- package/dist/unit-of-work/create-knex-unit-of-work.d.ts +8 -1
- package/dist/unit-of-work/create-knex-unit-of-work.d.ts.map +1 -1
- package/dist/unit-of-work/create-knex-unit-of-work.js +7 -2
- package/dist/unit-of-work/create-knex-unit-of-work.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -68,6 +68,12 @@ export async function up(knex: Knex): Promise<void> {
|
|
|
68
68
|
`processed_events` has `(consumer, event_id)` as its primary key. `occurred_at` is text on
|
|
69
69
|
purpose: the envelope comes back exactly as published, offset included.
|
|
70
70
|
|
|
71
|
+
A multi-tenant project keeps the tenant of each event, so that its consumers run in that tenant:
|
|
72
|
+
`createOutboxTables(knex, { schema: 'messaging', tenant: true })` adds a nullable `tenant_id`
|
|
73
|
+
(`addOutboxTenantColumn(knex, { schema: 'messaging' })` is the migration of a project that becomes
|
|
74
|
+
multi-tenant), and `new KnexOutboxStore(context, { schema: 'messaging', tenant: true })` writes
|
|
75
|
+
it. A table that has the column is read back either way.
|
|
76
|
+
|
|
71
77
|
One schema per bounded context: `schemaNameOf('order-management')` gives `order_management`,
|
|
72
78
|
to pass to `knex.schema.createSchemaIfNotExists`, `knex.schema.withSchema` and
|
|
73
79
|
`.withSchema(...)` on queries. Contexts never join each other's tables.
|
|
@@ -419,6 +425,91 @@ The rules these examples hold, and that the tests of this package check on a rea
|
|
|
419
425
|
- **An offset page answers `total`**, a cursor page `nextCursor`. Offer the offset form for
|
|
420
426
|
small, browsable lists and the cursor form for anything that grows.
|
|
421
427
|
|
|
428
|
+
## Tenant isolation
|
|
429
|
+
|
|
430
|
+
Four strategies, chosen per project ([Multitenancy](../../docs/concepts/multitenancy.md) says
|
|
431
|
+
when each fits). Every one of them is proven here by `tenantIsolationContract` of
|
|
432
|
+
`@ddd-ts-kit/testing/contracts`, on PGlite and on PostgreSQL.
|
|
433
|
+
|
|
434
|
+
**Shared tables.** One table per aggregate, a `tenant_id` column, and every statement confined
|
|
435
|
+
by the kit instead of by a condition written by hand:
|
|
436
|
+
|
|
437
|
+
```ts
|
|
438
|
+
const INVOICES = { schema: BILLING, table: 'invoices' };
|
|
439
|
+
|
|
440
|
+
// reads: the tenant of the work, or the tenants of an elevation
|
|
441
|
+
const row = await tenantTable<InvoiceRow>(this.context, this.scope, INVOICES).where({ id }).first();
|
|
442
|
+
// updates and deletes: the one tenant of the work, which an elevation never widens
|
|
443
|
+
await ownTenantTable<InvoiceRow>(this.context, this.scope, INVOICES).where({ id, version: expected }).update(changes);
|
|
444
|
+
// inserts name the tenant themselves
|
|
445
|
+
const inserted = { ...state, ...tenantRow(tenantScopeOf(this.scope)), ...auditRow(stampCreation(this.scope, this.clock)) };
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
`whereTenant(builder, scope)` is the condition alone, for a builder of your own. Work that names
|
|
449
|
+
no tenant raises `NoCurrentTenantError` before any SQL. A read model of tenant data passes
|
|
450
|
+
`tenant: scope` to `KnexReadModelTable` and `KnexReadModelStore`: each row is written with the
|
|
451
|
+
tenant of the work and every read and write is confined to it (keys stay unique across tenants;
|
|
452
|
+
a rebuild, which runs in no tenant, is refused).
|
|
453
|
+
|
|
454
|
+
**Row-level security**, a second line on shared tables: the database itself refuses a row of
|
|
455
|
+
another tenant, even to a statement that forgot its condition.
|
|
456
|
+
|
|
457
|
+
```ts
|
|
458
|
+
// the migration that creates the table
|
|
459
|
+
await enableTenantIsolation(knex, INVOICES); // enable, force on the owner, one policy per command
|
|
460
|
+
|
|
461
|
+
// the composition root
|
|
462
|
+
const unitOfWork = createKnexUnitOfWork(knex, undefined, { begin: tenantSession(executionScope) });
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
`tenantSession` sets the tenant settings for each transaction only (`set_config(..., true)`), so
|
|
466
|
+
a pooled connection never carries a tenant into the next one: `ddd_ts_kit.tenant_id`, and for an
|
|
467
|
+
elevation `ddd_ts_kit.reach` (the tenants listed) or `ddd_ts_kit.every_tenant`. There is one
|
|
468
|
+
policy per command: a select sees the tenant of the work and what an elevation reaches; an
|
|
469
|
+
insert, an update and a delete only ever touch the tenant of the work, so an elevated
|
|
470
|
+
`delete from invoices` without a condition removes no other tenant's row.
|
|
471
|
+
`tenantIsolationStatements(target)` gives the SQL for a migration written by hand. Three
|
|
472
|
+
conditions hold it: the application connects with a role that is **not a superuser and has no
|
|
473
|
+
`BYPASSRLS`** (both ignore every policy); every statement runs **inside the unit of work** (a
|
|
474
|
+
statement outside of a transaction carries no setting and sees nothing, so queries go through the
|
|
475
|
+
unit of work too); migrations run as the owner, outside of it.
|
|
476
|
+
|
|
477
|
+
**Schema per tenant.** The tables of a context exist once per tenant, in `<schema>__<tenant>`
|
|
478
|
+
(`tenantSchemaOf('billing', 'acme')`; a tenant id that a schema name could not hold as it is, is
|
|
479
|
+
refused rather than altered). `tenantSchemaTable(context, scope, { schema: BILLING, table:
|
|
480
|
+
'invoices' })` reaches the tenant's copy. The tenant migrations live in a directory of their own
|
|
481
|
+
and name their schema from the tenant they run for:
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
export async function up(knex: Knex): Promise<void> {
|
|
485
|
+
const schema = tenantSchemaOf(BILLING, tenantOfMigration(knex));
|
|
486
|
+
|
|
487
|
+
await knex.schema.createSchemaIfNotExists(schema);
|
|
488
|
+
await knex.schema.withSchema(schema).createTable('invoices', (table) => { /* ... */ });
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
`migrateTenantSchema(knex, tenantId, { directory: 'migrations/tenant' })` applies them for one
|
|
493
|
+
tenant and records them in `migrations__<tenant>`, so each tenant moves on its own and a new
|
|
494
|
+
tenant is provisioned by its first run. `tenantSearchPath(scope, [BILLING])` is a `begin` that
|
|
495
|
+
sets the search path of each transaction to the tenant's schemas only, for SQL that names no
|
|
496
|
+
schema. An elevation does not reach several schemas at once: staff read one tenant at a time.
|
|
497
|
+
|
|
498
|
+
**Database per tenant.** `new TenantDatabases({ connectionOf: (tenantId) => configOf(tenantId),
|
|
499
|
+
maxTenants: 20 })` opens one knex (one bounded pool) per tenant on first use. At most
|
|
500
|
+
`maxTenants` instances exist at once, those still closing included, so the server never has to
|
|
501
|
+
accept more than `maxTenants * pool.max` connections per instance of the application. Work holds
|
|
502
|
+
the instance of its tenant by a lease (`databases.lease(tenantId, (knex) => ...)`): an instance is
|
|
503
|
+
closed only when no work holds it, the least recently used first, and work for another tenant
|
|
504
|
+
waits for a place instead of opening beyond the bound. `createTenantRoutedUnitOfWork(databases,
|
|
505
|
+
scope)` is the unit of work and `KnexContext`: each transaction holds a lease on the database of
|
|
506
|
+
the tenant of the work until it ends; every statement runs inside it
|
|
507
|
+
(`StatementOutsideUnitOfWorkError` otherwise, so queries go through the unit of work too), work
|
|
508
|
+
that names no tenant reaches no database, and work of another tenant never joins an open
|
|
509
|
+
transaction (`CrossTenantUnitOfWorkError`). `migrateEveryTenant(databases, directory, migrate)`
|
|
510
|
+
applies the migrations to every tenant of a `TenantDirectory`, stopping at the first failure and
|
|
511
|
+
naming its tenant.
|
|
512
|
+
|
|
422
513
|
## Criteria
|
|
423
514
|
|
|
424
515
|
`criteriaToKnex(builder, plan, columns)` adds a criteria plan of the kernel to a query: the
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './outbox/table-names.js';
|
|
|
5
5
|
export * from './outbox/outbox-tables-options.js';
|
|
6
6
|
export * from './outbox/create-outbox-tables.js';
|
|
7
7
|
export * from './outbox/drop-outbox-tables.js';
|
|
8
|
+
export * from './outbox/add-outbox-tenant-column.js';
|
|
8
9
|
export * from './outbox/knex-outbox-store.js';
|
|
9
10
|
export * from './outbox/knex-processed-event-store.js';
|
|
10
11
|
export * from './columns/audit-columns.js';
|
|
@@ -18,4 +19,24 @@ export * from './read-model/criteria-to-knex.js';
|
|
|
18
19
|
export * from './read-model/knex-read-model-options.js';
|
|
19
20
|
export * from './read-model/knex-read-model-table.js';
|
|
20
21
|
export * from './read-model/knex-read-model-store.js';
|
|
22
|
+
export * from './tenancy/where-tenant.js';
|
|
23
|
+
export * from './tenancy/tenant-table-target.js';
|
|
24
|
+
export * from './tenancy/tenant-table.js';
|
|
25
|
+
export * from './tenancy/own-tenant-table.js';
|
|
26
|
+
export * from './tenancy/tenant-isolation-statements.js';
|
|
27
|
+
export * from './tenancy/enable-tenant-isolation.js';
|
|
28
|
+
export * from './tenancy/tenant-session.js';
|
|
29
|
+
export * from './tenancy/invalid-tenant-identifier-error.js';
|
|
30
|
+
export * from './tenancy/tenant-schema-of.js';
|
|
31
|
+
export * from './tenancy/tenant-schema-target.js';
|
|
32
|
+
export * from './tenancy/tenant-schema-table.js';
|
|
33
|
+
export * from './tenancy/tenant-search-path.js';
|
|
34
|
+
export * from './tenancy/tenant-of-migration.js';
|
|
35
|
+
export * from './tenancy/migrate-tenant-schema.js';
|
|
36
|
+
export * from './tenancy/tenant-databases-options.js';
|
|
37
|
+
export * from './tenancy/tenant-databases.js';
|
|
38
|
+
export * from './tenancy/cross-tenant-unit-of-work-error.js';
|
|
39
|
+
export * from './tenancy/statement-outside-unit-of-work-error.js';
|
|
40
|
+
export * from './tenancy/create-tenant-routed-unit-of-work.js';
|
|
41
|
+
export * from './tenancy/migrate-every-tenant.js';
|
|
21
42
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yCAAyC,CAAC;AACxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sCAAsC,CAAC;AACrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yCAAyC,CAAC;AACxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8CAA8C,CAAC;AAC7D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8CAA8C,CAAC;AAC7D,cAAc,mDAAmD,CAAC;AAClE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,mCAAmC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from './outbox/table-names.js';
|
|
|
5
5
|
export * from './outbox/outbox-tables-options.js';
|
|
6
6
|
export * from './outbox/create-outbox-tables.js';
|
|
7
7
|
export * from './outbox/drop-outbox-tables.js';
|
|
8
|
+
export * from './outbox/add-outbox-tenant-column.js';
|
|
8
9
|
export * from './outbox/knex-outbox-store.js';
|
|
9
10
|
export * from './outbox/knex-processed-event-store.js';
|
|
10
11
|
export * from './columns/audit-columns.js';
|
|
@@ -18,4 +19,24 @@ export * from './read-model/criteria-to-knex.js';
|
|
|
18
19
|
export * from './read-model/knex-read-model-options.js';
|
|
19
20
|
export * from './read-model/knex-read-model-table.js';
|
|
20
21
|
export * from './read-model/knex-read-model-store.js';
|
|
22
|
+
export * from './tenancy/where-tenant.js';
|
|
23
|
+
export * from './tenancy/tenant-table-target.js';
|
|
24
|
+
export * from './tenancy/tenant-table.js';
|
|
25
|
+
export * from './tenancy/own-tenant-table.js';
|
|
26
|
+
export * from './tenancy/tenant-isolation-statements.js';
|
|
27
|
+
export * from './tenancy/enable-tenant-isolation.js';
|
|
28
|
+
export * from './tenancy/tenant-session.js';
|
|
29
|
+
export * from './tenancy/invalid-tenant-identifier-error.js';
|
|
30
|
+
export * from './tenancy/tenant-schema-of.js';
|
|
31
|
+
export * from './tenancy/tenant-schema-target.js';
|
|
32
|
+
export * from './tenancy/tenant-schema-table.js';
|
|
33
|
+
export * from './tenancy/tenant-search-path.js';
|
|
34
|
+
export * from './tenancy/tenant-of-migration.js';
|
|
35
|
+
export * from './tenancy/migrate-tenant-schema.js';
|
|
36
|
+
export * from './tenancy/tenant-databases-options.js';
|
|
37
|
+
export * from './tenancy/tenant-databases.js';
|
|
38
|
+
export * from './tenancy/cross-tenant-unit-of-work-error.js';
|
|
39
|
+
export * from './tenancy/statement-outside-unit-of-work-error.js';
|
|
40
|
+
export * from './tenancy/create-tenant-routed-unit-of-work.js';
|
|
41
|
+
export * from './tenancy/migrate-every-tenant.js';
|
|
21
42
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GAEb,MAAM,oBAAoB,CAAC;AAC5B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yCAAyC,CAAC;AACxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GAEb,MAAM,oBAAoB,CAAC;AAC5B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sCAAsC,CAAC;AACrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yCAAyC,CAAC;AACxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8CAA8C,CAAC;AAC7D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8CAA8C,CAAC;AAC7D,cAAc,mDAAmD,CAAC;AAClE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,mCAAmC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
import type { OutboxTablesOptions } from './outbox-tables-options.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adds `tenant_id` to an outbox created without it: the migration of a project that becomes
|
|
5
|
+
* multi-tenant (`export const up = (knex) => addOutboxTenantColumn(knex, { schema: 'messaging' })`).
|
|
6
|
+
* Nullable: the events already in it belong to no tenant.
|
|
7
|
+
*/
|
|
8
|
+
export declare function addOutboxTenantColumn(knex: Knex, options?: OutboxTablesOptions): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=add-outbox-tenant-column.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-outbox-tenant-column.d.ts","sourceRoot":"","sources":["../../src/outbox/add-outbox-tenant-column.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAItE;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIxG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { builderIn } from './builder-in.js';
|
|
2
|
+
import { INDEXABLE_LENGTH } from '../columns/indexable-length.js';
|
|
3
|
+
import { OUTBOX_TABLE } from './table-names.js';
|
|
4
|
+
/**
|
|
5
|
+
* Adds `tenant_id` to an outbox created without it: the migration of a project that becomes
|
|
6
|
+
* multi-tenant (`export const up = (knex) => addOutboxTenantColumn(knex, { schema: 'messaging' })`).
|
|
7
|
+
* Nullable: the events already in it belong to no tenant.
|
|
8
|
+
*/
|
|
9
|
+
export async function addOutboxTenantColumn(knex, options = {}) {
|
|
10
|
+
await builderIn(knex, options.schema).alterTable(options.outboxTable ?? OUTBOX_TABLE, (table) => {
|
|
11
|
+
table.string('tenant_id', INDEXABLE_LENGTH);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=add-outbox-tenant-column.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-outbox-tenant-column.js","sourceRoot":"","sources":["../../src/outbox/add-outbox-tenant-column.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAU,EAAE,OAAO,GAAwB,EAAE;IACvF,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,IAAI,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;QAC9F,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -41,6 +41,9 @@ async function createOutboxTable(knex, options) {
|
|
|
41
41
|
table.jsonb('payload');
|
|
42
42
|
table.text('traceparent');
|
|
43
43
|
table.text('correlation_id');
|
|
44
|
+
if (options.tenant === true) {
|
|
45
|
+
table.string('tenant_id', INDEXABLE_LENGTH);
|
|
46
|
+
}
|
|
44
47
|
table.string('status', 16).notNullable().defaultTo('pending');
|
|
45
48
|
table.integer('attempts').notNullable().defaultTo(0);
|
|
46
49
|
table.datetime('next_attempt_at', INSTANT).notNullable();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-outbox-tables.js","sourceRoot":"","sources":["../../src/outbox/create-outbox-tables.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAExE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAU,EAAE,OAAO,GAAwB,EAAE;IACpF,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,MAAM,0BAA0B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,sFAAsF;AACtF,KAAK,UAAU,eAAe,CAAC,IAAU,EAAE,IAAY;IACrD,QAAQ,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,KAAK,UAAU;YACb,MAAM,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;YAEhD,OAAO;QACT,KAAK,OAAO;YACV,MAAM,IAAI,CAAC,GAAG,CAAC,kCAAkC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAE3D,OAAO;QACT,KAAK,QAAQ;YACX,MAAM,IAAI,SAAS,CACjB,8FAA8F,CAC/F,CAAC;QACJ,QAAQ;QACR,+DAA+D;IACjE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,IAAU,EAAE,OAA4B;IACvE,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,YAAY,CAAC;IAEnD,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAClE,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QACjC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QACvC,4FAA4F;QAC5F,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACxC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"create-outbox-tables.js","sourceRoot":"","sources":["../../src/outbox/create-outbox-tables.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,12 @@ export interface KnexOutboxStoreOptions {
|
|
|
19
19
|
readonly leaseMs?: number;
|
|
20
20
|
/** Default: `skip-locked` on PostgreSQL and MySQL, `compare-and-set` elsewhere. */
|
|
21
21
|
readonly claim?: OutboxClaimStrategy;
|
|
22
|
+
/**
|
|
23
|
+
* Writes the tenant of each event to `tenant_id`, which `createOutboxTables(knex, { tenant:
|
|
24
|
+
* true })` or `addOutboxTenantColumn` created: its consumers then run in that tenant. Default
|
|
25
|
+
* false, for a table without the column. A table that has it is read back either way.
|
|
26
|
+
*/
|
|
27
|
+
readonly tenant?: boolean;
|
|
22
28
|
}
|
|
23
29
|
/**
|
|
24
30
|
* The outbox in a SQL database. `append` runs on the executor of the context: called inside a
|
|
@@ -31,6 +37,7 @@ export declare class KnexOutboxStore implements OutboxStore {
|
|
|
31
37
|
private readonly tableName;
|
|
32
38
|
private readonly leaseDurationMs;
|
|
33
39
|
private readonly claimStrategy;
|
|
40
|
+
private readonly tenant;
|
|
34
41
|
constructor(context: KnexContext, options?: KnexOutboxStoreOptions);
|
|
35
42
|
append(events: readonly IntegrationEvent[]): Promise<void>;
|
|
36
43
|
claimBatch(limit: number, now: Date): Promise<OutboxRecord[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knex-outbox-store.d.ts","sourceRoot":"","sources":["../../src/outbox/knex-outbox-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAgB,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAG/F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGnE;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,iBAAiB,CAAC;AAEpE,MAAM,WAAW,sBAAsB;IACrC,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"knex-outbox-store.d.ts","sourceRoot":"","sources":["../../src/outbox/knex-outbox-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAgB,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAG/F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGnE;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,iBAAiB,CAAC;AAEpE,MAAM,WAAW,sBAAsB;IACrC,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAwBD;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IAEtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAEhD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAEhE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IAEjC,YAAY,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,sBAA2B,EAOrE;IAEK,MAAM,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB/D;IAEK,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAqBlE;IAEK,aAAa,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnE;IAEK,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,aAAa,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CASxG;IAEK,SAAS,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CASlE;IAEK,cAAc,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAKlD;IAEK,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,CAclC;IAED;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;;;OAIG;YACW,oBAAoB;IA2BlC,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,GAAG;IASX,OAAO,CAAC,KAAK;CAMd"}
|
|
@@ -13,12 +13,14 @@ export class KnexOutboxStore {
|
|
|
13
13
|
tableName;
|
|
14
14
|
leaseDurationMs;
|
|
15
15
|
claimStrategy;
|
|
16
|
+
tenant;
|
|
16
17
|
constructor(context, options = {}) {
|
|
17
18
|
this.context = context;
|
|
18
19
|
this.schemaName = options.schema;
|
|
19
20
|
this.tableName = options.table ?? OUTBOX_TABLE;
|
|
20
21
|
this.leaseDurationMs = options.leaseMs ?? 30_000;
|
|
21
22
|
this.claimStrategy = options.claim;
|
|
23
|
+
this.tenant = options.tenant ?? false;
|
|
22
24
|
}
|
|
23
25
|
async append(events) {
|
|
24
26
|
if (events.length === 0) {
|
|
@@ -33,6 +35,7 @@ export class KnexOutboxStore {
|
|
|
33
35
|
payload: event.payload === undefined ? null : JSON.stringify(event.payload),
|
|
34
36
|
traceparent: event.traceparent ?? null,
|
|
35
37
|
correlation_id: event.correlationId ?? null,
|
|
38
|
+
...(this.tenant ? { tenant_id: event.tenantId ?? null } : {}),
|
|
36
39
|
next_attempt_at: DUE_IMMEDIATELY,
|
|
37
40
|
})));
|
|
38
41
|
}
|
|
@@ -170,6 +173,7 @@ function toRecord(row, dialect) {
|
|
|
170
173
|
payload,
|
|
171
174
|
...(row.traceparent === null ? {} : { traceparent: row.traceparent }),
|
|
172
175
|
...(row.correlation_id === null ? {} : { correlationId: row.correlation_id }),
|
|
176
|
+
...(typeof row.tenant_id === 'string' ? { tenantId: row.tenant_id } : {}),
|
|
173
177
|
},
|
|
174
178
|
status: row.status,
|
|
175
179
|
attempts: row.attempts,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knex-outbox-store.js","sourceRoot":"","sources":["../../src/outbox/knex-outbox-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"knex-outbox-store.js","sourceRoot":"","sources":["../../src/outbox/knex-outbox-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAgDhD,mEAAmE;AACnE,MAAM,eAAe,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;AAEpC;;;;GAIG;AACH,MAAM,OAAO,eAAe;IACT,OAAO,CAAc;IAErB,UAAU,CAAqB;IAE/B,SAAS,CAAS;IAElB,eAAe,CAAS;IAExB,aAAa,CAAkC;IAE/C,MAAM,CAAU;IAEjC,YAAY,OAAoB,EAAE,OAAO,GAA2B,EAAE;QACpE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;QAC/C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAmC;QAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAC7C,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACrB,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,WAAW,EAAE,KAAK,CAAC,UAAU;YAC7B,8EAA8E;YAC9E,OAAO,EAAE,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;YAC3E,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;YACtC,cAAc,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI;YAC3C,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,eAAe,EAAE,eAAe;SACjC,CAAC,CAAC,CACJ,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAa,EAAE,GAAS;QACvC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEpC,MAAM,QAAQ,GACZ,IAAI,CAAC,aAAa,IAAI,CAAC,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAE5G,MAAM,OAAO,GACX,QAAQ,KAAK,aAAa;YACxB,CAAC,CAAC,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC;YACtD,CAAC,CAAC,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAE5D,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;QAEnE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACzB,QAAQ,CAAC,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,eAAe,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,CACxF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAsB,EAAE,EAAQ;QAClD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;aACrC,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;aACvB,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,KAAgC,EAAE,aAA0B;QACvF,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;aACrC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;aACb,QAAQ,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;aACjC,MAAM,CACL,aAAa,KAAK,IAAI;YACpB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,IAAI,EAAE;YACjD,CAAC,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,KAAK,CAAC,IAAI,EAAE,CACpE,CAAC;IACN,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAsB,EAAE,GAAS;QAC/C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;aACtC,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;aACvB,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;aACzB,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,MAAY;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;aACtC,KAAK,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;aAC9B,KAAK,CAAC,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC;aAClC,MAAM,EAAE,CAAC;IACd,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEzC,kDAAkD;QAClD,MAAM,KAAK,GAAG,CAAC,SAAiB,EAAE,KAAa,EAAE,EAAE,CACjD,QAAQ,CAAC,GAAG,CAAC,iBAAiB,SAAS,2BAA2B,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAE/E,MAAM,GAAG,GAAY,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAClD,KAAK,CAAC,oBAAoB,EAAE,SAAS,CAAC,EACtC,KAAK,CAAC,oDAAoD,EAAE,QAAQ,CAAC,EACrE,KAAK,CAAC,iBAAiB,EAAE,MAAM,CAAC,CACjC,CAAC;QAEF,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;IAC1G,CAAC;IAED;;;;;OAKG;IACK,mBAAmB,CAAC,QAAc,EAAE,KAAa,EAAE,GAAS;QAClE,OAAO,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE;YAChD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,UAAU,EAAE,CAAC;YAE7E,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnB,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;qBACzB,OAAO,CACN,IAAI,EACJ,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CACzB;qBACA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;YAC1C,CAAC;YAED,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,oBAAoB,CAAC,QAAc,EAAE,KAAa,EAAE,GAAS;QACzE,MAAM,OAAO,GAAgB,EAAE,CAAC;QAEhC,OAAO,OAAO,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;YACtC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YAElD,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;gBACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;qBACpC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;qBAChE,KAAK,CAAC,iBAAiB,EAAE,IAAI,EAAE,GAAG,CAAC;qBACnC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;gBAErC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;oBAChB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;YAED,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;gBACxB,2EAA2E;gBAC3E,MAAM;YACR,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,IAAI,CAAC,QAAc;QACzB,MAAM,KAAK,GAAG,QAAQ,CAAyB,IAAI,CAAC,SAAS,CAAC,CAAC;QAE/D,OAAO,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnF,CAAC;IAEO,GAAG,CAAC,QAAc,EAAE,KAAa,EAAE,GAAS;QAClD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;aACvB,MAAM,CAAC,GAAG,CAAC;aACX,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;aAC5B,KAAK,CAAC,iBAAiB,EAAE,IAAI,EAAE,GAAG,CAAC;aACnC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;aAChE,KAAK,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,QAAc,EAAE,GAAS;QACrC,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,CAAC;YAC9C,eAAe,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC;SAChE,CAAC;IACJ,CAAC;CACF;AAED,8FAA8F;AAC9F,SAAS,OAAO,CAAC,GAAY,EAAE,MAAc;IAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,KAAK,GAAY,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhF,OAAO,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,QAAQ,CAAC,GAAc,EAAE,OAAmB;IACnD,2FAA2F;IAC3F,sFAAsF;IACtF,MAAM,OAAO,GACX,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IAElG,OAAO;QACL,KAAK,EAAE;YACL,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,UAAU,EAAE,GAAG,CAAC,WAAW;YAC3B,OAAO;YACP,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC;YACrE,GAAG,CAAC,GAAG,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,cAAc,EAAE,CAAC;YAC7E,GAAG,CAAC,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1E;QACD,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC;QAC1C,GAAG,CAAC,GAAG,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC;QAC/E,GAAG,CAAC,GAAG,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;KAChF,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,KAA6B;IAC3C,OAAO,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -8,5 +8,7 @@ export interface OutboxTablesOptions {
|
|
|
8
8
|
readonly outboxTable?: string;
|
|
9
9
|
/** Default `processed_events`. */
|
|
10
10
|
readonly processedEventsTable?: string;
|
|
11
|
+
/** Adds `tenant_id` to the outbox, for a multi-tenant project: pair it with `KnexOutboxStore`'s `tenant`. Default false. */
|
|
12
|
+
readonly tenant?: boolean;
|
|
11
13
|
}
|
|
12
14
|
//# sourceMappingURL=outbox-tables-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbox-tables-options.d.ts","sourceRoot":"","sources":["../../src/outbox/outbox-tables-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kCAAkC;IAClC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"outbox-tables-options.d.ts","sourceRoot":"","sources":["../../src/outbox/outbox-tables-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kCAAkC;IAClC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,4HAA4H;IAC5H,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ExecutionScope } from '@ddd-ts-kit/kernel';
|
|
1
2
|
export interface KnexReadModelOptions<Row> {
|
|
2
3
|
readonly table: string;
|
|
3
4
|
/** The schema of the context. Default: the default schema of the connection. */
|
|
@@ -6,5 +7,15 @@ export interface KnexReadModelOptions<Row> {
|
|
|
6
7
|
readonly keyColumn?: string;
|
|
7
8
|
/** The column of every field of the row: `{ startsAt: 'starts_at' }`. */
|
|
8
9
|
readonly columns: Readonly<Record<keyof Row & string, string>>;
|
|
10
|
+
/**
|
|
11
|
+
* For a read model of tenant data: every row is written with the tenant of the work in
|
|
12
|
+
* progress (`tenant_id`, which `tenantColumn` adds) and every read and write is confined to it,
|
|
13
|
+
* an elevation widening the reads only. Keys stay unique across tenants (the conflict of an
|
|
14
|
+
* insert is on the key alone): a key that two tenants could share (a day, a slug) is a
|
|
15
|
+
* generated id, or carries the tenant (`acme:2026-03-01`), otherwise the second tenant's
|
|
16
|
+
* insert is ignored and its event ends in a conflict. Absent: one read model for every tenant,
|
|
17
|
+
* as before.
|
|
18
|
+
*/
|
|
19
|
+
readonly tenant?: ExecutionScope;
|
|
9
20
|
}
|
|
10
21
|
//# sourceMappingURL=knex-read-model-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knex-read-model-options.d.ts","sourceRoot":"","sources":["../../src/read-model/knex-read-model-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB,CAAC,GAAG;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"knex-read-model-options.d.ts","sourceRoot":"","sources":["../../src/read-model/knex-read-model-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,oBAAoB,CAAC,GAAG;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/D;;;;;;;;OAQG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;CAClC"}
|
|
@@ -38,7 +38,7 @@ export class KnexReadModelTable {
|
|
|
38
38
|
async search(plan) {
|
|
39
39
|
const { columns } = this.options;
|
|
40
40
|
const mapper = new RowMapper(columns);
|
|
41
|
-
const kept = () => this.rows.
|
|
41
|
+
const kept = () => this.rows.reading().where('deleted', false);
|
|
42
42
|
const answered = await criteriaToKnex(kept().select(Object.values(columns)), plan, columns);
|
|
43
43
|
const rows = recordsOf(answered).map((record) => mapper.toRow(record));
|
|
44
44
|
if (plan.kind === 'cursor') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knex-read-model-table.js","sourceRoot":"","sources":["../../src/read-model/knex-read-model-table.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,GAQzB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;GAIG;AACH,MAAM,OAAO,kBAAkB;IAQV,OAAO;IACP,OAAO;IART,IAAI,CAAuB;IAE3B,IAAI,CAAuB;IAE3B,OAAO,CAA2B;IAEnD,YACmB,OAAoB,EACpB,OAAkC;uBADlC,OAAO;uBACP,OAAO;QAExB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAElC,IAAI,CAAC,IAAI,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAE1G,IAAI,CAAC,OAAO,GAAG,IAAI,wBAAwB,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE;YACtG,KAAK;YACL,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,GAAW;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,KAAsB;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,KAAsB,EAAE,IAAgB;QAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAkB;QAC7B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAM,OAAO,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"knex-read-model-table.js","sourceRoot":"","sources":["../../src/read-model/knex-read-model-table.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Knex } from 'knex';
|
|
2
|
-
import type
|
|
2
|
+
import { type EventStamp, type ReadModelRows, type StampedRow } from '@ddd-ts-kit/kernel';
|
|
3
3
|
import type { KnexContext } from '../unit-of-work/knex-context.js';
|
|
4
4
|
import type { KnexReadModelOptions } from './knex-read-model-options.js';
|
|
5
5
|
/** The stamped rows of one table, the copy of a rebuild as well as the table itself. */
|
|
@@ -13,6 +13,9 @@ export declare class KnexStampedRows<Row extends object> implements ReadModelRow
|
|
|
13
13
|
replace(entry: StampedRow<Row>, held: EventStamp): Promise<boolean>;
|
|
14
14
|
/** The table, on the executor of the current unit of work. */
|
|
15
15
|
table(): Knex.QueryBuilder;
|
|
16
|
+
/** What a read may reach: the table, confined to the tenant when the read model is of tenant data. */
|
|
17
|
+
reading(): Knex.QueryBuilder;
|
|
18
|
+
private writing;
|
|
16
19
|
private recordOf;
|
|
17
20
|
private keyColumn;
|
|
18
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knex-stamped-rows.d.ts","sourceRoot":"","sources":["../../src/read-model/knex-stamped-rows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"knex-stamped-rows.d.ts","sourceRoot":"","sources":["../../src/read-model/knex-stamped-rows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAiB,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGzG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAIzE,wFAAwF;AACxF,qBAAa,eAAe,CAAC,GAAG,SAAS,MAAM,CAAE,YAAW,aAAa,CAAC,GAAG,CAAC;IAI1E,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IAExC,YACmB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,oBAAoB,CAAC,GAAG,CAAC,EAGpD;IAEK,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAmB5D;IAEK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CASrD;IAEK,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAQxE;IAED,8DAA8D;IAC9D,KAAK,IAAI,IAAI,CAAC,YAAY,CAKzB;IAED,sGAAsG;IACtG,OAAO,IAAI,IAAI,CAAC,YAAY,CAI3B;IAED,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,SAAS;CAGlB"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { tenantScopeOf } from '@ddd-ts-kit/kernel';
|
|
1
2
|
import { insertIgnoringConflict } from '../sql/insert-ignoring-conflict.js';
|
|
3
|
+
import { TENANT_COLUMN, whereTenant } from '../tenancy/where-tenant.js';
|
|
2
4
|
import { recordsOf } from './records-of.js';
|
|
3
5
|
import { RowMapper } from './row.mapper.js';
|
|
4
6
|
/** The stamped rows of one table, the copy of a rebuild as well as the table itself. */
|
|
@@ -12,7 +14,7 @@ export class KnexStampedRows {
|
|
|
12
14
|
this.mapper = new RowMapper(options.columns);
|
|
13
15
|
}
|
|
14
16
|
async find(key) {
|
|
15
|
-
const answered = await this.
|
|
17
|
+
const answered = await this.reading().where(this.keyColumn(), key).limit(1);
|
|
16
18
|
const [record] = recordsOf(answered);
|
|
17
19
|
if (record === undefined) {
|
|
18
20
|
return undefined;
|
|
@@ -38,7 +40,7 @@ export class KnexStampedRows {
|
|
|
38
40
|
});
|
|
39
41
|
}
|
|
40
42
|
async replace(entry, held) {
|
|
41
|
-
const replaced = await this.
|
|
43
|
+
const replaced = await this.writing()
|
|
42
44
|
.where(this.keyColumn(), entry.key)
|
|
43
45
|
.where('last_event_id', held.eventId)
|
|
44
46
|
.where('last_event_at', held.occurredAt)
|
|
@@ -51,9 +53,20 @@ export class KnexStampedRows {
|
|
|
51
53
|
const builder = this.context.executor()(table);
|
|
52
54
|
return schema === undefined ? builder : builder.withSchema(schema);
|
|
53
55
|
}
|
|
56
|
+
/** What a read may reach: the table, confined to the tenant when the read model is of tenant data. */
|
|
57
|
+
reading() {
|
|
58
|
+
const { tenant } = this.options;
|
|
59
|
+
return tenant === undefined ? this.table() : whereTenant(this.table(), tenant);
|
|
60
|
+
}
|
|
61
|
+
writing() {
|
|
62
|
+
const { tenant } = this.options;
|
|
63
|
+
return tenant === undefined ? this.table() : this.table().where(TENANT_COLUMN, tenantScopeOf(tenant).tenantId);
|
|
64
|
+
}
|
|
54
65
|
recordOf({ key, row, stamp }) {
|
|
66
|
+
const { tenant } = this.options;
|
|
55
67
|
return {
|
|
56
68
|
...(row === undefined ? {} : this.mapper.toRecord(row)),
|
|
69
|
+
...(tenant === undefined ? {} : { [TENANT_COLUMN]: tenantScopeOf(tenant).tenantId }),
|
|
57
70
|
[this.keyColumn()]: key,
|
|
58
71
|
last_event_id: stamp.eventId,
|
|
59
72
|
last_event_at: stamp.occurredAt,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knex-stamped-rows.js","sourceRoot":"","sources":["../../src/read-model/knex-stamped-rows.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"knex-stamped-rows.js","sourceRoot":"","sources":["../../src/read-model/knex-stamped-rows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
import { type ExecutionScope } from '@ddd-ts-kit/kernel';
|
|
3
|
+
import type { KnexUnitOfWork } from '../unit-of-work/create-knex-unit-of-work.js';
|
|
4
|
+
import type { TenantDatabases } from './tenant-databases.js';
|
|
5
|
+
/**
|
|
6
|
+
* The unit of work of the database-per-tenant strategy: each transaction opens on the database
|
|
7
|
+
* of the tenant of the work in progress, holding a lease on it until it ends, and `executor()`
|
|
8
|
+
* answers that transaction. Every statement runs inside `run` (`StatementOutsideUnitOfWorkError`
|
|
9
|
+
* otherwise), work that names no tenant reaches no database (`NoCurrentTenantError`), and work
|
|
10
|
+
* of another tenant never joins an open transaction (`CrossTenantUnitOfWorkError`).
|
|
11
|
+
*/
|
|
12
|
+
export declare function createTenantRoutedUnitOfWork(databases: TenantDatabases, scope: ExecutionScope, config?: Knex.TransactionConfig): KnexUnitOfWork;
|
|
13
|
+
//# sourceMappingURL=create-tenant-routed-unit-of-work.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-tenant-routed-unit-of-work.d.ts","sourceRoot":"","sources":["../../src/tenancy/create-tenant-routed-unit-of-work.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAGlF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQ7D;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,cAAc,EACrB,MAAM,CAAC,EAAE,IAAI,CAAC,iBAAiB,GAC9B,cAAc,CA+BhB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { tenantScopeOf, withinUnitOfWork } from '@ddd-ts-kit/kernel';
|
|
3
|
+
import { CrossTenantUnitOfWorkError } from './cross-tenant-unit-of-work-error.js';
|
|
4
|
+
import { StatementOutsideUnitOfWorkError } from './statement-outside-unit-of-work-error.js';
|
|
5
|
+
/**
|
|
6
|
+
* The unit of work of the database-per-tenant strategy: each transaction opens on the database
|
|
7
|
+
* of the tenant of the work in progress, holding a lease on it until it ends, and `executor()`
|
|
8
|
+
* answers that transaction. Every statement runs inside `run` (`StatementOutsideUnitOfWorkError`
|
|
9
|
+
* otherwise), work that names no tenant reaches no database (`NoCurrentTenantError`), and work
|
|
10
|
+
* of another tenant never joins an open transaction (`CrossTenantUnitOfWorkError`).
|
|
11
|
+
*/
|
|
12
|
+
export function createTenantRoutedUnitOfWork(databases, scope, config) {
|
|
13
|
+
const current = new AsyncLocalStorage();
|
|
14
|
+
return {
|
|
15
|
+
run(work) {
|
|
16
|
+
return withinUnitOfWork(work, (scoped) => {
|
|
17
|
+
const { tenantId } = tenantScopeOf(scope);
|
|
18
|
+
const open = current.getStore();
|
|
19
|
+
if (open !== undefined) {
|
|
20
|
+
return open.tenantId === tenantId
|
|
21
|
+
? scoped()
|
|
22
|
+
: Promise.reject(new CrossTenantUnitOfWorkError(open.tenantId, tenantId));
|
|
23
|
+
}
|
|
24
|
+
return databases.lease(tenantId, (database) => database.transaction((transaction) => current.run({ transaction, tenantId }, scoped), config));
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
executor: () => {
|
|
28
|
+
const open = current.getStore();
|
|
29
|
+
if (open === undefined) {
|
|
30
|
+
throw new StatementOutsideUnitOfWorkError();
|
|
31
|
+
}
|
|
32
|
+
return open.transaction;
|
|
33
|
+
},
|
|
34
|
+
inTransaction: () => current.getStore() !== undefined,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=create-tenant-routed-unit-of-work.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-tenant-routed-unit-of-work.js","sourceRoot":"","sources":["../../src/tenancy/create-tenant-routed-unit-of-work.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAuB,MAAM,oBAAoB,CAAC;AAE1F,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAAE,+BAA+B,EAAE,MAAM,2CAA2C,CAAC;AAS5F;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAC1C,SAA0B,EAC1B,KAAqB,EACrB,MAA+B;IAE/B,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAmB,CAAC;IAEzD,OAAO;QACL,GAAG,CAAI,IAAsB;YAC3B,OAAO,gBAAgB,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE;gBACvC,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAEhC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;wBAC/B,CAAC,CAAC,MAAM,EAAE;wBACV,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;gBAC9E,CAAC;gBAED,OAAO,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAC5C,QAAQ,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAC9F,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QACD,QAAQ,EAAE,GAAG,EAAE;YACb,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;YAEhC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,IAAI,+BAA+B,EAAE,CAAC;YAC9C,CAAC;YAED,OAAO,IAAI,CAAC,WAAW,CAAC;QAC1B,CAAC;QACD,aAAa,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,SAAS;KACtD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Work of one tenant run inside the open unit of work of another: it would join that tenant's
|
|
3
|
+
* transaction (its database, its settings). One unit of work never spans tenants.
|
|
4
|
+
*/
|
|
5
|
+
export declare class CrossTenantUnitOfWorkError extends Error {
|
|
6
|
+
constructor(open: string, requested: string);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=cross-tenant-unit-of-work-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-tenant-unit-of-work-error.d.ts","sourceRoot":"","sources":["../../src/tenancy/cross-tenant-unit-of-work-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,YAAY,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAM1C;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Work of one tenant run inside the open unit of work of another: it would join that tenant's
|
|
3
|
+
* transaction (its database, its settings). One unit of work never spans tenants.
|
|
4
|
+
*/
|
|
5
|
+
export class CrossTenantUnitOfWorkError extends Error {
|
|
6
|
+
constructor(open, requested) {
|
|
7
|
+
super(`A unit of work of tenant "${open}" cannot run work of tenant "${requested}": open a unit of work per tenant`);
|
|
8
|
+
this.name = 'CrossTenantUnitOfWorkError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=cross-tenant-unit-of-work-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-tenant-unit-of-work-error.js","sourceRoot":"","sources":["../../src/tenancy/cross-tenant-unit-of-work-error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,YAAY,IAAY,EAAE,SAAiB;QACzC,KAAK,CACH,6BAA6B,IAAI,gCAAgC,SAAS,mCAAmC,CAC9G,CAAC;QAEF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF"}
|