@ddd-ts-kit/kernel 0.6.0 → 0.8.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/LICENSE +21 -0
- package/README.md +44 -11
- package/dist/application/audit/tenant-scope-of.d.ts +4 -1
- package/dist/application/audit/tenant-scope-of.d.ts.map +1 -1
- package/dist/application/audit/tenant-scope-of.js +6 -2
- package/dist/application/audit/tenant-scope-of.js.map +1 -1
- package/dist/application/cache/tenant-cache-key.d.ts +5 -0
- package/dist/application/cache/tenant-cache-key.d.ts.map +1 -0
- package/dist/application/cache/tenant-cache-key.js +7 -0
- package/dist/application/cache/tenant-cache-key.js.map +1 -0
- package/dist/application/events/execution-context-of-event.d.ts +2 -1
- package/dist/application/events/execution-context-of-event.d.ts.map +1 -1
- package/dist/application/events/execution-context-of-event.js +3 -1
- package/dist/application/events/execution-context-of-event.js.map +1 -1
- package/dist/application/events/integration-event.d.ts +6 -0
- package/dist/application/events/integration-event.d.ts.map +1 -1
- package/dist/application/events/scoped-publisher.d.ts +4 -3
- package/dist/application/events/scoped-publisher.d.ts.map +1 -1
- package/dist/application/events/scoped-publisher.js +11 -5
- package/dist/application/events/scoped-publisher.js.map +1 -1
- package/dist/application/execution/execution-context.d.ts +7 -1
- package/dist/application/execution/execution-context.d.ts.map +1 -1
- package/dist/application/execution/execution-context.js +7 -2
- package/dist/application/execution/execution-context.js.map +1 -1
- package/dist/application/execution/log-fields-of.d.ts.map +1 -1
- package/dist/application/execution/log-fields-of.js +1 -0
- package/dist/application/execution/log-fields-of.js.map +1 -1
- package/dist/application/ports/tenant-directory.d.ts +8 -0
- package/dist/application/ports/tenant-directory.d.ts.map +1 -0
- package/dist/application/ports/tenant-directory.js +10 -0
- package/dist/application/ports/tenant-directory.js.map +1 -0
- package/dist/application/scheduling/execution-context-of-job.d.ts +3 -1
- package/dist/application/scheduling/execution-context-of-job.d.ts.map +1 -1
- package/dist/application/scheduling/execution-context-of-job.js +1 -1
- package/dist/application/scheduling/execution-context-of-job.js.map +1 -1
- package/dist/application/scheduling/job-execution.d.ts +2 -0
- package/dist/application/scheduling/job-execution.d.ts.map +1 -1
- package/dist/application/scheduling/job-options.d.ts +6 -0
- package/dist/application/scheduling/job-options.d.ts.map +1 -1
- package/dist/application/scheduling/job-policy.d.ts.map +1 -1
- package/dist/application/scheduling/job-policy.js +4 -2
- package/dist/application/scheduling/job-policy.js.map +1 -1
- package/dist/application/session/has-scope.d.ts +5 -0
- package/dist/application/session/has-scope.d.ts.map +1 -0
- package/dist/application/session/has-scope.js +5 -0
- package/dist/application/session/has-scope.js.map +1 -0
- package/dist/application/session/session-scope.d.ts +4 -0
- package/dist/application/session/session-scope.d.ts.map +1 -0
- package/dist/application/session/session-scope.js +2 -0
- package/dist/application/session/session-scope.js.map +1 -0
- package/dist/application/session/session-scopes.d.ts +11 -0
- package/dist/application/session/session-scopes.d.ts.map +1 -0
- package/dist/application/session/session-scopes.js +2 -0
- package/dist/application/session/session-scopes.js.map +1 -0
- package/dist/application/session/session.d.ts +6 -0
- package/dist/application/session/session.d.ts.map +1 -1
- package/dist/application/tenancy/across-tenants.d.ts +12 -0
- package/dist/application/tenancy/across-tenants.d.ts.map +1 -0
- package/dist/application/tenancy/across-tenants.js +47 -0
- package/dist/application/tenancy/across-tenants.js.map +1 -0
- package/dist/application/tenancy/assert-tenant-id.d.ts +3 -0
- package/dist/application/tenancy/assert-tenant-id.d.ts.map +1 -0
- package/dist/application/tenancy/assert-tenant-id.js +10 -0
- package/dist/application/tenancy/assert-tenant-id.js.map +1 -0
- package/dist/application/tenancy/elevation-options.d.ts +12 -0
- package/dist/application/tenancy/elevation-options.d.ts.map +1 -0
- package/dist/application/tenancy/elevation-options.js +2 -0
- package/dist/application/tenancy/elevation-options.js.map +1 -0
- package/dist/application/tenancy/invalid-tenant-elevation-error.d.ts +5 -0
- package/dist/application/tenancy/invalid-tenant-elevation-error.d.ts.map +1 -0
- package/dist/application/tenancy/invalid-tenant-elevation-error.js +8 -0
- package/dist/application/tenancy/invalid-tenant-elevation-error.js.map +1 -0
- package/dist/application/tenancy/invalid-tenant-id-error.d.ts +6 -0
- package/dist/application/tenancy/invalid-tenant-id-error.d.ts.map +1 -0
- package/dist/application/tenancy/invalid-tenant-id-error.js +10 -0
- package/dist/application/tenancy/invalid-tenant-id-error.js.map +1 -0
- package/dist/application/tenancy/is-tenant-id.d.ts +3 -0
- package/dist/application/tenancy/is-tenant-id.d.ts.map +1 -0
- package/dist/application/tenancy/is-tenant-id.js +12 -0
- package/dist/application/tenancy/is-tenant-id.js.map +1 -0
- package/dist/application/tenancy/is-tenant-member.d.ts +4 -0
- package/dist/application/tenancy/is-tenant-member.d.ts.map +1 -0
- package/dist/application/tenancy/is-tenant-member.js +6 -0
- package/dist/application/tenancy/is-tenant-member.js.map +1 -0
- package/dist/application/tenancy/tenant-elevation.d.ts +11 -0
- package/dist/application/tenancy/tenant-elevation.d.ts.map +1 -0
- package/dist/application/tenancy/tenant-elevation.js +2 -0
- package/dist/application/tenancy/tenant-elevation.js.map +1 -0
- package/dist/application/tenancy/tenant-key.d.ts +9 -0
- package/dist/application/tenancy/tenant-key.d.ts.map +1 -0
- package/dist/application/tenancy/tenant-key.js +11 -0
- package/dist/application/tenancy/tenant-key.js.map +1 -0
- package/dist/application/tenancy/tenant-reach-of.d.ts +9 -0
- package/dist/application/tenancy/tenant-reach-of.d.ts.map +1 -0
- package/dist/application/tenancy/tenant-reach-of.js +18 -0
- package/dist/application/tenancy/tenant-reach-of.js.map +1 -0
- package/dist/application/tenancy/tenant-reach.d.ts +12 -0
- package/dist/application/tenancy/tenant-reach.d.ts.map +1 -0
- package/dist/application/tenancy/tenant-reach.js +2 -0
- package/dist/application/tenancy/tenant-reach.js.map +1 -0
- package/dist/application/tenancy/tenants-of.d.ts +8 -0
- package/dist/application/tenancy/tenants-of.d.ts.map +1 -0
- package/dist/application/tenancy/tenants-of.js +14 -0
- package/dist/application/tenancy/tenants-of.js.map +1 -0
- package/dist/declarations/decorators/domain-event-handler.d.ts +3 -2
- package/dist/declarations/decorators/domain-event-handler.d.ts.map +1 -1
- package/dist/declarations/decorators/domain-event-handler.js +3 -2
- package/dist/declarations/decorators/domain-event-handler.js.map +1 -1
- package/dist/declarations/decorators/on.d.ts +1 -1
- package/dist/domain/value-object.d.ts +3 -2
- package/dist/domain/value-object.d.ts.map +1 -1
- package/dist/domain/value-object.js +3 -2
- package/dist/domain/value-object.js.map +1 -1
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/in-memory/in-memory-tenant-directory.d.ts +8 -0
- package/dist/infrastructure/in-memory/in-memory-tenant-directory.d.ts.map +1 -0
- package/dist/infrastructure/in-memory/in-memory-tenant-directory.js +12 -0
- package/dist/infrastructure/in-memory/in-memory-tenant-directory.js.map +1 -0
- package/dist/infrastructure/tenancy/tenant-isolation-policies.d.ts +13 -0
- package/dist/infrastructure/tenancy/tenant-isolation-policies.d.ts.map +1 -0
- package/dist/infrastructure/tenancy/tenant-isolation-policies.js +13 -0
- package/dist/infrastructure/tenancy/tenant-isolation-policies.js.map +1 -0
- package/dist/infrastructure/tenancy/tenant-policy-expressions.d.ts +11 -0
- package/dist/infrastructure/tenancy/tenant-policy-expressions.d.ts.map +1 -0
- package/dist/infrastructure/tenancy/tenant-policy-expressions.js +15 -0
- package/dist/infrastructure/tenancy/tenant-policy-expressions.js.map +1 -0
- package/dist/infrastructure/tenancy/tenant-setting-values.d.ts +13 -0
- package/dist/infrastructure/tenancy/tenant-setting-values.d.ts.map +1 -0
- package/dist/infrastructure/tenancy/tenant-setting-values.js +19 -0
- package/dist/infrastructure/tenancy/tenant-setting-values.js.map +1 -0
- package/dist/infrastructure/tenancy/tenant-settings.d.ts +13 -0
- package/dist/infrastructure/tenancy/tenant-settings.d.ts.map +1 -0
- package/dist/infrastructure/tenancy/tenant-settings.js +13 -0
- package/dist/infrastructure/tenancy/tenant-settings.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vocabulary of the scopes a project grants its clients, by declaration merging, so that a
|
|
3
|
+
* guard names only scopes that exist:
|
|
4
|
+
*
|
|
5
|
+
* declare module '@ddd-ts-kit/kernel' {
|
|
6
|
+
* interface SessionScopes { readonly 'invoices:read': true; readonly 'invoices:write': true }
|
|
7
|
+
* }
|
|
8
|
+
*/
|
|
9
|
+
export interface SessionScopes {
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=session-scopes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-scopes.d.ts","sourceRoot":"","sources":["../../../src/application/session/session-scopes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;CAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-scopes.js","sourceRoot":"","sources":["../../../src/application/session/session-scopes.ts"],"names":[],"mappings":""}
|
|
@@ -22,6 +22,12 @@ export interface Session {
|
|
|
22
22
|
/** IANA time zone, for example `Europe/Paris`. */
|
|
23
23
|
readonly timeZone?: string;
|
|
24
24
|
readonly client?: SessionClient;
|
|
25
|
+
/**
|
|
26
|
+
* What the credential allows whoever presents it (the OAuth 2.0 `scope` of the token): a
|
|
27
|
+
* limit on the client, checked at the edge (`HasScope`), never what the actor may do, which
|
|
28
|
+
* stays a permission of the use case. Absent when the credential carries none.
|
|
29
|
+
*/
|
|
30
|
+
readonly scopes?: readonly string[];
|
|
25
31
|
readonly extensions: SessionExtensionValues;
|
|
26
32
|
}
|
|
27
33
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/application/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IACzD,kFAAkF;IAClF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gDAAgD;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;CAC7C"}
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/application/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IACzD,kFAAkF;IAClF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gDAAgD;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;CAC7C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ElevationOptions } from './elevation-options.js';
|
|
2
|
+
import type { TenantElevation } from './tenant-elevation.js';
|
|
3
|
+
/** The action of the audit entry an elevation writes. */
|
|
4
|
+
export declare const TENANT_ELEVATION_ACTION = "tenancy:elevate";
|
|
5
|
+
/**
|
|
6
|
+
* Runs `work` with reads widened to the tenants of `elevation`, for platform staff. Never
|
|
7
|
+
* implicit: the platform calls it after the permission to elevate was decided, and the
|
|
8
|
+
* elevation is written to the audit trail before the work starts; a trail that fails refuses
|
|
9
|
+
* the elevation. Writes still name one tenant (`tenantScopeOf`).
|
|
10
|
+
*/
|
|
11
|
+
export declare function acrossTenants<T>(options: ElevationOptions, elevation: TenantElevation, work: () => Promise<T>): Promise<T>;
|
|
12
|
+
//# sourceMappingURL=across-tenants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"across-tenants.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/across-tenants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,yDAAyD;AACzD,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAEzD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,CAAC,CAQZ"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { InvalidTenantElevationError } from './invalid-tenant-elevation-error.js';
|
|
2
|
+
import { isTenantId } from './is-tenant-id.js';
|
|
3
|
+
/** The action of the audit entry an elevation writes. */
|
|
4
|
+
export const TENANT_ELEVATION_ACTION = 'tenancy:elevate';
|
|
5
|
+
/**
|
|
6
|
+
* Runs `work` with reads widened to the tenants of `elevation`, for platform staff. Never
|
|
7
|
+
* implicit: the platform calls it after the permission to elevate was decided, and the
|
|
8
|
+
* elevation is written to the audit trail before the work starts; a trail that fails refuses
|
|
9
|
+
* the elevation. Writes still name one tenant (`tenantScopeOf`).
|
|
10
|
+
*/
|
|
11
|
+
export async function acrossTenants(options, elevation, work) {
|
|
12
|
+
assertValid(elevation);
|
|
13
|
+
const context = options.scope.require();
|
|
14
|
+
await options.trail.record(elevationRecord(options, context, elevation));
|
|
15
|
+
return options.scope.run(Object.freeze({ ...context, elevation }), work);
|
|
16
|
+
}
|
|
17
|
+
function assertValid({ reason, tenants }) {
|
|
18
|
+
if (reason.trim() === '') {
|
|
19
|
+
throw new InvalidTenantElevationError('it names no reason');
|
|
20
|
+
}
|
|
21
|
+
if (tenants !== 'all' && tenants.length === 0) {
|
|
22
|
+
throw new InvalidTenantElevationError('it names no tenant');
|
|
23
|
+
}
|
|
24
|
+
if (tenants !== 'all' && !tenants.every(isTenantId)) {
|
|
25
|
+
throw new InvalidTenantElevationError('it names a tenant id outside the grammar of isTenantId');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function elevationRecord(options, context, elevation) {
|
|
29
|
+
const { tenantId, session } = context;
|
|
30
|
+
return {
|
|
31
|
+
id: options.ids.next(),
|
|
32
|
+
occurredAt: options.clock.now(),
|
|
33
|
+
category: 'authorization',
|
|
34
|
+
action: TENANT_ELEVATION_ACTION,
|
|
35
|
+
outcome: 'allowed',
|
|
36
|
+
reason: elevation.reason,
|
|
37
|
+
actor: { id: context.actor.id, type: context.actor.type },
|
|
38
|
+
resource: { type: 'tenants', id: elevation.tenants === 'all' ? '*' : elevation.tenants.join(',') },
|
|
39
|
+
correlationId: context.correlationId,
|
|
40
|
+
origin: context.origin,
|
|
41
|
+
...(tenantId === undefined ? {} : { tenantId }),
|
|
42
|
+
...(session === undefined ? {} : { sessionId: session.id }),
|
|
43
|
+
...(session?.impersonatedBy === undefined ? {} : { impersonatedBy: session.impersonatedBy }),
|
|
44
|
+
...(context.causationId === undefined ? {} : { causationId: context.causationId }),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=across-tenants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"across-tenants.js","sourceRoot":"","sources":["../../../src/application/tenancy/across-tenants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-tenant-id.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/assert-tenant-id.ts"],"names":[],"mappings":"AAGA,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMvD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { InvalidTenantIdError } from './invalid-tenant-id-error.js';
|
|
2
|
+
import { isTenantId } from './is-tenant-id.js';
|
|
3
|
+
/** The tenant id as it came in, refused (`InvalidTenantIdError`) when it is outside the grammar of `isTenantId`. */
|
|
4
|
+
export function assertTenantId(tenantId) {
|
|
5
|
+
if (!isTenantId(tenantId)) {
|
|
6
|
+
throw new InvalidTenantIdError(tenantId);
|
|
7
|
+
}
|
|
8
|
+
return tenantId;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=assert-tenant-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-tenant-id.js","sourceRoot":"","sources":["../../../src/application/tenancy/assert-tenant-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,oHAAoH;AACpH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AuditTrail } from '../ports/audit-trail.js';
|
|
2
|
+
import type { Clock } from '../ports/clock.js';
|
|
3
|
+
import type { ExecutionScope } from '../ports/execution-scope.js';
|
|
4
|
+
import type { IdGenerator } from '../ports/id-generator.js';
|
|
5
|
+
/** What `acrossTenants` needs: the scope it widens, and the trail it records the elevation in. */
|
|
6
|
+
export interface ElevationOptions {
|
|
7
|
+
readonly scope: ExecutionScope;
|
|
8
|
+
readonly trail: AuditTrail;
|
|
9
|
+
readonly clock: Clock;
|
|
10
|
+
readonly ids: IdGenerator;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=elevation-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elevation-options.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/elevation-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,kGAAkG;AAClG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elevation-options.js","sourceRoot":"","sources":["../../../src/application/tenancy/elevation-options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalid-tenant-elevation-error.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/invalid-tenant-elevation-error.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,YAAY,MAAM,EAAE,MAAM,EAGzB;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** An elevation that names no reason or no tenant: refused before anything is recorded or run. */
|
|
2
|
+
export class InvalidTenantElevationError extends Error {
|
|
3
|
+
constructor(detail) {
|
|
4
|
+
super(`Invalid tenant elevation: ${detail}`);
|
|
5
|
+
this.name = 'InvalidTenantElevationError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=invalid-tenant-elevation-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalid-tenant-elevation-error.js","sourceRoot":"","sources":["../../../src/application/tenancy/invalid-tenant-elevation-error.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IACpD,YAAY,MAAc;QACxB,KAAK,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** A tenant id outside the grammar of `isTenantId`: refused where it comes in, never altered. */
|
|
2
|
+
export declare class InvalidTenantIdError extends Error {
|
|
3
|
+
readonly tenantId: string;
|
|
4
|
+
constructor(tenantId: string);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=invalid-tenant-id-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalid-tenant-id-error.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/invalid-tenant-id-error.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,qBAAa,oBAAqB,SAAQ,KAAK;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAArC,YAAqB,QAAQ,EAAE,MAAM,EAGpC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** A tenant id outside the grammar of `isTenantId`: refused where it comes in, never altered. */
|
|
2
|
+
export class InvalidTenantIdError extends Error {
|
|
3
|
+
tenantId;
|
|
4
|
+
constructor(tenantId) {
|
|
5
|
+
super(`Invalid tenant id ${JSON.stringify(tenantId.slice(0, 80))}: only letters, digits, "_" and "-", at most 63`);
|
|
6
|
+
this.tenantId = tenantId;
|
|
7
|
+
this.name = 'InvalidTenantIdError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=invalid-tenant-id-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalid-tenant-id-error.js","sourceRoot":"","sources":["../../../src/application/tenancy/invalid-tenant-id-error.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACxB,QAAQ;IAA7B,YAAqB,QAAgB;QACnC,KAAK,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,iDAAiD,CAAC,CAAC;wBADhG,QAAQ;QAE3B,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-tenant-id.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/is-tenant-id.ts"],"names":[],"mappings":"AAQA,sDAAsD;AACtD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE1D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one grammar of a tenant id, wherever a tenant comes in: letters, digits, `_` and `-`, at
|
|
3
|
+
* most 63 characters (what a slug or a UUID is made of). Nothing in it can be read as a list,
|
|
4
|
+
* a wildcard, a key separator or a part of an SQL identifier, so no tenant id can ever widen
|
|
5
|
+
* what another tenant reaches.
|
|
6
|
+
*/
|
|
7
|
+
const TENANT_ID = /^[A-Za-z0-9_-]{1,63}$/;
|
|
8
|
+
/** Whether a value is a tenant id of that grammar. */
|
|
9
|
+
export function isTenantId(value) {
|
|
10
|
+
return typeof value === 'string' && TENANT_ID.test(value);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=is-tenant-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-tenant-id.js","sourceRoot":"","sources":["../../../src/application/tenancy/is-tenant-id.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAE1C,sDAAsD;AACtD,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Actor } from '../actor/actor.js';
|
|
2
|
+
/** Whether the actor belongs to the tenant, as its credential says: `tenantId` or the `tenants` attribute. */
|
|
3
|
+
export declare function isTenantMember(actor: Actor, tenantId: string): boolean;
|
|
4
|
+
//# sourceMappingURL=is-tenant-member.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-tenant-member.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/is-tenant-member.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,8GAA8G;AAC9G,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtE"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { tenantsOf } from './tenants-of.js';
|
|
2
|
+
/** Whether the actor belongs to the tenant, as its credential says: `tenantId` or the `tenants` attribute. */
|
|
3
|
+
export function isTenantMember(actor, tenantId) {
|
|
4
|
+
return tenantsOf(actor).includes(tenantId);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=is-tenant-member.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-tenant-member.js","sourceRoot":"","sources":["../../../src/application/tenancy/is-tenant-member.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,8GAA8G;AAC9G,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,QAAgB;IAC3D,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform staff reaching tenants that are not theirs: said, never implied. Opened by
|
|
3
|
+
* `acrossTenants`, which records it in the audit trail before any work runs.
|
|
4
|
+
*/
|
|
5
|
+
export interface TenantElevation {
|
|
6
|
+
/** A stable code naming why (`SUPPORT_TICKET`, `BILLING_RECONCILIATION`), never a sentence: it is audited. */
|
|
7
|
+
readonly reason: string;
|
|
8
|
+
/** The tenants the work may read: `all`, or the list. */
|
|
9
|
+
readonly tenants: 'all' | readonly string[];
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tenant-elevation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-elevation.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/tenant-elevation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,8GAA8G;IAC9G,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,KAAK,GAAG,SAAS,MAAM,EAAE,CAAC;CAC7C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-elevation.js","sourceRoot":"","sources":["../../../src/application/tenancy/tenant-elevation.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ExecutionScope } from '../ports/execution-scope.js';
|
|
2
|
+
/**
|
|
3
|
+
* A key of a shared store (a rate limit, a lock, a counter) confined to the tenant of the work
|
|
4
|
+
* in progress: `tenant:<id>:<segments>`, each segment percent-encoded so that no segment holds a
|
|
5
|
+
* `:` (`['a:b']` and `['a', 'b']` are two keys). Two tenants never share an entry, and work that
|
|
6
|
+
* names no tenant is refused instead of reaching a global entry by omission.
|
|
7
|
+
*/
|
|
8
|
+
export declare function tenantKey(scope: ExecutionScope, ...segments: readonly string[]): string;
|
|
9
|
+
//# sourceMappingURL=tenant-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-key.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/tenant-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAGlE;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEvF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { tenantScopeOf } from '../audit/tenant-scope-of.js';
|
|
2
|
+
/**
|
|
3
|
+
* A key of a shared store (a rate limit, a lock, a counter) confined to the tenant of the work
|
|
4
|
+
* in progress: `tenant:<id>:<segments>`, each segment percent-encoded so that no segment holds a
|
|
5
|
+
* `:` (`['a:b']` and `['a', 'b']` are two keys). Two tenants never share an entry, and work that
|
|
6
|
+
* names no tenant is refused instead of reaching a global entry by omission.
|
|
7
|
+
*/
|
|
8
|
+
export function tenantKey(scope, ...segments) {
|
|
9
|
+
return ['tenant', tenantScopeOf(scope).tenantId, ...segments.map(encodeURIComponent)].join(':');
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tenant-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-key.js","sourceRoot":"","sources":["../../../src/application/tenancy/tenant-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB,EAAE,GAAG,QAA2B;IAC7E,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClG,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ExecutionScope } from '../ports/execution-scope.js';
|
|
2
|
+
import type { TenantReach } from './tenant-reach.js';
|
|
3
|
+
/**
|
|
4
|
+
* For an adapter scoping a read: the tenants it may see. An elevation opened by `acrossTenants`
|
|
5
|
+
* widens it; otherwise it is the tenant of the work, and work that names none is refused, so
|
|
6
|
+
* that no read runs unscoped by omission. Writes keep `tenantScopeOf`: one tenant, always.
|
|
7
|
+
*/
|
|
8
|
+
export declare function tenantReachOf(scope: ExecutionScope): TenantReach;
|
|
9
|
+
//# sourceMappingURL=tenant-reach-of.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-reach-of.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/tenant-reach-of.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAYhE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NoCurrentTenantError } from '../audit/no-current-tenant-error.js';
|
|
2
|
+
import { assertTenantId } from './assert-tenant-id.js';
|
|
3
|
+
/**
|
|
4
|
+
* For an adapter scoping a read: the tenants it may see. An elevation opened by `acrossTenants`
|
|
5
|
+
* widens it; otherwise it is the tenant of the work, and work that names none is refused, so
|
|
6
|
+
* that no read runs unscoped by omission. Writes keep `tenantScopeOf`: one tenant, always.
|
|
7
|
+
*/
|
|
8
|
+
export function tenantReachOf(scope) {
|
|
9
|
+
const { tenantId, elevation } = scope.require();
|
|
10
|
+
if (elevation !== undefined) {
|
|
11
|
+
return { kind: 'elevated', tenants: elevation.tenants === 'all' ? 'all' : elevation.tenants.map(assertTenantId) };
|
|
12
|
+
}
|
|
13
|
+
if (tenantId === undefined) {
|
|
14
|
+
throw new NoCurrentTenantError();
|
|
15
|
+
}
|
|
16
|
+
return { kind: 'tenant', tenantId: assertTenantId(tenantId) };
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=tenant-reach-of.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-reach-of.js","sourceRoot":"","sources":["../../../src/application/tenancy/tenant-reach-of.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAqB;IACjD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAEhD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;IACpH,CAAC;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,oBAAoB,EAAE,CAAC;IACnC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a read may see: the one tenant of the work in progress, or, under an elevation, the
|
|
3
|
+
* tenants it names (`all` for every one).
|
|
4
|
+
*/
|
|
5
|
+
export type TenantReach = {
|
|
6
|
+
readonly kind: 'tenant';
|
|
7
|
+
readonly tenantId: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: 'elevated';
|
|
10
|
+
readonly tenants: 'all' | readonly string[];
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=tenant-reach.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-reach.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/tenant-reach.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,GAAG,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-reach.js","sourceRoot":"","sources":["../../../src/application/tenancy/tenant-reach.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Actor } from '../actor/actor.js';
|
|
2
|
+
/**
|
|
3
|
+
* The tenants an actor belongs to: its `tenantId`, and the `tenants` attribute for an actor
|
|
4
|
+
* that belongs to several (a consultant of two clinics). The authenticator fills both from
|
|
5
|
+
* the credential; nothing else may.
|
|
6
|
+
*/
|
|
7
|
+
export declare function tenantsOf(actor: Actor): readonly string[];
|
|
8
|
+
//# sourceMappingURL=tenants-of.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenants-of.d.ts","sourceRoot":"","sources":["../../../src/application/tenancy/tenants-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,MAAM,EAAE,CAKzD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tenants an actor belongs to: its `tenantId`, and the `tenants` attribute for an actor
|
|
3
|
+
* that belongs to several (a consultant of two clinics). The authenticator fills both from
|
|
4
|
+
* the credential; nothing else may.
|
|
5
|
+
*/
|
|
6
|
+
export function tenantsOf(actor) {
|
|
7
|
+
const listed = actor.attributes['tenants'];
|
|
8
|
+
const others = isTextList(listed) ? listed : [];
|
|
9
|
+
return [...new Set([...(actor.tenantId === undefined ? [] : [actor.tenantId]), ...others])];
|
|
10
|
+
}
|
|
11
|
+
function isTextList(value) {
|
|
12
|
+
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=tenants-of.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenants-of.js","sourceRoot":"","sources":["../../../src/application/tenancy/tenants-of.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,KAAY;IACpC,MAAM,MAAM,GAAY,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;AACjF,CAAC"}
|
|
@@ -23,9 +23,10 @@ export type DomainEventHandler<E extends DomainEvent> = DomainEventHandlerShape<
|
|
|
23
23
|
/**
|
|
24
24
|
* A handler of a domain event of its own context, run at the end of the unit of work that
|
|
25
25
|
* recorded the event, before the commit:
|
|
26
|
-
* `@DomainEventHandler(OrderPaid, { name:
|
|
26
|
+
* `@DomainEventHandler(OrderPaid, { name: OrderPaid.eventName })`, the name the event class
|
|
27
|
+
* declares once (`static readonly eventName = 'ordering.order.paid'`). One whose
|
|
27
28
|
* effect is outside the transaction runs after it:
|
|
28
|
-
* `@DomainEventHandler(OrderPaid, { name:
|
|
29
|
+
* `@DomainEventHandler(OrderPaid, { name: OrderPaid.eventName, phase: 'after-commit' })`.
|
|
29
30
|
*/
|
|
30
31
|
export declare function DomainEventHandler<E extends DomainEvent, const Name extends string, const D extends DeclaredDependencies = DependenciesFromSignature>(event: DomainEventType<E>, options: DomainEventHandlerOptions<Name> & Named<Name, 'name'>, dependencies?: D): ClassDeclarator<DomainEventHandlerShape<E>, D>;
|
|
31
32
|
//# sourceMappingURL=domain-event-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain-event-handler.d.ts","sourceRoot":"","sources":["../../../src/declarations/decorators/domain-event-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,KAAK,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACtG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,yBAAyB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IACrE,+GAA+G;IAC/G,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,WAAW,IAAI,uBAAuB,CAAC,CAAC,CAAC,CAAC;AAEnF
|
|
1
|
+
{"version":3,"file":"domain-event-handler.d.ts","sourceRoot":"","sources":["../../../src/declarations/decorators/domain-event-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,KAAK,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AACtG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,yBAAyB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IACrE,+GAA+G;IAC/G,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,WAAW,IAAI,uBAAuB,CAAC,CAAC,CAAC,CAAC;AAEnF;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,SAAS,WAAW,EACrB,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,KAAK,CAAC,CAAC,SAAS,oBAAoB,GAAG,yBAAyB,EAEhE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,EACzB,OAAO,EAAE,yBAAyB,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAC9D,YAAY,CAAC,EAAE,CAAC,GACf,eAAe,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAehD"}
|
|
@@ -3,9 +3,10 @@ import { assertNamed } from './assert-named.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* A handler of a domain event of its own context, run at the end of the unit of work that
|
|
5
5
|
* recorded the event, before the commit:
|
|
6
|
-
* `@DomainEventHandler(OrderPaid, { name:
|
|
6
|
+
* `@DomainEventHandler(OrderPaid, { name: OrderPaid.eventName })`, the name the event class
|
|
7
|
+
* declares once (`static readonly eventName = 'ordering.order.paid'`). One whose
|
|
7
8
|
* effect is outside the transaction runs after it:
|
|
8
|
-
* `@DomainEventHandler(OrderPaid, { name:
|
|
9
|
+
* `@DomainEventHandler(OrderPaid, { name: OrderPaid.eventName, phase: 'after-commit' })`.
|
|
9
10
|
*/
|
|
10
11
|
export function DomainEventHandler(event, options, dependencies) {
|
|
11
12
|
const { name, phase = 'before-commit' } = options;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain-event-handler.js","sourceRoot":"","sources":["../../../src/declarations/decorators/domain-event-handler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAmBhD
|
|
1
|
+
{"version":3,"file":"domain-event-handler.js","sourceRoot":"","sources":["../../../src/declarations/decorators/domain-event-handler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAmBhD;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAKhC,KAAyB,EACzB,OAA8D,EAC9D,YAAgB;IAEhB,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC;IAElD,WAAW,CAAC,IAAI,EAAE,gBAAgB,KAAK,CAAC,IAAI,kCAAkC,CAAC,CAAC;IAEhF,OAAO,CAAC,MAAM,EAAE,EAAE;QAChB,MAAM,CAAC,MAAM,EAAE;YACb,IAAI,EAAE,sBAAsB;YAC5B,IAAI;YACJ,KAAK;YACL,KAAK;YACL,YAAY;YACZ,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -9,7 +9,7 @@ type DomainEventName<Name extends string = string> = Pick<DomainEventHandlerOpti
|
|
|
9
9
|
/**
|
|
10
10
|
* On a method of a `@Projection` class: this method applies that event.
|
|
11
11
|
* `@On(PractitionerRenamed)` for an integration event of an upstream context,
|
|
12
|
-
* `@On(AppointmentBooked, { name:
|
|
12
|
+
* `@On(AppointmentBooked, { name: AppointmentBooked.eventName })` for a domain event of
|
|
13
13
|
* the projection's own context. The method receives the event and answers what its store
|
|
14
14
|
* answered.
|
|
15
15
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Immutable, compared by value, valid at construction. Subclass with a private
|
|
3
|
-
*
|
|
2
|
+
* Immutable, compared by value, valid at construction. Subclass with a private constructor and
|
|
3
|
+
* a `create` factory that validates, then returns the value object or throws the refusal of its
|
|
4
|
+
* concept (or returns a `Result`, in a project that says `"stack.valueObjects": "result"`).
|
|
4
5
|
*/
|
|
5
6
|
export declare abstract class ValueObject<Props extends Record<string, unknown>> {
|
|
6
7
|
protected readonly props: Readonly<Props>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-object.d.ts","sourceRoot":"","sources":["../../src/domain/value-object.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"value-object.d.ts","sourceRoot":"","sources":["../../src/domain/value-object.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,8BAAsB,WAAW,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrE,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1C,SAAS,aAAa,KAAK,EAAE,KAAK,EAEjC;IAED,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAM5D;IAED,MAAM,IAAI,KAAK,CAEd;CACF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Immutable, compared by value, valid at construction. Subclass with a private
|
|
3
|
-
*
|
|
2
|
+
* Immutable, compared by value, valid at construction. Subclass with a private constructor and
|
|
3
|
+
* a `create` factory that validates, then returns the value object or throws the refusal of its
|
|
4
|
+
* concept (or returns a `Result`, in a project that says `"stack.valueObjects": "result"`).
|
|
4
5
|
*/
|
|
5
6
|
export class ValueObject {
|
|
6
7
|
props;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-object.js","sourceRoot":"","sources":["../../src/domain/value-object.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"value-object.js","sourceRoot":"","sources":["../../src/domain/value-object.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAgB,WAAW;IACZ,KAAK,CAAkB;IAE1C,YAAsB,KAAY;QAChC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,KAA4C;QACjD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YACpF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,CAAU,EAAE,CAAU;IAC/C,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QAC3C,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE5B,OAAO,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -57,6 +57,7 @@ export * from './application/audit/tenant-scope-of.js';
|
|
|
57
57
|
export * from './application/audit/tenant-scoped.js';
|
|
58
58
|
export * from './application/audit/update-stamp.js';
|
|
59
59
|
export * from './application/cache/cache-key.js';
|
|
60
|
+
export * from './application/cache/tenant-cache-key.js';
|
|
60
61
|
export * from './application/dependency-kind.js';
|
|
61
62
|
export * from './application/error-reporting/error-origin.js';
|
|
62
63
|
export * from './application/error-reporting/error-report-extension-values.js';
|
|
@@ -205,6 +206,7 @@ export * from './application/ports/read-model-store.js';
|
|
|
205
206
|
export * from './application/ports/read-model-table.js';
|
|
206
207
|
export * from './application/ports/repository.js';
|
|
207
208
|
export * from './application/ports/unit-of-work.js';
|
|
209
|
+
export * from './application/ports/tenant-directory.js';
|
|
208
210
|
export * from './application/rate-limit/rate-limit-decision-of.js';
|
|
209
211
|
export * from './application/rate-limit/rate-limit-decision.js';
|
|
210
212
|
export * from './application/rate-limit/rate-limit.js';
|
|
@@ -239,7 +241,22 @@ export * from './application/session/session-client.js';
|
|
|
239
241
|
export * from './application/session/session-extension-values.js';
|
|
240
242
|
export * from './application/session/session-extensions.js';
|
|
241
243
|
export * from './application/session/session.js';
|
|
244
|
+
export * from './application/session/session-scope.js';
|
|
245
|
+
export * from './application/session/session-scopes.js';
|
|
246
|
+
export * from './application/session/has-scope.js';
|
|
242
247
|
export * from './application/session/system-session.js';
|
|
248
|
+
export * from './application/tenancy/across-tenants.js';
|
|
249
|
+
export * from './application/tenancy/assert-tenant-id.js';
|
|
250
|
+
export * from './application/tenancy/elevation-options.js';
|
|
251
|
+
export * from './application/tenancy/invalid-tenant-elevation-error.js';
|
|
252
|
+
export * from './application/tenancy/invalid-tenant-id-error.js';
|
|
253
|
+
export * from './application/tenancy/is-tenant-id.js';
|
|
254
|
+
export * from './application/tenancy/is-tenant-member.js';
|
|
255
|
+
export * from './application/tenancy/tenant-elevation.js';
|
|
256
|
+
export * from './application/tenancy/tenant-key.js';
|
|
257
|
+
export * from './application/tenancy/tenant-reach-of.js';
|
|
258
|
+
export * from './application/tenancy/tenant-reach.js';
|
|
259
|
+
export * from './application/tenancy/tenants-of.js';
|
|
243
260
|
export * from './application/use-case.js';
|
|
244
261
|
export * from './infrastructure/clock/fixed-clock.js';
|
|
245
262
|
export * from './infrastructure/clock/system-clock.js';
|
|
@@ -277,6 +294,7 @@ export * from './infrastructure/in-memory/in-memory-rate-limiter.js';
|
|
|
277
294
|
export * from './infrastructure/in-memory/in-memory-unit-of-work.js';
|
|
278
295
|
export * from './infrastructure/in-memory/metric-sample.js';
|
|
279
296
|
export * from './infrastructure/in-memory/unit-of-work-middleware.js';
|
|
297
|
+
export * from './infrastructure/in-memory/in-memory-tenant-directory.js';
|
|
280
298
|
export * from './infrastructure/read-model/postgres-read-model-rebuild.js';
|
|
281
299
|
export * from './infrastructure/read-model/projection-rebuild.js';
|
|
282
300
|
export * from './infrastructure/read-model/sql-run.js';
|
|
@@ -285,4 +303,8 @@ export * from './infrastructure/read-model/write-if-newer.js';
|
|
|
285
303
|
export * from './infrastructure/noop/noop-error-reporter.js';
|
|
286
304
|
export * from './infrastructure/noop/noop-logger.js';
|
|
287
305
|
export * from './infrastructure/noop/noop-metrics.js';
|
|
306
|
+
export * from './infrastructure/tenancy/tenant-settings.js';
|
|
307
|
+
export * from './infrastructure/tenancy/tenant-setting-values.js';
|
|
308
|
+
export * from './infrastructure/tenancy/tenant-isolation-policies.js';
|
|
309
|
+
export * from './infrastructure/tenancy/tenant-policy-expressions.js';
|
|
288
310
|
//# sourceMappingURL=index.d.ts.map
|