@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gary Bourgeat
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -159,7 +159,7 @@ a repository adapter never call it. An aggregate is recognised by what it does (
|
|
|
159
159
|
| `after-commit` | `dispatcher.on(name, callback, { phase: 'after-commit' })` | once the transaction has committed, never when it rolled back, in dispatch order, awaited before the command answers | never fails the command: reported, and the other handlers still run |
|
|
160
160
|
|
|
161
161
|
With declarations the phase is an option of the decorator:
|
|
162
|
-
`@DomainEventHandler(OrderPaid, { name:
|
|
162
|
+
`@DomainEventHandler(OrderPaid, { name: OrderPaid.eventName, phase: 'after-commit' })`.
|
|
163
163
|
|
|
164
164
|
The `after-commit` phase is at most once: a crash between the commit and the run loses it. What
|
|
165
165
|
must not be lost goes through the outbox as an integration event. A `before-commit` handler
|
|
@@ -419,7 +419,7 @@ left alone.
|
|
|
419
419
|
| `CommandHandler(Message)` | the one handler of a command | `@CommandHandler(PlaceOrder)` |
|
|
420
420
|
| `QueryHandler(Message)` | the one handler of a query | `@QueryHandler(GetOrder)` |
|
|
421
421
|
| `IntegrationEventHandler(definition, { consumer, actorOf? })` | the handler of an integration event of another context | `@IntegrationEventHandler(OrderPlaced, { consumer: 'billing.invoice-on-order-placed' })` |
|
|
422
|
-
| `DomainEventHandler(Event, { name })` | a handler of a domain event of its own context | `@DomainEventHandler(OrderPaid, { name:
|
|
422
|
+
| `DomainEventHandler(Event, { name })` | a handler of a domain event of its own context | `@DomainEventHandler(OrderPaid, { name: OrderPaid.eventName })`, the name the event class declares once in `static readonly eventName` |
|
|
423
423
|
| `Scheduled(name, schedule and options)` | a job run by time, which triggers use cases | `@Scheduled('billing.send-reminders', { cron: '0 7 * * 1-5', timeZone: 'Europe/Paris' })` |
|
|
424
424
|
| `Projection(name)` with `On(definition)` on its methods | a projector: the class that keeps one read model up to date | `@Projection('scheduling.appointment-list')`, `@On(PaymentCaptured)` |
|
|
425
425
|
| `Repository(Port, options?)` | the adapter of a repository of the domain | `@Repository(OrderRepository)` |
|
|
@@ -552,8 +552,13 @@ The authenticated session of an actor, as plain data.
|
|
|
552
552
|
| `authenticationStrength?` | `{ mfa?, assuranceLevel? }` |
|
|
553
553
|
| `impersonatedBy?` | id of the support actor acting as `actor`; `logFieldsOf` carries it to every log line |
|
|
554
554
|
| `locale?`, `timeZone?`, `client?` | BCP 47 tag, IANA zone, `{ ip?, userAgent? }` as opaque strings |
|
|
555
|
+
| `scopes?` | what the credential allows whoever presents it (the OAuth 2.0 `scope`): a limit on the client, never what the actor may do |
|
|
555
556
|
| `extensions` | the fields of the project |
|
|
556
557
|
|
|
558
|
+
`hasScope(session, scope)` reads the scopes; a project names its scope vocabulary once by
|
|
559
|
+
declaration merging of `SessionScopes` (`interface SessionScopes { readonly 'invoices:read': true }`),
|
|
560
|
+
and `SessionScope`, the type a guard takes, is then that vocabulary instead of any string.
|
|
561
|
+
|
|
557
562
|
`isExpired(session, clock.now())`, `isImpersonated(session)`, `anonymousSession()`,
|
|
558
563
|
`systemSession(name, issuedAt?)`, and `isSession(value)`, the structural guard a boundary uses on
|
|
559
564
|
what it received as a principal.
|
|
@@ -561,8 +566,8 @@ what it received as a principal.
|
|
|
561
566
|
### ExecutionContext and ExecutionScope
|
|
562
567
|
|
|
563
568
|
What every unit of work carries, whatever started it: `correlationId`, `causationId?`, `actor`,
|
|
564
|
-
`session?`, `tenantId?`, `
|
|
565
|
-
was due), `origin` (`http`, `event`, `schedule`, `cli`, or a string of the project) and `extensions`. `executionContext(init)` builds one and takes the tenant
|
|
569
|
+
`session?`, `tenantId?`, `elevation?` (platform staff reading over tenants, see "Tenancy"),
|
|
570
|
+
`locale?`, `deadline?`, `scheduledAt?` (for a scheduled job, the instant it was due), `origin` (`http`, `event`, `schedule`, `cli`, or a string of the project) and `extensions`. `executionContext(init)` builds one and takes the tenant
|
|
566
571
|
of the actor; `withActor(context, actor)` is the same work seen as another actor.
|
|
567
572
|
|
|
568
573
|
`ExecutionScope` (`current()`, `require()`, `run(context, work)`) gives the context of the work
|
|
@@ -584,11 +589,13 @@ tenant scoping and outgoing headers.
|
|
|
584
589
|
|
|
585
590
|
A consumed event opens its own context: `executionContextOfEvent(event, { consumer })` has
|
|
586
591
|
origin `event`, the correlation of the event (its id when it names none), the event as
|
|
587
|
-
`causationId
|
|
592
|
+
`causationId`, `systemActor(consumer)` as actor and the `tenantId` of the event, so the
|
|
593
|
+
consumer reads and writes in that tenant only; `inEventScope(scope, { consumer }, handler)`
|
|
588
594
|
wraps a handler with it. The standard envelope carries no actor, so that no personal data
|
|
589
595
|
travels by default: a project whose envelopes name one passes `actorOf`. On the way out,
|
|
590
|
-
`scopedPublisher(publisher, scope)` stamps the correlation of the work in
|
|
591
|
-
event published without
|
|
596
|
+
`scopedPublisher(publisher, scope)` stamps the correlation and the tenant of the work in
|
|
597
|
+
progress on every event published without them, so everything one stimulus causes is found
|
|
598
|
+
again across processes and stays in its tenant.
|
|
592
599
|
|
|
593
600
|
`ActorContext` stays, unchanged. `ScopedActorContext` implements it on top of a scope: the
|
|
594
601
|
current actor is the actor of the current execution context, so the two cannot disagree.
|
|
@@ -701,7 +708,8 @@ const hit: Quote | undefined = await cache.get(quoteKey('EUR-USD'));
|
|
|
701
708
|
```
|
|
702
709
|
|
|
703
710
|
The key carries the type of its value. `InMemoryCache(clock, { maxEntries? })` expires by the
|
|
704
|
-
`Clock` and is bounded.
|
|
711
|
+
`Clock` and is bounded. `tenantCacheKey<Quote>(scope, 'quote', pair)` is the same key confined to
|
|
712
|
+
the tenant of the work in progress: what one tenant cached is never served to another.
|
|
705
713
|
|
|
706
714
|
### Lock
|
|
707
715
|
|
|
@@ -748,9 +756,10 @@ instead of rejecting: only an unknown name rejects (`UnknownJobError`), and a na
|
|
|
748
756
|
twice throws (`DuplicateJobError`).
|
|
749
757
|
|
|
750
758
|
A run happens inside `ExecutionScope`, in the context `executionContextOfJob(name, { correlationId,
|
|
751
|
-
scheduledAt, deadline? })` builds: origin `schedule`, `systemActor(name)`, a correlation of its
|
|
759
|
+
scheduledAt, deadline?, tenantId? })` builds: origin `schedule`, `systemActor(name)`, a correlation of its
|
|
752
760
|
own, and `scheduledAt`, the instant the run was due, which `ExecutionContext` carries for this
|
|
753
|
-
origin.
|
|
761
|
+
origin. A job is `global` by default and runs in no tenant; `tenancy: 'per-tenant'` makes the
|
|
762
|
+
scheduler run it once per tenant of a `TenantDirectory`, each run in that tenant.
|
|
754
763
|
|
|
755
764
|
`parseJobSchedule(schedule)` validates a schedule and answers the form occurrences are
|
|
756
765
|
computed from (`InvalidJobScheduleError`, code `INVALID_JOB_SCHEDULE`, otherwise);
|
|
@@ -770,12 +779,36 @@ if (!decision.allowed) {
|
|
|
770
779
|
|
|
771
780
|
A sliding window: at any instant, at most `limit` allowed calls in the `windowMs` before it. A
|
|
772
781
|
`RateLimitDecision` is `{ allowed, remaining, retryAfterMs }`; a refused call is not counted.
|
|
773
|
-
The key is whatever is limited: a client, a tenant, a route and an address together.
|
|
782
|
+
The key is whatever is limited: a client, a tenant, a route and an address together. In a
|
|
783
|
+
multi-tenant project, `tenantKey(scope, 'password-reset', accountId)` confines it to the tenant of
|
|
784
|
+
the work in progress (`tenant:<id>:password-reset:<account>`) and refuses work that names none.
|
|
774
785
|
|
|
775
786
|
`InMemoryRateLimiter(clock)` counts inside one process; the adapter shared by several instances
|
|
776
787
|
is in `@ddd-ts-kit/redis`. `rateLimitDecisionOf(counted, limit)` turns what an adapter counted
|
|
777
788
|
into the decision.
|
|
778
789
|
|
|
790
|
+
### Tenancy
|
|
791
|
+
|
|
792
|
+
The tenant of the work is `ExecutionContext.tenantId`, set at the boundary and read by
|
|
793
|
+
infrastructure only, like the rest of the context. The kernel holds what every strategy shares;
|
|
794
|
+
the isolation itself (tenant column, row-level security, schema or database per tenant) is in the
|
|
795
|
+
persistence packages, and the whole picture in
|
|
796
|
+
[Multitenancy](../../docs/concepts/multitenancy.md).
|
|
797
|
+
|
|
798
|
+
| Concept | What it does |
|
|
799
|
+
|---|---|
|
|
800
|
+
| `isTenantId(value)`, `assertTenantId(id)`, `InvalidTenantIdError` | the one grammar of a tenant id (letters, digits, `_`, `-`, at most 63): `executionContext`, `executionContextOfEvent`, `acrossTenants`, `InMemoryTenantDirectory`, `tenantScopeOf`, `tenantReachOf` and the row-level security settings refuse any other, so that no tenant id can be read as a wildcard, a list or a key separator |
|
|
801
|
+
| `tenantScopeOf(scope)` | the one tenant a write names; `NoCurrentTenantError` for work that names none |
|
|
802
|
+
| `tenantReachOf(scope)` | what a read may see: `{ kind: 'tenant', tenantId }`, or `{ kind: 'elevated', tenants }` under an elevation |
|
|
803
|
+
| `tenantsOf(actor)`, `isTenantMember(actor, tenantId)` | the tenants an actor belongs to: its `tenantId` and its `tenants` attribute |
|
|
804
|
+
| `acrossTenants({ scope, trail, clock, ids }, { reason, tenants }, work)` | platform staff reading over tenants: refused without a reason or a tenant, recorded in the `AuditTrail` (action `tenancy:elevate`) before the work runs; writes still name one tenant |
|
|
805
|
+
| `tenantKey(scope, ...segments)`, `tenantCacheKey(scope, ...segments)` | keys of rate limits, locks and caches confined to the tenant: `tenant:<id>:<segments>`, each segment percent-encoded, so that two lists of segments never give one key |
|
|
806
|
+
| `TenantDirectory`, `InMemoryTenantDirectory` | the tenants that exist, for per-tenant jobs, provisioning and migrations |
|
|
807
|
+
| `TENANT_SETTINGS`, `tenantSettingValues(context)`, `TENANT_ISOLATION_POLICIES`, `tenantPolicyExpressions(column)` | what the row-level security of the persistence packages shares: the three settings of a transaction (`ddd_ts_kit.tenant_id`, and for an elevation only `ddd_ts_kit.reach` and `ddd_ts_kit.every_tenant`), their values for the work in progress, the names of the four policies (one per command) and their `read` and `write` expressions |
|
|
808
|
+
|
|
809
|
+
An elevation is never implied by a role: the platform decides the permission to elevate (a use
|
|
810
|
+
case or a guard), then calls `acrossTenants`. A trail that fails to record it refuses it.
|
|
811
|
+
|
|
779
812
|
### Page and PageRequest
|
|
780
813
|
|
|
781
814
|
One shape for every search, in two variants:
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ExecutionScope } from '../ports/execution-scope.js';
|
|
2
2
|
import type { TenantScoped } from './tenant-scoped.js';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* For a repository adapter scoping a statement: the tenant of the work in progress, checked
|
|
5
|
+
* against the grammar of `isTenantId` again however the context was built.
|
|
6
|
+
*/
|
|
4
7
|
export declare function tenantScopeOf(scope: ExecutionScope): TenantScoped;
|
|
5
8
|
//# sourceMappingURL=tenant-scope-of.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-scope-of.d.ts","sourceRoot":"","sources":["../../../src/application/audit/tenant-scope-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"tenant-scope-of.d.ts","sourceRoot":"","sources":["../../../src/application/audit/tenant-scope-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAGlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAQjE"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { assertTenantId } from '../tenancy/assert-tenant-id.js';
|
|
1
2
|
import { NoCurrentTenantError } from './no-current-tenant-error.js';
|
|
2
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* For a repository adapter scoping a statement: the tenant of the work in progress, checked
|
|
5
|
+
* against the grammar of `isTenantId` again however the context was built.
|
|
6
|
+
*/
|
|
3
7
|
export function tenantScopeOf(scope) {
|
|
4
8
|
const { tenantId } = scope.require();
|
|
5
9
|
if (tenantId === undefined) {
|
|
6
10
|
throw new NoCurrentTenantError();
|
|
7
11
|
}
|
|
8
|
-
return { tenantId };
|
|
12
|
+
return { tenantId: assertTenantId(tenantId) };
|
|
9
13
|
}
|
|
10
14
|
//# sourceMappingURL=tenant-scope-of.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-scope-of.js","sourceRoot":"","sources":["../../../src/application/audit/tenant-scope-of.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE
|
|
1
|
+
{"version":3,"file":"tenant-scope-of.js","sourceRoot":"","sources":["../../../src/application/audit/tenant-scope-of.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGpE;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAqB;IACjD,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAErC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,oBAAoB,EAAE,CAAC;IACnC,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ExecutionScope } from '../ports/execution-scope.js';
|
|
2
|
+
import { type CacheKey } from './cache-key.js';
|
|
3
|
+
/** `cacheKey` confined to the tenant of the work in progress: what one tenant cached is never served to another. */
|
|
4
|
+
export declare function tenantCacheKey<T>(scope: ExecutionScope, ...segments: readonly string[]): CacheKey<T>;
|
|
5
|
+
//# sourceMappingURL=tenant-cache-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-cache-key.d.ts","sourceRoot":"","sources":["../../../src/application/cache/tenant-cache-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,gBAAgB,CAAC;AAEzD,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAEpG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { tenantKey } from '../tenancy/tenant-key.js';
|
|
2
|
+
import { cacheKey } from './cache-key.js';
|
|
3
|
+
/** `cacheKey` confined to the tenant of the work in progress: what one tenant cached is never served to another. */
|
|
4
|
+
export function tenantCacheKey(scope, ...segments) {
|
|
5
|
+
return cacheKey(tenantKey(scope, ...segments));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=tenant-cache-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-cache-key.js","sourceRoot":"","sources":["../../../src/application/cache/tenant-cache-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAiB,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEzD,oHAAoH;AACpH,MAAM,UAAU,cAAc,CAAI,KAAqB,EAAE,GAAG,QAA2B;IACrF,OAAO,QAAQ,CAAI,SAAS,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -3,7 +3,8 @@ import type { EventExecutionOptions } from './event-execution-options.js';
|
|
|
3
3
|
import type { IntegrationEvent } from './integration-event.js';
|
|
4
4
|
/**
|
|
5
5
|
* The execution context of a consumed event: origin `event`, the correlation of the event (its
|
|
6
|
-
* own id when it names none, which starts a new chain),
|
|
6
|
+
* own id when it names none, which starts a new chain), the event as the direct cause, and the
|
|
7
|
+
* tenant the event belongs to, so the consumer reads and writes in that tenant only.
|
|
7
8
|
*/
|
|
8
9
|
export declare function executionContextOfEvent(event: IntegrationEvent, options: EventExecutionOptions): ExecutionContext;
|
|
9
10
|
//# sourceMappingURL=execution-context-of-event.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-context-of-event.d.ts","sourceRoot":"","sources":["../../../src/application/events/execution-context-of-event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAoB,MAAM,mCAAmC,CAAC;AAC5F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D
|
|
1
|
+
{"version":3,"file":"execution-context-of-event.d.ts","sourceRoot":"","sources":["../../../src/application/events/execution-context-of-event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAoB,MAAM,mCAAmC,CAAC;AAC5F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,qBAAqB,GAAG,gBAAgB,CAQjH"}
|
|
@@ -2,7 +2,8 @@ import { systemActor } from '../actor/system-actor.js';
|
|
|
2
2
|
import { executionContext } from '../execution/execution-context.js';
|
|
3
3
|
/**
|
|
4
4
|
* The execution context of a consumed event: origin `event`, the correlation of the event (its
|
|
5
|
-
* own id when it names none, which starts a new chain),
|
|
5
|
+
* own id when it names none, which starts a new chain), the event as the direct cause, and the
|
|
6
|
+
* tenant the event belongs to, so the consumer reads and writes in that tenant only.
|
|
6
7
|
*/
|
|
7
8
|
export function executionContextOfEvent(event, options) {
|
|
8
9
|
return executionContext({
|
|
@@ -10,6 +11,7 @@ export function executionContextOfEvent(event, options) {
|
|
|
10
11
|
causationId: event.id,
|
|
11
12
|
actor: options.actorOf?.(event) ?? systemActor(options.consumer),
|
|
12
13
|
origin: 'event',
|
|
14
|
+
...(event.tenantId === undefined ? {} : { tenantId: event.tenantId }),
|
|
13
15
|
});
|
|
14
16
|
}
|
|
15
17
|
//# sourceMappingURL=execution-context-of-event.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-context-of-event.js","sourceRoot":"","sources":["../../../src/application/events/execution-context-of-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAyB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI5F
|
|
1
|
+
{"version":3,"file":"execution-context-of-event.js","sourceRoot":"","sources":["../../../src/application/events/execution-context-of-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAyB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAI5F;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAuB,EAAE,OAA8B;IAC7F,OAAO,gBAAgB,CAAC;QACtB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,EAAE;QAC9C,WAAW,EAAE,KAAK,CAAC,EAAE;QACrB,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC;QAChE,MAAM,EAAE,OAAO;QACf,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;KACtE,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -13,5 +13,11 @@ export interface IntegrationEvent<Payload = unknown> {
|
|
|
13
13
|
/** W3C traceparent captured at publication so consumers continue the same trace. */
|
|
14
14
|
readonly traceparent?: string;
|
|
15
15
|
readonly correlationId?: string;
|
|
16
|
+
/**
|
|
17
|
+
* The tenant the fact belongs to, stamped from the work that published it. A consumer handles
|
|
18
|
+
* the event in that tenant's scope, so its reads and writes stay in the tenant. Absent for a
|
|
19
|
+
* fact of no tenant (the platform's own).
|
|
20
|
+
*/
|
|
21
|
+
readonly tenantId?: string;
|
|
16
22
|
}
|
|
17
23
|
//# sourceMappingURL=integration-event.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-event.d.ts","sourceRoot":"","sources":["../../../src/application/events/integration-event.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,OAAO,GAAG,OAAO;IACjD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"integration-event.d.ts","sourceRoot":"","sources":["../../../src/application/events/integration-event.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,gBAAgB,CAAC,OAAO,GAAG,OAAO;IACjD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B"}
|
|
@@ -2,9 +2,10 @@ import type { ExecutionScope } from '../ports/execution-scope.js';
|
|
|
2
2
|
import type { IntegrationEventPublisher } from '../ports/integration-event-publisher.js';
|
|
3
3
|
/**
|
|
4
4
|
* Decorates a publisher: an event published without `correlationId` takes the one of the work
|
|
5
|
-
* in progress, so everything one stimulus causes can be found again
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* in progress, so everything one stimulus causes can be found again, and one without `tenantId`
|
|
6
|
+
* the tenant of that work, so its consumers run in the same tenant. What an event names is
|
|
7
|
+
* kept, and outside of any execution context nothing is stamped. The name of the transport
|
|
8
|
+
* (`messagingSystem`) is passed on.
|
|
8
9
|
*/
|
|
9
10
|
export declare function scopedPublisher(publisher: IntegrationEventPublisher, scope: ExecutionScope): IntegrationEventPublisher;
|
|
10
11
|
//# sourceMappingURL=scoped-publisher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-publisher.d.ts","sourceRoot":"","sources":["../../../src/application/events/scoped-publisher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AAIzF
|
|
1
|
+
{"version":3,"file":"scoped-publisher.d.ts","sourceRoot":"","sources":["../../../src/application/events/scoped-publisher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AAIzF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,yBAAyB,EACpC,KAAK,EAAE,cAAc,GACpB,yBAAyB,CAO3B"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { messagingSystemOf } from './messaging-system-of.js';
|
|
2
2
|
/**
|
|
3
3
|
* Decorates a publisher: an event published without `correlationId` takes the one of the work
|
|
4
|
-
* in progress, so everything one stimulus causes can be found again
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* in progress, so everything one stimulus causes can be found again, and one without `tenantId`
|
|
5
|
+
* the tenant of that work, so its consumers run in the same tenant. What an event names is
|
|
6
|
+
* kept, and outside of any execution context nothing is stamped. The name of the transport
|
|
7
|
+
* (`messagingSystem`) is passed on.
|
|
7
8
|
*/
|
|
8
9
|
export function scopedPublisher(publisher, scope) {
|
|
9
10
|
const messagingSystem = messagingSystemOf(publisher);
|
|
@@ -13,9 +14,14 @@ export function scopedPublisher(publisher, scope) {
|
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
16
|
function correlated(event, context) {
|
|
16
|
-
if (
|
|
17
|
+
if (context === undefined) {
|
|
17
18
|
return event;
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
+
const { correlationId, tenantId } = context;
|
|
21
|
+
return {
|
|
22
|
+
...event,
|
|
23
|
+
...(event.correlationId === undefined ? { correlationId } : {}),
|
|
24
|
+
...(event.tenantId === undefined && tenantId !== undefined ? { tenantId } : {}),
|
|
25
|
+
};
|
|
20
26
|
}
|
|
21
27
|
//# sourceMappingURL=scoped-publisher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-publisher.js","sourceRoot":"","sources":["../../../src/application/events/scoped-publisher.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D
|
|
1
|
+
{"version":3,"file":"scoped-publisher.js","sourceRoot":"","sources":["../../../src/application/events/scoped-publisher.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAoC,EACpC,KAAqB;IAErB,MAAM,eAAe,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAErD,OAAO;QACL,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACjG,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAuB,EAAE,OAAqC;IAChF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE5C,OAAO;QACL,GAAG,KAAK;QACR,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChF,CAAC;AACJ,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Actor } from '../actor/actor.js';
|
|
2
2
|
import type { Session } from '../session/session.js';
|
|
3
|
+
import type { TenantElevation } from '../tenancy/tenant-elevation.js';
|
|
3
4
|
import type { ExecutionContextExtensionValues } from './execution-context-extension-values.js';
|
|
4
5
|
import type { ExecutionOrigin } from './execution-origin.js';
|
|
5
6
|
/**
|
|
@@ -14,6 +15,8 @@ export interface ExecutionContext {
|
|
|
14
15
|
readonly actor: Actor;
|
|
15
16
|
readonly session?: Session;
|
|
16
17
|
readonly tenantId?: string;
|
|
18
|
+
/** Platform staff reading over tenants, opened by `acrossTenants` and audited. Absent otherwise. */
|
|
19
|
+
readonly elevation?: TenantElevation;
|
|
17
20
|
readonly locale?: string;
|
|
18
21
|
/** The instant after which the result is useless to the caller. */
|
|
19
22
|
readonly deadline?: Date;
|
|
@@ -23,6 +26,9 @@ export interface ExecutionContext {
|
|
|
23
26
|
readonly extensions: ExecutionContextExtensionValues;
|
|
24
27
|
}
|
|
25
28
|
export type ExecutionContextInit = Omit<ExecutionContext, 'extensions' | 'tenantId'> & Partial<Pick<ExecutionContext, 'extensions' | 'tenantId'>>;
|
|
26
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Fills what can be derived: the tenant of the actor, no extension. A tenant id outside the
|
|
31
|
+
* grammar of `isTenantId` is refused (`InvalidTenantIdError`), whatever named it.
|
|
32
|
+
*/
|
|
27
33
|
export declare function executionContext(init: ExecutionContextInit): ExecutionContext;
|
|
28
34
|
//# sourceMappingURL=execution-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../../../src/application/execution/execution-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../../../src/application/execution/execution-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,oGAAoG;IACpG,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;IACzB,mGAAmG;IACnG,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,+BAA+B,CAAC;CACtD;AAED,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC,GAClF,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAS7E"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { assertTenantId } from '../tenancy/assert-tenant-id.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fills what can be derived: the tenant of the actor, no extension. A tenant id outside the
|
|
4
|
+
* grammar of `isTenantId` is refused (`InvalidTenantIdError`), whatever named it.
|
|
5
|
+
*/
|
|
2
6
|
export function executionContext(init) {
|
|
3
|
-
const
|
|
7
|
+
const named = init.tenantId ?? init.actor.tenantId;
|
|
8
|
+
const tenantId = named === undefined ? undefined : assertTenantId(named);
|
|
4
9
|
return Object.freeze({
|
|
5
10
|
...init,
|
|
6
11
|
...(tenantId === undefined ? {} : { tenantId }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../../../src/application/execution/execution-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../../../src/application/execution/execution-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AA+BhE;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA0B;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IACnD,MAAM,QAAQ,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAEzE,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,IAAI;QACP,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;QAC/C,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;KACjD,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-fields-of.d.ts","sourceRoot":"","sources":["../../../src/application/execution/log-fields-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"log-fields-of.d.ts","sourceRoot":"","sources":["../../../src/application/execution/log-fields-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAUhE"}
|
|
@@ -6,6 +6,7 @@ export function logFieldsOf(context) {
|
|
|
6
6
|
actorId: context.actor.id,
|
|
7
7
|
...(context.causationId === undefined ? {} : { causationId: context.causationId }),
|
|
8
8
|
...(context.tenantId === undefined ? {} : { tenantId: context.tenantId }),
|
|
9
|
+
...(context.elevation === undefined ? {} : { elevation: context.elevation.reason }),
|
|
9
10
|
...(context.session?.impersonatedBy === undefined ? {} : { impersonatedBy: context.session.impersonatedBy }),
|
|
10
11
|
};
|
|
11
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-fields-of.js","sourceRoot":"","sources":["../../../src/application/execution/log-fields-of.ts"],"names":[],"mappings":"AAGA,iGAAiG;AACjG,MAAM,UAAU,WAAW,CAAC,OAAyB;IACnD,OAAO;QACL,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACzB,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;QAClF,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzE,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;KAC7G,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"log-fields-of.js","sourceRoot":"","sources":["../../../src/application/execution/log-fields-of.ts"],"names":[],"mappings":"AAGA,iGAAiG;AACjG,MAAM,UAAU,WAAW,CAAC,OAAyB;IACnD,OAAO;QACL,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACzB,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;QAClF,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzE,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QACnF,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;KAC7G,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tenants that exist, for work that runs once per tenant: a job declared `tenancy:
|
|
3
|
+
* 'per-tenant'`, the provisioning of a schema or a database, a migration applied to each.
|
|
4
|
+
*/
|
|
5
|
+
export declare abstract class TenantDirectory {
|
|
6
|
+
abstract tenants(): Promise<readonly string[]>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=tenant-directory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-directory.d.ts","sourceRoot":"","sources":["../../../src/application/ports/tenant-directory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,8BAAsB,eAAe;IAKnC,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;CAChD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tenants that exist, for work that runs once per tenant: a job declared `tenancy:
|
|
3
|
+
* 'per-tenant'`, the provisioning of a schema or a database, a migration applied to each.
|
|
4
|
+
*/
|
|
5
|
+
export class TenantDirectory {
|
|
6
|
+
static {
|
|
7
|
+
Object.defineProperty(this, 'tokenKey', { value: 'kernel.TenantDirectory' });
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=tenant-directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-directory.js","sourceRoot":"","sources":["../../../src/application/ports/tenant-directory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAgB,eAAe;IACnC;QACE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;IAC/E,CAAC;CAGF"}
|
|
@@ -4,10 +4,12 @@ export interface JobExecutionStart {
|
|
|
4
4
|
readonly scheduledAt: Date;
|
|
5
5
|
/** The instant the timeout of the job ends the run, when it has one. */
|
|
6
6
|
readonly deadline?: Date;
|
|
7
|
+
/** For a job declared `tenancy: 'per-tenant'`: the tenant of this run. */
|
|
8
|
+
readonly tenantId?: string;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* The execution context of one run: origin `schedule`, the system actor named after the job, a
|
|
10
|
-
* correlation of its own
|
|
12
|
+
* correlation of its own, the instant the run was due, and the tenant of a per-tenant run.
|
|
11
13
|
*/
|
|
12
14
|
export declare function executionContextOfJob(job: string, start: JobExecutionStart): ExecutionContext;
|
|
13
15
|
//# sourceMappingURL=execution-context-of-job.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-context-of-job.d.ts","sourceRoot":"","sources":["../../../src/application/scheduling/execution-context-of-job.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAoB,MAAM,mCAAmC,CAAC;AAE5F,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"execution-context-of-job.d.ts","sourceRoot":"","sources":["../../../src/application/scheduling/execution-context-of-job.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAoB,MAAM,mCAAmC,CAAC;AAE5F,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,gBAAgB,CAE7F"}
|
|
@@ -2,7 +2,7 @@ import { systemActor } from '../actor/system-actor.js';
|
|
|
2
2
|
import { executionContext } from '../execution/execution-context.js';
|
|
3
3
|
/**
|
|
4
4
|
* The execution context of one run: origin `schedule`, the system actor named after the job, a
|
|
5
|
-
* correlation of its own
|
|
5
|
+
* correlation of its own, the instant the run was due, and the tenant of a per-tenant run.
|
|
6
6
|
*/
|
|
7
7
|
export function executionContextOfJob(job, start) {
|
|
8
8
|
return executionContext({ ...start, actor: systemActor(job), origin: 'schedule' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-context-of-job.js","sourceRoot":"","sources":["../../../src/application/scheduling/execution-context-of-job.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAyB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"execution-context-of-job.js","sourceRoot":"","sources":["../../../src/application/scheduling/execution-context-of-job.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAyB,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAW5F;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW,EAAE,KAAwB;IACzE,OAAO,gBAAgB,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -8,5 +8,7 @@ export interface JobExecution {
|
|
|
8
8
|
readonly attempt: number;
|
|
9
9
|
/** Aborted when the run exceeds its timeout or the scheduler stops: a long job checks it. */
|
|
10
10
|
readonly signal: AbortSignal;
|
|
11
|
+
/** The tenant of this run, for a job declared `tenancy: 'per-tenant'`. */
|
|
12
|
+
readonly tenantId?: string;
|
|
11
13
|
}
|
|
12
14
|
//# sourceMappingURL=job-execution.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-execution.d.ts","sourceRoot":"","sources":["../../../src/application/scheduling/job-execution.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,yGAAyG;IACzG,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,uGAAuG;IACvG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"job-execution.d.ts","sourceRoot":"","sources":["../../../src/application/scheduling/job-execution.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,yGAAyG;IACzG,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,uGAAuG;IACvG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B"}
|
|
@@ -21,5 +21,11 @@ export interface JobOptions {
|
|
|
21
21
|
* an application running several runs it. Best effort: see the scheduler.
|
|
22
22
|
*/
|
|
23
23
|
readonly singleInstance?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* `global` (default): one run per occurrence, in no tenant. `per-tenant`: one run per tenant
|
|
26
|
+
* of the `TenantDirectory` for each occurrence, each in that tenant's execution scope, so the
|
|
27
|
+
* job reads and writes one tenant at a time; one failing tenant does not stop the others.
|
|
28
|
+
*/
|
|
29
|
+
readonly tenancy?: 'global' | 'per-tenant';
|
|
24
30
|
}
|
|
25
31
|
//# sourceMappingURL=job-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-options.d.ts","sourceRoot":"","sources":["../../../src/application/scheduling/job-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,sHAAsH;IACtH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,uGAAuG;IACvG,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"job-options.d.ts","sourceRoot":"","sources":["../../../src/application/scheduling/job-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,sHAAsH;IACtH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,uGAAuG;IACvG,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC;CAC5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-policy.d.ts","sourceRoot":"","sources":["../../../src/application/scheduling/job-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,iDAAiD;AACjD,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAEhG,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"job-policy.d.ts","sourceRoot":"","sources":["../../../src/application/scheduling/job-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,iDAAiD;AACjD,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAEhG,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,CAmBxD"}
|
|
@@ -3,15 +3,17 @@ import { parseDuration } from './parse-duration.js';
|
|
|
3
3
|
/** Validates the options and fills in the defaults. Throws `InvalidJobScheduleError`. */
|
|
4
4
|
export function jobPolicy(options) {
|
|
5
5
|
const { overlap = 'skip', missed = 'skip', timeoutMs, jitterMs = 0, enabled = true, singleInstance = true } = options;
|
|
6
|
+
const tenancy = options.tenancy ?? 'global';
|
|
6
7
|
assertOneOf('overlap', overlap, ['skip', 'queue']);
|
|
7
8
|
assertOneOf('missed', missed, ['skip', 'run-once']);
|
|
9
|
+
assertOneOf('tenancy', tenancy, ['global', 'per-tenant']);
|
|
8
10
|
if (!Number.isSafeInteger(jitterMs) || jitterMs < 0) {
|
|
9
11
|
throw new InvalidJobScheduleError(`jitterMs is ${jitterMs}: a whole number of milliseconds, zero or more, is expected.`);
|
|
10
12
|
}
|
|
11
13
|
if (timeoutMs === undefined) {
|
|
12
|
-
return { overlap, missed, jitterMs, enabled, singleInstance };
|
|
14
|
+
return { overlap, missed, jitterMs, enabled, singleInstance, tenancy };
|
|
13
15
|
}
|
|
14
|
-
return { overlap, missed, jitterMs, enabled, singleInstance, timeoutMs: parseDuration(timeoutMs) };
|
|
16
|
+
return { overlap, missed, jitterMs, enabled, singleInstance, tenancy, timeoutMs: parseDuration(timeoutMs) };
|
|
15
17
|
}
|
|
16
18
|
function assertOneOf(option, value, allowed) {
|
|
17
19
|
if (allowed.includes(value)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-policy.js","sourceRoot":"","sources":["../../../src/application/scheduling/job-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKpD,yFAAyF;AACzF,MAAM,UAAU,SAAS,CAAC,OAAmB;IAC3C,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,QAAQ,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"job-policy.js","sourceRoot":"","sources":["../../../src/application/scheduling/job-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKpD,yFAAyF;AACzF,MAAM,UAAU,SAAS,CAAC,OAAmB;IAC3C,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,QAAQ,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACtH,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC;IAE5C,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IAE1D,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,uBAAuB,CAC/B,eAAe,QAAQ,8DAA8D,CACtF,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;IACzE,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;AAC9G,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,KAAa,EAAE,OAA0B;IAC5E,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,IAAI,uBAAuB,CAAC,GAAG,MAAM,QAAQ,KAAK,aAAa,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AAC1G,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SessionScope } from './session-scope.js';
|
|
2
|
+
import type { Session } from './session.js';
|
|
3
|
+
/** Whether the session was granted the scope; a request without a session was granted none. */
|
|
4
|
+
export declare function hasScope(session: Session | undefined, scope: SessionScope): boolean;
|
|
5
|
+
//# sourceMappingURL=has-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-scope.d.ts","sourceRoot":"","sources":["../../../src/application/session/has-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,+FAA+F;AAC/F,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAEnF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-scope.js","sourceRoot":"","sources":["../../../src/application/session/has-scope.ts"],"names":[],"mappings":"AAGA,+FAA+F;AAC/F,MAAM,UAAU,QAAQ,CAAC,OAA4B,EAAE,KAAmB;IACxE,OAAO,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SessionScopes } from './session-scopes.js';
|
|
2
|
+
/** A scope of the project's vocabulary once `SessionScopes` declares one, any string before. */
|
|
3
|
+
export type SessionScope = [keyof SessionScopes] extends [never] ? string : Extract<keyof SessionScopes, string>;
|
|
4
|
+
//# sourceMappingURL=session-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-scope.d.ts","sourceRoot":"","sources":["../../../src/application/session/session-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,gGAAgG;AAChG,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,aAAa,EAAE,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-scope.js","sourceRoot":"","sources":["../../../src/application/session/session-scope.ts"],"names":[],"mappings":""}
|