@aeolus-fleet/core 0.26.1 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/adapters/http/request-credentials.d.ts +2 -9
- package/dist/adapters/http/request-credentials.js +8 -1
- package/dist/adapters/http/request-credentials.js.map +1 -1
- package/dist/adapters/http/server.js +2 -1
- package/dist/adapters/http/server.js.map +1 -1
- package/dist/adapters/mcp/mcp-endpoint.js +11 -1
- package/dist/adapters/mcp/mcp-endpoint.js.map +1 -1
- package/dist/adapters/prisma/generated/browser.d.ts +8 -0
- package/dist/adapters/prisma/generated/client.d.ts +8 -0
- package/dist/adapters/prisma/generated/enums.d.ts +2 -0
- package/dist/adapters/prisma/generated/enums.js +3 -1
- package/dist/adapters/prisma/generated/enums.js.map +1 -1
- package/dist/adapters/prisma/generated/internal/class.d.ts +11 -0
- package/dist/adapters/prisma/generated/internal/class.js +4 -4
- package/dist/adapters/prisma/generated/internal/class.js.map +1 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespace.d.ts +94 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespace.js +18 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespace.js.map +1 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.d.ts +18 -0
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js +18 -1
- package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -1
- package/dist/adapters/prisma/generated/models/Delivery.d.ts +71 -1
- package/dist/adapters/prisma/generated/models/Fleet.d.ts +275 -0
- package/dist/adapters/prisma/generated/models/Lease.d.ts +113 -1
- package/dist/adapters/prisma/generated/models/NetworkSettings.d.ts +151 -19
- package/dist/adapters/prisma/generated/models/ReachRefusal.d.ts +71 -1
- package/dist/adapters/prisma/generated/models/ScopeNamespace.d.ts +1220 -0
- package/dist/adapters/prisma/generated/models/ScopeNamespace.js +2 -0
- package/dist/adapters/prisma/generated/models/ScopeNamespace.js.map +1 -0
- package/dist/adapters/prisma/generated/models/Ship.d.ts +983 -55
- package/dist/adapters/prisma/generated/models.d.ts +1 -0
- package/dist/adapters/prisma/health.js +27 -7
- package/dist/adapters/prisma/health.js.map +1 -1
- package/dist/adapters/prisma/history.js +14 -70
- package/dist/adapters/prisma/history.js.map +1 -1
- package/dist/adapters/prisma/messaging.js +27 -34
- package/dist/adapters/prisma/messaging.js.map +1 -1
- package/dist/adapters/prisma/network.js +39 -12
- package/dist/adapters/prisma/network.js.map +1 -1
- package/dist/adapters/prisma/registry.js +65 -11
- package/dist/adapters/prisma/registry.js.map +1 -1
- package/dist/adapters/prisma/rows.d.ts +3 -0
- package/dist/adapters/prisma/rows.js +20 -7
- package/dist/adapters/prisma/rows.js.map +1 -1
- package/dist/adapters/prisma/scope-namespaces.d.ts +4 -0
- package/dist/adapters/prisma/scope-namespaces.js +39 -0
- package/dist/adapters/prisma/scope-namespaces.js.map +1 -0
- package/dist/adapters/prisma/unit-of-work.d.ts +2 -1
- package/dist/adapters/prisma/unit-of-work.js +2 -0
- package/dist/adapters/prisma/unit-of-work.js.map +1 -1
- package/dist/adapters/rest/rest-api.js +2 -2
- package/dist/adapters/rest/rest-api.js.map +1 -1
- package/dist/adapters/trpc/console.d.ts +1 -1
- package/dist/adapters/trpc/console.js +6 -4
- package/dist/adapters/trpc/console.js.map +1 -1
- package/dist/adapters/trpc/context.d.ts +20 -4
- package/dist/adapters/trpc/fleet.d.ts +179 -82
- package/dist/adapters/trpc/fleet.js +117 -53
- package/dist/adapters/trpc/fleet.js.map +1 -1
- package/dist/adapters/trpc/router.d.ts +231 -80
- package/dist/adapters/trpc/ship-contract.js +4 -0
- package/dist/adapters/trpc/ship-contract.js.map +1 -1
- package/dist/adapters/trpc/ship-protocol.js +7 -5
- package/dist/adapters/trpc/ship-protocol.js.map +1 -1
- package/dist/adapters/trpc/ship.d.ts +71 -3
- package/dist/adapters/trpc/ship.js +42 -5
- package/dist/adapters/trpc/ship.js.map +1 -1
- package/dist/adapters/trpc/trpc.d.ts +6 -5
- package/dist/adapters/trpc/trpc.js +76 -21
- package/dist/adapters/trpc/trpc.js.map +1 -1
- package/dist/domain/messaging/check-inbox.d.ts +5 -5
- package/dist/domain/messaging/check-inbox.js +9 -7
- package/dist/domain/messaging/check-inbox.js.map +1 -1
- package/dist/domain/messaging/dismiss-delivery.d.ts +9 -4
- package/dist/domain/messaging/dismiss-delivery.js +26 -19
- package/dist/domain/messaging/dismiss-delivery.js.map +1 -1
- package/dist/domain/messaging/message.d.ts +11 -5
- package/dist/domain/messaging/message.js +11 -4
- package/dist/domain/messaging/message.js.map +1 -1
- package/dist/domain/messaging/ping-ship.d.ts +3 -3
- package/dist/domain/messaging/ping-ship.js +6 -2
- package/dist/domain/messaging/ping-ship.js.map +1 -1
- package/dist/domain/messaging/ports.d.ts +9 -3
- package/dist/domain/messaging/receive-deliveries.d.ts +2 -0
- package/dist/domain/messaging/receive-deliveries.js +1 -0
- package/dist/domain/messaging/receive-deliveries.js.map +1 -1
- package/dist/domain/messaging/resend-delivery.d.ts +5 -2
- package/dist/domain/messaging/resend-delivery.js +8 -4
- package/dist/domain/messaging/resend-delivery.js.map +1 -1
- package/dist/domain/messaging/send-message.d.ts +9 -2
- package/dist/domain/messaging/send-message.js +12 -2
- package/dist/domain/messaging/send-message.js.map +1 -1
- package/dist/domain/messaging/send-request.d.ts +3 -1
- package/dist/domain/messaging/send-request.js +4 -2
- package/dist/domain/messaging/send-request.js.map +1 -1
- package/dist/domain/registry/assign-label.d.ts +2 -1
- package/dist/domain/registry/assign-label.js +3 -2
- package/dist/domain/registry/assign-label.js.map +1 -1
- package/dist/domain/registry/check-reach.d.ts +63 -4
- package/dist/domain/registry/check-reach.js +107 -11
- package/dist/domain/registry/check-reach.js.map +1 -1
- package/dist/domain/registry/commission-ship.d.ts +17 -8
- package/dist/domain/registry/commission-ship.js +24 -10
- package/dist/domain/registry/commission-ship.js.map +1 -1
- package/dist/domain/registry/crew-request.d.ts +1 -1
- package/dist/domain/registry/declare-scopes.d.ts +38 -0
- package/dist/domain/registry/declare-scopes.js +34 -0
- package/dist/domain/registry/declare-scopes.js.map +1 -0
- package/dist/domain/registry/declared-network-rules.d.ts +2 -1
- package/dist/domain/registry/declared-network-rules.js +11 -5
- package/dist/domain/registry/declared-network-rules.js.map +1 -1
- package/dist/domain/registry/discover.d.ts +28 -0
- package/dist/domain/registry/discover.js +54 -0
- package/dist/domain/registry/discover.js.map +1 -0
- package/dist/domain/registry/explain-reach.d.ts +12 -12
- package/dist/domain/registry/explain-reach.js +35 -12
- package/dist/domain/registry/explain-reach.js.map +1 -1
- package/dist/domain/registry/get-ship.d.ts +11 -3
- package/dist/domain/registry/get-ship.js +8 -2
- package/dist/domain/registry/get-ship.js.map +1 -1
- package/dist/domain/registry/get-starting-prompt.d.ts +18 -2
- package/dist/domain/registry/get-starting-prompt.js +7 -7
- package/dist/domain/registry/get-starting-prompt.js.map +1 -1
- package/dist/domain/registry/grant-scopes.d.ts +34 -0
- package/dist/domain/registry/grant-scopes.js +35 -0
- package/dist/domain/registry/grant-scopes.js.map +1 -0
- package/dist/domain/registry/label.d.ts +12 -7
- package/dist/domain/registry/label.js +21 -4
- package/dist/domain/registry/label.js.map +1 -1
- package/dist/domain/registry/list-fleet.d.ts +19 -6
- package/dist/domain/registry/list-fleet.js +18 -3
- package/dist/domain/registry/list-fleet.js.map +1 -1
- package/dist/domain/registry/list-scopes.d.ts +24 -0
- package/dist/domain/registry/list-scopes.js +22 -0
- package/dist/domain/registry/list-scopes.js.map +1 -0
- package/dist/domain/registry/managed-or-assigned.d.ts +25 -0
- package/dist/domain/registry/managed-or-assigned.js +23 -0
- package/dist/domain/registry/managed-or-assigned.js.map +1 -0
- package/dist/domain/registry/named-namespaces.d.ts +19 -0
- package/dist/domain/registry/named-namespaces.js +19 -0
- package/dist/domain/registry/named-namespaces.js.map +1 -0
- package/dist/domain/registry/network-settings.d.ts +84 -24
- package/dist/domain/registry/network-settings.js +134 -45
- package/dist/domain/registry/network-settings.js.map +1 -1
- package/dist/domain/registry/ports.d.ts +63 -1
- package/dist/domain/registry/public.d.ts +3 -2
- package/dist/domain/registry/public.js +3 -2
- package/dist/domain/registry/public.js.map +1 -1
- package/dist/domain/registry/reach-refusal.d.ts +12 -4
- package/dist/domain/registry/read-assigned-crew-requests.d.ts +12 -3
- package/dist/domain/registry/read-assigned-crew-requests.js +8 -8
- package/dist/domain/registry/read-assigned-crew-requests.js.map +1 -1
- package/dist/domain/registry/read-built-in-rules.d.ts +20 -0
- package/dist/domain/registry/read-built-in-rules.js +23 -0
- package/dist/domain/registry/read-built-in-rules.js.map +1 -0
- package/dist/domain/registry/read-clear-requests.d.ts +5 -3
- package/dist/domain/registry/read-clear-requests.js +7 -5
- package/dist/domain/registry/read-clear-requests.js.map +1 -1
- package/dist/domain/registry/read-on-behalf.d.ts +20 -0
- package/dist/domain/registry/read-on-behalf.js +31 -0
- package/dist/domain/registry/read-on-behalf.js.map +1 -0
- package/dist/domain/registry/read-reach.d.ts +62 -0
- package/dist/domain/registry/read-reach.js +78 -0
- package/dist/domain/registry/read-reach.js.map +1 -0
- package/dist/domain/registry/recrew-ship.d.ts +3 -2
- package/dist/domain/registry/recrew-ship.js +6 -1
- package/dist/domain/registry/recrew-ship.js.map +1 -1
- package/dist/domain/registry/release-ship.d.ts +6 -3
- package/dist/domain/registry/release-ship.js +7 -7
- package/dist/domain/registry/release-ship.js.map +1 -1
- package/dist/domain/registry/remove-crew-request.d.ts +4 -3
- package/dist/domain/registry/remove-crew-request.js +6 -1
- package/dist/domain/registry/remove-crew-request.js.map +1 -1
- package/dist/domain/registry/rename-ship.d.ts +7 -5
- package/dist/domain/registry/rename-ship.js +9 -3
- package/dist/domain/registry/rename-ship.js.map +1 -1
- package/dist/domain/registry/request-crew.d.ts +5 -4
- package/dist/domain/registry/request-crew.js +6 -1
- package/dist/domain/registry/request-crew.js.map +1 -1
- package/dist/domain/registry/request-worktree-clear.d.ts +3 -2
- package/dist/domain/registry/request-worktree-clear.js +6 -1
- package/dist/domain/registry/request-worktree-clear.js.map +1 -1
- package/dist/domain/registry/retire-ship.d.ts +16 -7
- package/dist/domain/registry/retire-ship.js +46 -5
- package/dist/domain/registry/retire-ship.js.map +1 -1
- package/dist/domain/registry/scope-grant.d.ts +53 -0
- package/dist/domain/registry/scope-grant.js +74 -0
- package/dist/domain/registry/scope-grant.js.map +1 -0
- package/dist/domain/registry/scope-namespace.d.ts +68 -0
- package/dist/domain/registry/scope-namespace.js +82 -0
- package/dist/domain/registry/scope-namespace.js.map +1 -0
- package/dist/domain/registry/set-built-in-rule.d.ts +28 -0
- package/dist/domain/registry/set-built-in-rule.js +33 -0
- package/dist/domain/registry/set-built-in-rule.js.map +1 -0
- package/dist/domain/registry/set-network-rules.d.ts +3 -3
- package/dist/domain/registry/set-network-rules.js +2 -2
- package/dist/domain/registry/set-owner.d.ts +30 -0
- package/dist/domain/registry/set-owner.js +37 -0
- package/dist/domain/registry/set-owner.js.map +1 -0
- package/dist/domain/registry/set-statement.d.ts +27 -0
- package/dist/domain/registry/set-statement.js +28 -0
- package/dist/domain/registry/set-statement.js.map +1 -0
- package/dist/domain/registry/ship.d.ts +70 -10
- package/dist/domain/registry/ship.js +95 -10
- package/dist/domain/registry/ship.js.map +1 -1
- package/dist/domain/registry/statement.d.ts +32 -0
- package/dist/domain/registry/statement.js +39 -0
- package/dist/domain/registry/statement.js.map +1 -0
- package/dist/domain/registry/unassign-label.js +1 -1
- package/dist/domain/registry/unassign-label.js.map +1 -1
- package/dist/domain/registry/whoami.d.ts +5 -1
- package/dist/domain/registry/whoami.js +7 -4
- package/dist/domain/registry/whoami.js.map +1 -1
- package/dist/domain/shared/caller.d.ts +5 -2
- package/dist/domain/shared/caller.js.map +1 -1
- package/dist/domain/shared/errors.d.ts +1 -1
- package/dist/domain/shared/errors.js.map +1 -1
- package/dist/domain/shared/events-read.d.ts +16 -0
- package/dist/domain/shared/events-read.js +15 -0
- package/dist/domain/shared/events-read.js.map +1 -0
- package/dist/domain/shared/follow-fleet.d.ts +8 -2
- package/dist/domain/shared/follow-fleet.js +14 -4
- package/dist/domain/shared/follow-fleet.js.map +1 -1
- package/dist/domain/shared/health.d.ts +9 -2
- package/dist/domain/shared/health.js +9 -3
- package/dist/domain/shared/health.js.map +1 -1
- package/dist/domain/shared/history.d.ts +9 -42
- package/dist/domain/shared/history.js +9 -0
- package/dist/domain/shared/history.js.map +1 -1
- package/dist/domain/shared/read-fleet-events.d.ts +8 -2
- package/dist/domain/shared/read-fleet-events.js +10 -4
- package/dist/domain/shared/read-fleet-events.js.map +1 -1
- package/dist/domain/shared/read-health.d.ts +4 -1
- package/dist/domain/shared/read-health.js +7 -2
- package/dist/domain/shared/read-health.js.map +1 -1
- package/dist/domain/shared/read-inbox.d.ts +6 -3
- package/dist/domain/shared/read-inbox.js +14 -4
- package/dist/domain/shared/read-inbox.js.map +1 -1
- package/dist/domain/shared/read-message.d.ts +6 -2
- package/dist/domain/shared/read-message.js +6 -2
- package/dist/domain/shared/read-message.js.map +1 -1
- package/dist/domain/shared/read-needs-attention.d.ts +4 -1
- package/dist/domain/shared/read-needs-attention.js +8 -3
- package/dist/domain/shared/read-needs-attention.js.map +1 -1
- package/dist/domain/shared/read-ship-messages.d.ts +6 -2
- package/dist/domain/shared/read-ship-messages.js +7 -2
- package/dist/domain/shared/read-ship-messages.js.map +1 -1
- package/dist/domain/shared/read-ship-timeline.d.ts +5 -2
- package/dist/domain/shared/read-ship-timeline.js +11 -6
- package/dist/domain/shared/read-ship-timeline.js.map +1 -1
- package/dist/domain/shared/read-ship-way.d.ts +11 -4
- package/dist/domain/shared/read-ship-way.js +9 -2
- package/dist/domain/shared/read-ship-way.js.map +1 -1
- package/dist/domain/shared/stuck.d.ts +10 -1
- package/dist/domain/shared/stuck.js +1 -1
- package/dist/domain/shared/stuck.js.map +1 -1
- package/dist/wiring.d.ts +18 -4
- package/dist/wiring.js +37 -18
- package/dist/wiring.js.map +1 -1
- package/package.json +2 -2
- package/src/adapters/prisma/migrations/20261018100000_force_scope/migration.sql +8 -0
- package/src/adapters/prisma/migrations/20261018110000_forced_delivery/migration.sql +4 -0
- package/src/adapters/prisma/migrations/20261018120000_person_and_app_ships/migration.sql +3 -0
- package/src/adapters/prisma/migrations/20261018130000_owners/migration.sql +14 -0
- package/src/adapters/prisma/migrations/20261018140000_owners_on_reach_refusals/migration.sql +14 -0
- package/src/adapters/prisma/migrations/20261018150000_network_verbs/migration.sql +9 -0
- package/src/adapters/prisma/migrations/20261018160000_built_in_rules/migration.sql +13 -0
- package/src/adapters/prisma/migrations/20261018170000_network_rules_a_list/migration.sql +5 -0
- package/src/adapters/prisma/migrations/20261018180000_verb_on_reach_refusals/migration.sql +4 -0
- package/src/adapters/prisma/migrations/20261018200000_lease_statements/migration.sql +3 -0
- package/src/adapters/prisma/migrations/20261018210000_declare_and_grant_scopes/migration.sql +8 -0
- package/src/adapters/prisma/migrations/20261018220000_plugin_scopes/migration.sql +14 -0
- package/src/adapters/prisma/migrations/20261018230000_scope_namespaces/migration.sql +20 -0
- package/src/adapters/prisma/migrations/20261018240000_trierarch_plugin_crew_run/migration.sql +44 -0
- package/src/adapters/prisma/migrations/20261018250000_scope_catalogue/migration.sql +66 -0
- package/src/adapters/prisma/migrations/20261019090000_reach_refusal_asked_by/migration.sql +2 -0
- package/src/adapters/prisma/migrations/20261019100000_on_behalf_scope/migration.sql +59 -0
- package/src/adapters/prisma/migrations/20261019110000_events_fleet_id_occurred_at/migration.sql +2 -0
- package/src/adapters/prisma/schema.prisma +47 -2
- package/dist/domain/shared/read-no-ship-can-take.d.ts +0 -13
- package/dist/domain/shared/read-no-ship-can-take.js +0 -12
- package/dist/domain/shared/read-no-ship-can-take.js.map +0 -1
- package/dist/domain/shared/read-overdue.d.ts +0 -13
- package/dist/domain/shared/read-overdue.js +0 -12
- package/dist/domain/shared/read-overdue.js.map +0 -1
|
@@ -2,6 +2,7 @@ import { refuse } from '../shared/errors.js';
|
|
|
2
2
|
import { recordEvent, shipActor } from '../shared/events.js';
|
|
3
3
|
import { ok } from '../shared/result.js';
|
|
4
4
|
import { requestWorktreeClear } from './clear-request.js';
|
|
5
|
+
import { checkManage, keepingReachRefusal } from './check-reach.js';
|
|
5
6
|
/**
|
|
6
7
|
* Use case: the caller asks a trierarch to clear the worktree it kept for a
|
|
7
8
|
* ship in a repository (decision 0032). Its scope (fleet:manage) is checked
|
|
@@ -9,7 +10,7 @@ import { requestWorktreeClear } from './clear-request.js';
|
|
|
9
10
|
* two requests never both pass its limit: the request and its event.
|
|
10
11
|
*/
|
|
11
12
|
export function createRequestWorktreeClear(deps) {
|
|
12
|
-
return (caller, input) => deps.uow
|
|
13
|
+
return (caller, input) => keepingReachRefusal(deps.uow, async (tx) => {
|
|
13
14
|
const { fleetId } = caller;
|
|
14
15
|
const trierarch = await tx.ships.findForUpdate(fleetId, input.trierarchShipId);
|
|
15
16
|
if (!trierarch) {
|
|
@@ -18,6 +19,10 @@ export function createRequestWorktreeClear(deps) {
|
|
|
18
19
|
if (!(await tx.ships.find(fleetId, input.shipId))) {
|
|
19
20
|
return refuse('SHIP_NOT_FOUND', `Ship ${input.shipId} does not exist`);
|
|
20
21
|
}
|
|
22
|
+
const managed = await checkManage({ tx, ids: deps.ids }, { fleetId: fleetId, managerShipId: caller.shipId, shipId: input.shipId, at: deps.clock.now() });
|
|
23
|
+
if (!managed.isOk) {
|
|
24
|
+
return managed;
|
|
25
|
+
}
|
|
21
26
|
const key = { trierarchShipId: trierarch.id, shipId: input.shipId, repository: input.repository };
|
|
22
27
|
const requested = requestWorktreeClear({ trierarch, current: await tx.clearRequests.find(fleetId, key), pending: (await tx.clearRequests.listFor(fleetId, trierarch.id)).length }, { shipId: input.shipId, repository: input.repository, requestedBy: caller.shipId, at: deps.clock.now(), actor: shipActor(caller.shipId) });
|
|
23
28
|
if (!requested.isOk) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-worktree-clear.js","sourceRoot":"","sources":["../../../src/domain/registry/request-worktree-clear.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAiB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,oBAAoB,EAAoC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"request-worktree-clear.js","sourceRoot":"","sources":["../../../src/domain/registry/request-worktree-clear.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,18 +5,20 @@ import type { Clock } from '../shared/clock.js';
|
|
|
5
5
|
import { type DomainError } from '../shared/errors.js';
|
|
6
6
|
import { type Result } from '../shared/result.js';
|
|
7
7
|
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
8
|
+
import { type CheckManageTx, type NotReachable } from './check-reach.js';
|
|
8
9
|
import { type LeaseTx } from './leases.js';
|
|
9
|
-
import type { ClearRequestRepository, CrewRequestRepository, DeclaredNetworkRulesRepository, LabelRepository, NetworkSettingsRepository, ShipRepository } from './ports.js';
|
|
10
|
+
import type { ClearRequestRepository, CrewRequestRepository, DeclaredNetworkRulesRepository, LabelRepository, NetworkSettingsRepository, ScopeNamespaceRepository, ShipRepository } from './ports.js';
|
|
10
11
|
import { type RetireRefusal } from './ship.js';
|
|
11
|
-
export interface RetireShipTx extends LeaseTx, CredentialTx {
|
|
12
|
+
export interface RetireShipTx extends LeaseTx, CredentialTx, Omit<CheckManageTx, 'ships' | 'leases' | 'labels' | 'networkSettings'> {
|
|
12
13
|
ships: ShipRepository;
|
|
13
14
|
crewRequests: CrewRequestRepository;
|
|
14
15
|
clearRequests: ClearRequestRepository;
|
|
15
16
|
labels: LabelRepository;
|
|
16
|
-
networkSettings: Pick<NetworkSettingsRepository, 'findForUpdate' | 'save'>;
|
|
17
|
+
networkSettings: Pick<NetworkSettingsRepository, 'find' | 'findForShare' | 'findForUpdate' | 'save'>;
|
|
17
18
|
declaredNetworkRules: Pick<DeclaredNetworkRulesRepository, 'find' | 'save'>;
|
|
19
|
+
scopeNamespaces: Pick<ScopeNamespaceRepository, 'findByDeclarer' | 'lockNamespace' | 'remove'>;
|
|
18
20
|
}
|
|
19
|
-
export type RetireShipRefusal = DomainError<'SHIP_NOT_FOUND'> | RetireRefusal;
|
|
21
|
+
export type RetireShipRefusal = DomainError<'SHIP_NOT_FOUND'> | NotReachable | RetireRefusal;
|
|
20
22
|
export type RetireShip = (caller: Caller, input: {
|
|
21
23
|
shipId: ShipId;
|
|
22
24
|
}) => Promise<Result<{
|
|
@@ -36,9 +38,16 @@ export type RetireShip = (caller: Caller, input: {
|
|
|
36
38
|
* assignment of it gone first (decision 0031). A retired trierarch clears
|
|
37
39
|
* nothing: its pending clear requests go, one WorktreeClearRemoved each
|
|
38
40
|
* (decision 0032). The network rules it declared go with its labels
|
|
39
|
-
* (decision 0037).
|
|
40
|
-
*
|
|
41
|
-
*
|
|
41
|
+
* (decision 0037). Each active ship it owned falls to argo, one
|
|
42
|
+
* OwnerChanged each, locked after the ship as a set owner locks the owner
|
|
43
|
+
* first (decision 0045). A retired networking plugin unregisters, its rules going
|
|
44
|
+
* with it: all-to-all (decision 0035). A plugin namespace it declared goes,
|
|
45
|
+
* and its scopes leave every ship, one ScopesChanged each (decision 0046).
|
|
46
|
+
* The caller's scope (fleet:manage) is
|
|
47
|
+
* checked before this runs, and manage reach on the ship here (decision
|
|
48
|
+
* 0034), a refusal storing only its record. That check reads the network
|
|
49
|
+
* settings without a lock: retire takes them exclusively later, after the
|
|
50
|
+
* ships it owns, and a shared hold taken first would deadlock two retires.
|
|
42
51
|
*
|
|
43
52
|
* It locks the ship first, as a release does (FOR NO KEY UPDATE). A send to
|
|
44
53
|
* the ship holds it FOR SHARE while it resolves the selector, so the two
|
|
@@ -2,13 +2,15 @@ import { revokeShipSecret } from '../identity/public.js';
|
|
|
2
2
|
import { refuse } from '../shared/errors.js';
|
|
3
3
|
import { recordEvent, shipActor } from '../shared/events.js';
|
|
4
4
|
import { ok } from '../shared/result.js';
|
|
5
|
+
import { checkManage, keepingReachRefusal } from './check-reach.js';
|
|
5
6
|
import { removeClearRequestsOf } from './clear-request.js';
|
|
6
7
|
import { removeCrewRequest } from './crew-request.js';
|
|
7
8
|
import { retireLabelsWith } from './label.js';
|
|
8
9
|
import { endLease } from './leases.js';
|
|
9
10
|
import { withdrawWithRetiredShip } from './declared-network-rules.js';
|
|
10
11
|
import { unregisterNetworkPlugin } from './network-settings.js';
|
|
11
|
-
import { checkCanRetire } from './ship.js';
|
|
12
|
+
import { changeOwner, checkCanRetire } from './ship.js';
|
|
13
|
+
import { releaseWithDeclarer } from './scope-namespace.js';
|
|
12
14
|
/**
|
|
13
15
|
* Use case: the caller retires a ship of its fleet for good (Retire): any ship
|
|
14
16
|
* but argo, crewed or not. In one unit of work: its secret stops working; a
|
|
@@ -23,9 +25,16 @@ import { checkCanRetire } from './ship.js';
|
|
|
23
25
|
* assignment of it gone first (decision 0031). A retired trierarch clears
|
|
24
26
|
* nothing: its pending clear requests go, one WorktreeClearRemoved each
|
|
25
27
|
* (decision 0032). The network rules it declared go with its labels
|
|
26
|
-
* (decision 0037).
|
|
27
|
-
*
|
|
28
|
-
*
|
|
28
|
+
* (decision 0037). Each active ship it owned falls to argo, one
|
|
29
|
+
* OwnerChanged each, locked after the ship as a set owner locks the owner
|
|
30
|
+
* first (decision 0045). A retired networking plugin unregisters, its rules going
|
|
31
|
+
* with it: all-to-all (decision 0035). A plugin namespace it declared goes,
|
|
32
|
+
* and its scopes leave every ship, one ScopesChanged each (decision 0046).
|
|
33
|
+
* The caller's scope (fleet:manage) is
|
|
34
|
+
* checked before this runs, and manage reach on the ship here (decision
|
|
35
|
+
* 0034), a refusal storing only its record. That check reads the network
|
|
36
|
+
* settings without a lock: retire takes them exclusively later, after the
|
|
37
|
+
* ships it owns, and a shared hold taken first would deadlock two retires.
|
|
29
38
|
*
|
|
30
39
|
* It locks the ship first, as a release does (FOR NO KEY UPDATE). A send to
|
|
31
40
|
* the ship holds it FOR SHARE while it resolves the selector, so the two
|
|
@@ -34,12 +43,16 @@ import { checkCanRetire } from './ship.js';
|
|
|
34
43
|
* network settings exclusively, after the ship as every send takes them.
|
|
35
44
|
*/
|
|
36
45
|
export function createRetireShip(deps) {
|
|
37
|
-
return (caller, { shipId }) => deps.uow
|
|
46
|
+
return (caller, { shipId }) => keepingReachRefusal(deps.uow, async (tx) => {
|
|
38
47
|
const { fleetId } = caller;
|
|
39
48
|
const ship = await tx.ships.findForUpdate(fleetId, shipId);
|
|
40
49
|
if (!ship) {
|
|
41
50
|
return refuse('SHIP_NOT_FOUND', `Ship ${shipId} does not exist`);
|
|
42
51
|
}
|
|
52
|
+
const managed = await checkManage({ tx, ids: deps.ids }, { fleetId, managerShipId: caller.shipId, shipId, at: deps.clock.now(), settings: await tx.networkSettings.find(fleetId) });
|
|
53
|
+
if (!managed.isOk) {
|
|
54
|
+
return managed;
|
|
55
|
+
}
|
|
43
56
|
const retirable = checkCanRetire(ship);
|
|
44
57
|
if (!retirable.isOk) {
|
|
45
58
|
return retirable;
|
|
@@ -65,6 +78,17 @@ export function createRetireShip(deps) {
|
|
|
65
78
|
for (const { deliveryId, messageId } of abandoned) {
|
|
66
79
|
await recordEvent(recorded, { fleetId, type: 'DeliveryAbandoned', occurredAt: at, actor, shipId, messageId, deliveryId });
|
|
67
80
|
}
|
|
81
|
+
const argo = await tx.ships.findOperatorShip(fleetId);
|
|
82
|
+
for (const ownedShip of await tx.ships.listActiveOwnedByForUpdate(fleetId, shipId)) {
|
|
83
|
+
// Never refused: an owned ship is active and never argo's own, and argo is always active.
|
|
84
|
+
const changed = changeOwner(ownedShip, { owner: argo, why: 'ownerRetired', at, actor });
|
|
85
|
+
if (changed.isOk && changed.value.ship.owner !== null && changed.value.ship.owner !== ownedShip.owner) {
|
|
86
|
+
await tx.ships.setOwner({ fleetId, shipId: ownedShip.id, ownerShipId: changed.value.ship.owner });
|
|
87
|
+
for (const event of changed.value.events) {
|
|
88
|
+
await recordEvent(recorded, event);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
68
92
|
// A ship without a crew request has none to remove: nothing to do.
|
|
69
93
|
const removed = removeCrewRequest({ ship, current: await tx.crewRequests.find(fleetId, shipId) }, { at, actor });
|
|
70
94
|
if (removed.isOk) {
|
|
@@ -107,6 +131,23 @@ export function createRetireShip(deps) {
|
|
|
107
131
|
await recordEvent(recorded, event);
|
|
108
132
|
}
|
|
109
133
|
}
|
|
134
|
+
const declared = await tx.scopeNamespaces.findByDeclarer(fleetId, shipId);
|
|
135
|
+
if (declared !== undefined) {
|
|
136
|
+
// The holders first, as every grant locks its ship before the
|
|
137
|
+
// namespace; then the namespace, so no grant of its scopes commits
|
|
138
|
+
// in between; then the holders again: a grant that did commit before
|
|
139
|
+
// the namespace lock holds no lock any more.
|
|
140
|
+
await tx.ships.listActiveHoldingInForUpdate(fleetId, declared.namespace);
|
|
141
|
+
await tx.scopeNamespaces.lockNamespace(fleetId, declared.namespace);
|
|
142
|
+
const released = releaseWithDeclarer(declared, { holders: await tx.ships.listActiveHoldingInForUpdate(fleetId, declared.namespace), at, actor });
|
|
143
|
+
for (const changed of released.ships) {
|
|
144
|
+
await tx.ships.setScopes({ fleetId, shipId: changed.id, scopes: changed.scopes });
|
|
145
|
+
}
|
|
146
|
+
await tx.scopeNamespaces.remove(fleetId, declared.namespace);
|
|
147
|
+
for (const event of released.events) {
|
|
148
|
+
await recordEvent(recorded, event);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
110
151
|
return ok({ abandonedDeliveries: abandoned.length });
|
|
111
152
|
});
|
|
112
153
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retire-ship.js","sourceRoot":"","sources":["../../../src/domain/registry/retire-ship.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,uBAAuB,CAAC;AAG5E,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAgB,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAsB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"retire-ship.js","sourceRoot":"","sources":["../../../src/domain/registry/retire-ship.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type ScopeName, type ShipId, type ShipKind } from '@aeolus-fleet/common';
|
|
2
|
+
import { type DomainError } from '../shared/errors.js';
|
|
3
|
+
import type { Actor, NewEvent } from '../shared/events.js';
|
|
4
|
+
import { type Result } from '../shared/result.js';
|
|
5
|
+
import type { ScopeNamespace } from './scope-namespace.js';
|
|
6
|
+
import type { Ship } from './ship.js';
|
|
7
|
+
export type GrantScopesRefusal = DomainError<'INVALID_SCOPE' | 'BASE_SCOPE' | 'SCOPE_NOT_DECLARED' | 'SCOPE_NOT_HELD' | 'PLUGIN_SCOPE_NOT_YOURS' | 'SHIP_SCOPES_FIXED' | 'OWN_SHIP_SCOPES' | 'SHIP_ALREADY_RETIRED'>;
|
|
8
|
+
/**
|
|
9
|
+
* A granter grants and revokes scopes on a live ship (decision 0046), each
|
|
10
|
+
* within what it may grant: a core scope it holds (argo holds every one), or
|
|
11
|
+
* a declared scope of a plugin namespace when it is argo or that namespace's
|
|
12
|
+
* declarer. Revoking follows the same rule. Refused: a malformed or unknown
|
|
13
|
+
* scope, one both granted and revoked, revoking sending or receiving, argo's
|
|
14
|
+
* and the viewer's scopes, the granter's own ship and a retired ship. Writes
|
|
15
|
+
* ScopesChanged when anything changes.
|
|
16
|
+
*/
|
|
17
|
+
export declare function grantScopes(input: {
|
|
18
|
+
ship: Ship;
|
|
19
|
+
granter: {
|
|
20
|
+
shipId: ShipId;
|
|
21
|
+
kind: ShipKind;
|
|
22
|
+
scopes: readonly ScopeName[];
|
|
23
|
+
};
|
|
24
|
+
grant: readonly string[];
|
|
25
|
+
revoke: readonly string[];
|
|
26
|
+
at: Date;
|
|
27
|
+
actor: Actor;
|
|
28
|
+
}, fleet: {
|
|
29
|
+
/** The plugin namespaces the granted and revoked scopes name, with their declarers' names, by namespace. */
|
|
30
|
+
namespaces: ReadonlyMap<string, {
|
|
31
|
+
namespace: ScopeNamespace;
|
|
32
|
+
declarerName: string;
|
|
33
|
+
}>;
|
|
34
|
+
}): Result<{
|
|
35
|
+
ship: Ship;
|
|
36
|
+
events: NewEvent[];
|
|
37
|
+
}, GrantScopesRefusal>;
|
|
38
|
+
/**
|
|
39
|
+
* Whether the granter may grant or revoke the scope, at commission or on a
|
|
40
|
+
* live ship: a core scope it holds, or a declared plugin scope when it is
|
|
41
|
+
* argo or the declarer.
|
|
42
|
+
*/
|
|
43
|
+
export declare function mayGrant(scope: string, at: {
|
|
44
|
+
granter: {
|
|
45
|
+
shipId: ShipId;
|
|
46
|
+
kind: ShipKind;
|
|
47
|
+
scopes: readonly ScopeName[];
|
|
48
|
+
};
|
|
49
|
+
namespaces: ReadonlyMap<string, {
|
|
50
|
+
namespace: ScopeNamespace;
|
|
51
|
+
declarerName: string;
|
|
52
|
+
}>;
|
|
53
|
+
}): Result<null, DomainError<'INVALID_SCOPE' | 'SCOPE_NOT_DECLARED' | 'SCOPE_NOT_HELD' | 'PLUGIN_SCOPE_NOT_YOURS'>>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { scopeNameSchema, scopeSchema } from '@aeolus-fleet/common';
|
|
2
|
+
import { refuse } from '../shared/errors.js';
|
|
3
|
+
import { ok } from '../shared/result.js';
|
|
4
|
+
/** The scopes every agent, person and app ship holds: never revoked (decision 0046). */
|
|
5
|
+
const BASE_SCOPES = ['messages:send', 'messages:receive'];
|
|
6
|
+
/**
|
|
7
|
+
* A granter grants and revokes scopes on a live ship (decision 0046), each
|
|
8
|
+
* within what it may grant: a core scope it holds (argo holds every one), or
|
|
9
|
+
* a declared scope of a plugin namespace when it is argo or that namespace's
|
|
10
|
+
* declarer. Revoking follows the same rule. Refused: a malformed or unknown
|
|
11
|
+
* scope, one both granted and revoked, revoking sending or receiving, argo's
|
|
12
|
+
* and the viewer's scopes, the granter's own ship and a retired ship. Writes
|
|
13
|
+
* ScopesChanged when anything changes.
|
|
14
|
+
*/
|
|
15
|
+
export function grantScopes(input, fleet) {
|
|
16
|
+
const { ship, granter, at, actor } = input;
|
|
17
|
+
if (ship.kind === 'operator' || ship.kind === 'viewer') {
|
|
18
|
+
return refuse('SHIP_SCOPES_FIXED', `${ship.name}'s scopes are its own: argo holds every scope and the viewer reads`);
|
|
19
|
+
}
|
|
20
|
+
if (ship.id === granter.shipId) {
|
|
21
|
+
return refuse('OWN_SHIP_SCOPES', 'A ship never changes its own scopes');
|
|
22
|
+
}
|
|
23
|
+
if (ship.retiredAt !== null) {
|
|
24
|
+
return refuse('SHIP_ALREADY_RETIRED', `${ship.name} is retired: its scopes stay as they were`);
|
|
25
|
+
}
|
|
26
|
+
for (const scope of [...input.grant, ...input.revoke]) {
|
|
27
|
+
const allowed = mayGrant(scope, { granter, namespaces: fleet.namespaces });
|
|
28
|
+
if (!allowed.isOk) {
|
|
29
|
+
return allowed;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const both = input.grant.find((scope) => input.revoke.includes(scope));
|
|
33
|
+
if (both !== undefined) {
|
|
34
|
+
return refuse('INVALID_SCOPE', `${both} is both granted and revoked`);
|
|
35
|
+
}
|
|
36
|
+
const base = input.revoke.find((scope) => BASE_SCOPES.includes(scope));
|
|
37
|
+
if (base !== undefined) {
|
|
38
|
+
return refuse('BASE_SCOPE', `Every ship holds ${base}: it is never revoked`);
|
|
39
|
+
}
|
|
40
|
+
const added = [...new Set(input.grant)].filter((scope) => !ship.scopes.includes(scope));
|
|
41
|
+
const removed = ship.scopes.filter((scope) => input.revoke.includes(scope));
|
|
42
|
+
if (added.length === 0 && removed.length === 0) {
|
|
43
|
+
return ok({ ship, events: [] });
|
|
44
|
+
}
|
|
45
|
+
const changed = { ...ship, scopes: [...ship.scopes.filter((scope) => !removed.includes(scope)), ...added] };
|
|
46
|
+
return ok({
|
|
47
|
+
ship: changed,
|
|
48
|
+
events: [{ fleetId: ship.fleetId, type: 'ScopesChanged', occurredAt: at, actor, shipId: ship.id, details: { added: added.join(' '), removed: removed.join(' ') } }],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Whether the granter may grant or revoke the scope, at commission or on a
|
|
53
|
+
* live ship: a core scope it holds, or a declared plugin scope when it is
|
|
54
|
+
* argo or the declarer.
|
|
55
|
+
*/
|
|
56
|
+
export function mayGrant(scope, at) {
|
|
57
|
+
const { granter, namespaces } = at;
|
|
58
|
+
if (!scopeNameSchema.safeParse(scope).success) {
|
|
59
|
+
return refuse('INVALID_SCOPE', `${scope} is no scope: a core scope, or a plugin's <namespace>:<action>`);
|
|
60
|
+
}
|
|
61
|
+
if (scopeSchema.safeParse(scope).success) {
|
|
62
|
+
return granter.kind === 'operator' || granter.scopes.includes(scope) ? ok(null) : refuse('SCOPE_NOT_HELD', `Your ship does not hold ${scope}, so it cannot grant it`);
|
|
63
|
+
}
|
|
64
|
+
const namespace = scope.slice(0, scope.indexOf(':'));
|
|
65
|
+
const declared = namespaces.get(namespace);
|
|
66
|
+
if (declared?.namespace.scopes.some((each) => each.scope === scope) !== true) {
|
|
67
|
+
return refuse('SCOPE_NOT_DECLARED', `No plugin declared ${scope}`);
|
|
68
|
+
}
|
|
69
|
+
if (granter.kind !== 'operator' && declared.namespace.declaredBy !== granter.shipId) {
|
|
70
|
+
return refuse('PLUGIN_SCOPE_NOT_YOURS', `Only argo and ${declared.declarerName}, which declared ${namespace}, grant ${scope}`);
|
|
71
|
+
}
|
|
72
|
+
return ok(null);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=scope-grant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-grant.js","sourceRoot":"","sources":["../../../src/domain/registry/scope-grant.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type FleetId, type ScopeName, type ShipId } from '@aeolus-fleet/common';
|
|
2
|
+
import { type DomainError } from '../shared/errors.js';
|
|
3
|
+
import type { Actor, NewEvent } from '../shared/events.js';
|
|
4
|
+
import { type Result } from '../shared/result.js';
|
|
5
|
+
import type { Ship } from './ship.js';
|
|
6
|
+
/** One scope a plugin declared, with its one-line description. */
|
|
7
|
+
export interface DeclaredScope {
|
|
8
|
+
scope: ScopeName;
|
|
9
|
+
description: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A plugin's namespace (decision 0046): taken up for good by the ship that
|
|
13
|
+
* declared it, one per ship and unique in the fleet, with its whole list of
|
|
14
|
+
* scopes. Core stores and answers them and never checks them; the plugin
|
|
15
|
+
* enforces them. It goes when its declarer retires.
|
|
16
|
+
*/
|
|
17
|
+
export interface ScopeNamespace {
|
|
18
|
+
fleetId: FleetId;
|
|
19
|
+
namespace: string;
|
|
20
|
+
declaredBy: ShipId;
|
|
21
|
+
/** In the order the declarer gave them, each once. */
|
|
22
|
+
scopes: readonly DeclaredScope[];
|
|
23
|
+
}
|
|
24
|
+
export type DeclareScopesRefusal = DomainError<'INVALID_SCOPE' | 'INVALID_SCOPE_DESCRIPTION' | 'CORE_NAMESPACE' | 'NAMESPACE_TAKEN' | 'SECOND_NAMESPACE' | 'TOO_MANY_SCOPES' | 'SCOPE_HELD'>;
|
|
25
|
+
/**
|
|
26
|
+
* A ship declares its namespace with its whole list of scopes, the first
|
|
27
|
+
* time or again (decision 0046). Refused: a malformed namespace or scope, a
|
|
28
|
+
* scope of another namespace or twice, a description not on one line, a core
|
|
29
|
+
* namespace, a namespace another ship took, a second namespace, more than 20
|
|
30
|
+
* scopes, and removing a scope an active ship holds. Writes ScopesDeclared.
|
|
31
|
+
*/
|
|
32
|
+
export declare function declareScopes(input: {
|
|
33
|
+
fleetId: FleetId;
|
|
34
|
+
declarer: ShipId;
|
|
35
|
+
namespace: string;
|
|
36
|
+
scopes: readonly {
|
|
37
|
+
scope: string;
|
|
38
|
+
description: string;
|
|
39
|
+
}[];
|
|
40
|
+
at: Date;
|
|
41
|
+
actor: Actor;
|
|
42
|
+
}, fleet: {
|
|
43
|
+
/** The namespace as the fleet holds it, with its declarer's name, if anyone took it. */
|
|
44
|
+
taken: {
|
|
45
|
+
namespace: ScopeNamespace;
|
|
46
|
+
declarerName: string;
|
|
47
|
+
} | undefined;
|
|
48
|
+
/** The namespace the declaring ship took, if any. */
|
|
49
|
+
ofDeclarer: ScopeNamespace | undefined;
|
|
50
|
+
/** The scopes of this namespace an active ship holds. */
|
|
51
|
+
held: readonly ScopeName[];
|
|
52
|
+
}): Result<{
|
|
53
|
+
namespace: ScopeNamespace;
|
|
54
|
+
events: NewEvent[];
|
|
55
|
+
}, DeclareScopesRefusal>;
|
|
56
|
+
/**
|
|
57
|
+
* The namespace goes with its retiring declarer (decision 0046): each active
|
|
58
|
+
* ship that holds any of its scopes loses them, keeping its other scopes, one
|
|
59
|
+
* ScopesChanged each.
|
|
60
|
+
*/
|
|
61
|
+
export declare function releaseWithDeclarer(namespace: ScopeNamespace, at: {
|
|
62
|
+
holders: readonly Ship[];
|
|
63
|
+
at: Date;
|
|
64
|
+
actor: Actor;
|
|
65
|
+
}): {
|
|
66
|
+
ships: Ship[];
|
|
67
|
+
events: NewEvent[];
|
|
68
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { isCoreNamespace, NAMESPACE_SCOPES_MAX, SCOPE_DESCRIPTION_MAX_LENGTH, SCOPE_NAME_PATTERN, SCOPE_NAMESPACE_PATTERN, } from '@aeolus-fleet/common';
|
|
2
|
+
import { refuse } from '../shared/errors.js';
|
|
3
|
+
import { ok } from '../shared/result.js';
|
|
4
|
+
/**
|
|
5
|
+
* A ship declares its namespace with its whole list of scopes, the first
|
|
6
|
+
* time or again (decision 0046). Refused: a malformed namespace or scope, a
|
|
7
|
+
* scope of another namespace or twice, a description not on one line, a core
|
|
8
|
+
* namespace, a namespace another ship took, a second namespace, more than 20
|
|
9
|
+
* scopes, and removing a scope an active ship holds. Writes ScopesDeclared.
|
|
10
|
+
*/
|
|
11
|
+
export function declareScopes(input, fleet) {
|
|
12
|
+
const { fleetId, declarer, namespace, at, actor } = input;
|
|
13
|
+
if (!SCOPE_NAMESPACE_PATTERN.test(namespace)) {
|
|
14
|
+
return refuse('INVALID_SCOPE', `${namespace} is no namespace: lowercase letters, digits and hyphens, starting with a letter, at most 32 characters`);
|
|
15
|
+
}
|
|
16
|
+
if (isCoreNamespace(namespace)) {
|
|
17
|
+
return refuse('CORE_NAMESPACE', `${namespace} is a core namespace: core alone declares its scopes`);
|
|
18
|
+
}
|
|
19
|
+
if (input.scopes.length > NAMESPACE_SCOPES_MAX) {
|
|
20
|
+
return refuse('TOO_MANY_SCOPES', `A namespace has at most ${String(NAMESPACE_SCOPES_MAX)} scopes`);
|
|
21
|
+
}
|
|
22
|
+
const scopes = declaredScopes(namespace, input.scopes);
|
|
23
|
+
if (!scopes.isOk) {
|
|
24
|
+
return scopes;
|
|
25
|
+
}
|
|
26
|
+
if (fleet.taken !== undefined && fleet.taken.namespace.declaredBy !== declarer) {
|
|
27
|
+
return refuse('NAMESPACE_TAKEN', `The namespace ${namespace} is taken, by ${fleet.taken.declarerName}`);
|
|
28
|
+
}
|
|
29
|
+
if (fleet.ofDeclarer !== undefined && fleet.ofDeclarer.namespace !== namespace) {
|
|
30
|
+
return refuse('SECOND_NAMESPACE', `This ship declared the namespace ${fleet.ofDeclarer.namespace}: a ship takes up one namespace`);
|
|
31
|
+
}
|
|
32
|
+
const kept = new Set(scopes.value.map(({ scope }) => scope));
|
|
33
|
+
const removedHeld = fleet.held.filter((scope) => !kept.has(scope));
|
|
34
|
+
if (removedHeld.length > 0) {
|
|
35
|
+
return refuse('SCOPE_HELD', `Ships hold ${removedHeld.join(', ')}: revoke it from them first`);
|
|
36
|
+
}
|
|
37
|
+
const declared = { fleetId, namespace, declaredBy: declarer, scopes: scopes.value };
|
|
38
|
+
return ok({
|
|
39
|
+
namespace: declared,
|
|
40
|
+
events: [{ fleetId, type: 'ScopesDeclared', occurredAt: at, actor, shipId: declarer, details: { namespace, scopes: declared.scopes.length } }],
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/** The scopes as declared, each of the namespace, once, with a description on one line. */
|
|
44
|
+
function declaredScopes(namespace, scopes) {
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
const declared = [];
|
|
47
|
+
for (const { scope, description } of scopes) {
|
|
48
|
+
if (!SCOPE_NAME_PATTERN.test(scope) || !scope.startsWith(`${namespace}:`)) {
|
|
49
|
+
return refuse('INVALID_SCOPE', `${scope} is no scope of ${namespace}: ${namespace}:<action>`);
|
|
50
|
+
}
|
|
51
|
+
if (seen.has(scope)) {
|
|
52
|
+
return refuse('INVALID_SCOPE', `${scope} is declared twice`);
|
|
53
|
+
}
|
|
54
|
+
if (description.trim() === '' || description.includes('\n') || description.length > SCOPE_DESCRIPTION_MAX_LENGTH) {
|
|
55
|
+
return refuse('INVALID_SCOPE_DESCRIPTION', `The description of ${scope} is one line of 1 to ${String(SCOPE_DESCRIPTION_MAX_LENGTH)} characters`);
|
|
56
|
+
}
|
|
57
|
+
seen.add(scope);
|
|
58
|
+
declared.push({ scope, description });
|
|
59
|
+
}
|
|
60
|
+
return ok(declared);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The namespace goes with its retiring declarer (decision 0046): each active
|
|
64
|
+
* ship that holds any of its scopes loses them, keeping its other scopes, one
|
|
65
|
+
* ScopesChanged each.
|
|
66
|
+
*/
|
|
67
|
+
export function releaseWithDeclarer(namespace, at) {
|
|
68
|
+
const isOfNamespace = (scope) => scope.startsWith(`${namespace.namespace}:`);
|
|
69
|
+
const changed = at.holders.filter((ship) => ship.id !== namespace.declaredBy && ship.scopes.some(isOfNamespace));
|
|
70
|
+
return {
|
|
71
|
+
ships: changed.map((ship) => ({ ...ship, scopes: ship.scopes.filter((scope) => !isOfNamespace(scope)) })),
|
|
72
|
+
events: changed.map((ship) => ({
|
|
73
|
+
fleetId: ship.fleetId,
|
|
74
|
+
type: 'ScopesChanged',
|
|
75
|
+
occurredAt: at.at,
|
|
76
|
+
actor: at.actor,
|
|
77
|
+
shipId: ship.id,
|
|
78
|
+
details: { added: '', removed: ship.scopes.filter(isOfNamespace).join(' ') },
|
|
79
|
+
})),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=scope-namespace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-namespace.js","sourceRoot":"","sources":["../../../src/domain/registry/scope-namespace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IdGenerator, SetBuiltInRuleInput } from '@aeolus-fleet/common';
|
|
2
|
+
import type { Caller } from '../shared/caller.js';
|
|
3
|
+
import type { Clock } from '../shared/clock.js';
|
|
4
|
+
import { type EventLog } from '../shared/events.js';
|
|
5
|
+
import { type Result } from '../shared/result.js';
|
|
6
|
+
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
7
|
+
import { type SetBuiltInRuleRefusal } from './network-settings.js';
|
|
8
|
+
import type { NetworkSettingsRepository } from './ports.js';
|
|
9
|
+
export interface SetBuiltInRuleTx {
|
|
10
|
+
networkSettings: Pick<NetworkSettingsRepository, 'findForUpdate' | 'save'>;
|
|
11
|
+
events: EventLog;
|
|
12
|
+
}
|
|
13
|
+
export type SetBuiltInRule = (caller: Caller, input: SetBuiltInRuleInput) => Promise<Result<{
|
|
14
|
+
version: number;
|
|
15
|
+
}, SetBuiltInRuleRefusal>>;
|
|
16
|
+
/**
|
|
17
|
+
* Use case: a built-in rule turned on or off (decision 0034): the viewer
|
|
18
|
+
* reading by argo, open for one verb by the fleet's networking plugin. Its
|
|
19
|
+
* scope (fleet:network, which argo holds) is checked before this runs. In one
|
|
20
|
+
* unit of work, holding the settings exclusively so no send is checked
|
|
21
|
+
* halfway: the settings at their next version, and BuiltInRuleChanged. A rule
|
|
22
|
+
* already as asked answers the version it has.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createSetBuiltInRule(deps: {
|
|
25
|
+
uow: UnitOfWork<SetBuiltInRuleTx>;
|
|
26
|
+
clock: Clock;
|
|
27
|
+
ids: IdGenerator;
|
|
28
|
+
}): SetBuiltInRule;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { recordEvent, shipActor } from '../shared/events.js';
|
|
2
|
+
import { ok } from '../shared/result.js';
|
|
3
|
+
import { setBuiltInRule } from './network-settings.js';
|
|
4
|
+
/**
|
|
5
|
+
* Use case: a built-in rule turned on or off (decision 0034): the viewer
|
|
6
|
+
* reading by argo, open for one verb by the fleet's networking plugin. Its
|
|
7
|
+
* scope (fleet:network, which argo holds) is checked before this runs. In one
|
|
8
|
+
* unit of work, holding the settings exclusively so no send is checked
|
|
9
|
+
* halfway: the settings at their next version, and BuiltInRuleChanged. A rule
|
|
10
|
+
* already as asked answers the version it has.
|
|
11
|
+
*/
|
|
12
|
+
export function createSetBuiltInRule(deps) {
|
|
13
|
+
return (caller, input) => deps.uow.run(async (tx) => {
|
|
14
|
+
const current = await tx.networkSettings.findForUpdate(caller.fleetId);
|
|
15
|
+
const set = setBuiltInRule(current, {
|
|
16
|
+
input,
|
|
17
|
+
caller: { shipId: caller.shipId, isOperator: caller.kind === 'operator' },
|
|
18
|
+
at: deps.clock.now(),
|
|
19
|
+
actor: shipActor(caller.shipId),
|
|
20
|
+
});
|
|
21
|
+
if (!set.isOk) {
|
|
22
|
+
return set;
|
|
23
|
+
}
|
|
24
|
+
if (set.value.events.length > 0) {
|
|
25
|
+
await tx.networkSettings.save(set.value.settings);
|
|
26
|
+
}
|
|
27
|
+
for (const event of set.value.events) {
|
|
28
|
+
await recordEvent({ events: tx.events, ids: deps.ids }, event);
|
|
29
|
+
}
|
|
30
|
+
return ok({ version: set.value.settings.version });
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=set-built-in-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-built-in-rule.js","sourceRoot":"","sources":["../../../src/domain/registry/set-built-in-rule.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAiB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAA8B,MAAM,uBAAuB,CAAC;AAUnF;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAA2E;IAC9G,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAA+D,EAAE;QACrF,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvE,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,EAAE;YAClC,KAAK;YACL,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE;YACzE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YACpB,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,GAAG,CAAC;QACb,CAAC;QACD,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -12,13 +12,13 @@ export interface SetNetworkRulesTx {
|
|
|
12
12
|
events: EventLog;
|
|
13
13
|
}
|
|
14
14
|
export type SetNetworkRules = (caller: Caller, input: {
|
|
15
|
-
rules: readonly NetworkRule[]
|
|
15
|
+
rules: readonly NetworkRule[];
|
|
16
16
|
}) => Promise<Result<{
|
|
17
17
|
version: number;
|
|
18
18
|
}, SetNetworkRulesRefusal>>;
|
|
19
19
|
/**
|
|
20
|
-
* Use case: the caller sets the fleet's network rules, the whole list
|
|
21
|
-
*
|
|
20
|
+
* Use case: the caller sets the fleet's network rules, the whole list beside
|
|
21
|
+
* the built-in ones (decision 0034), argo's with the rules the fleet's
|
|
22
22
|
* ships declared added (decision 0037), which the limit counts. Its scope (fleet:network, which argo
|
|
23
23
|
* holds) is checked before this runs. In one unit of work, holding the
|
|
24
24
|
* settings exclusively so no send is checked halfway: the settings at their
|
|
@@ -2,8 +2,8 @@ import { recordEvent, shipActor } from '../shared/events.js';
|
|
|
2
2
|
import { ok } from '../shared/result.js';
|
|
3
3
|
import { setNetworkRules } from './network-settings.js';
|
|
4
4
|
/**
|
|
5
|
-
* Use case: the caller sets the fleet's network rules, the whole list
|
|
6
|
-
*
|
|
5
|
+
* Use case: the caller sets the fleet's network rules, the whole list beside
|
|
6
|
+
* the built-in ones (decision 0034), argo's with the rules the fleet's
|
|
7
7
|
* ships declared added (decision 0037), which the limit counts. Its scope (fleet:network, which argo
|
|
8
8
|
* holds) is checked before this runs. In one unit of work, holding the
|
|
9
9
|
* settings exclusively so no send is checked halfway: the settings at their
|