@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declared-network-rules.js","sourceRoot":"","sources":["../../../src/domain/registry/declared-network-rules.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,0BAA0B,
|
|
1
|
+
{"version":3,"file":"declared-network-rules.js","sourceRoot":"","sources":["../../../src/domain/registry/declared-network-rules.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,0BAA0B,EAAE,WAAW,EAA8E,MAAM,sBAAsB,CAAC;AAE3J,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAiB5F,qHAAqH;AACrH,MAAM,UAAU,YAAY,CAAC,KAA6B;IACxD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,OAAO;QACL,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvH,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;KAC1F,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAkB,EAClB,MAAmG;IAEnG,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAC1C,IAAI,KAAK,CAAC,MAAM,GAAG,0BAA0B,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC,uBAAuB,EAAE,2BAA2B,MAAM,CAAC,0BAA0B,CAAC,gCAAgC,CAAC,CAAC;IACxI,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAC9E,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,uBAAuB,EAAE,GAAG,OAAO,kBAAkB,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,uBAAuB,EAAE,6DAA6D,QAAQ,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAC;IACpK,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAqB,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACjF,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAChB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AACpL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAyC,EACzC,MAAkC;IAElC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACpC,OAAO,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;AACzH,CAAC;AAED,SAAS,aAAa,CAAC,QAAqF;IAC1G,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;AAClL,CAAC;AAED,SAAS,cAAc,CAAC,KAAkB,EAAE,SAA8C;IACxF,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACnC,MAAM,KAAK,GACT,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC;IACjK,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,uBAAuB,EAAE,gCAAgC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAClL,CAAC;IACD,OAAO,KAAK,CAAC,WAAW,KAAK,MAAM;QACjC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC;QACf,CAAC,CAAC,MAAM,CAAC,qBAAqB,EAAE,aAAa,KAAK,CAAC,GAAG,gBAAgB,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,uDAAuD,CAAC,CAAC;AACvK,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Discovered } from '@aeolus-fleet/common';
|
|
2
|
+
import type { Caller } from '../shared/caller.js';
|
|
3
|
+
import type { Clock } from '../shared/clock.js';
|
|
4
|
+
import { type Result } from '../shared/result.js';
|
|
5
|
+
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
6
|
+
import { type CheckReachTx } from './check-reach.js';
|
|
7
|
+
import type { LeaseRepository, ShipRepository } from './ports.js';
|
|
8
|
+
export interface DiscoverTx {
|
|
9
|
+
networkSettings: CheckReachTx['networkSettings'];
|
|
10
|
+
ships: Pick<ShipRepository, 'find' | 'listActive'>;
|
|
11
|
+
labels: CheckReachTx['labels'];
|
|
12
|
+
leases: Pick<LeaseRepository, 'findLastSeen' | 'listOpenStatements'>;
|
|
13
|
+
}
|
|
14
|
+
export type Discover = (caller: Caller) => Promise<Result<Discovered, never>>;
|
|
15
|
+
/**
|
|
16
|
+
* Use case: a ship asks which ships and types it may send to now (decision
|
|
17
|
+
* 0047), its scope (messages:send) checked before this runs. Each active
|
|
18
|
+
* ship but the caller and the viewer is checked as a send to it would be at
|
|
19
|
+
* this moment (decision 0034): the rules in force, what the networking plugin
|
|
20
|
+
* declared while it does not respond, the built-in rules; there is no message,
|
|
21
|
+
* so no answer to a sender. Each reached ship comes with its name, type, kind,
|
|
22
|
+
* status and statement, and each type with how many of its ships it reaches.
|
|
23
|
+
* Ships, never rules; it records nothing, a refusal included.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createDiscover(deps: {
|
|
26
|
+
uow: UnitOfWork<DiscoverTx>;
|
|
27
|
+
clock: Clock;
|
|
28
|
+
}): Discover;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ok } from '../shared/result.js';
|
|
2
|
+
import { reaching, rulesInForceAt, shipAsItIs } from './check-reach.js';
|
|
3
|
+
import { allowsReach } from './network-settings.js';
|
|
4
|
+
import { discoveredStatementOf } from './statement.js';
|
|
5
|
+
/**
|
|
6
|
+
* Use case: a ship asks which ships and types it may send to now (decision
|
|
7
|
+
* 0047), its scope (messages:send) checked before this runs. Each active
|
|
8
|
+
* ship but the caller and the viewer is checked as a send to it would be at
|
|
9
|
+
* this moment (decision 0034): the rules in force, what the networking plugin
|
|
10
|
+
* declared while it does not respond, the built-in rules; there is no message,
|
|
11
|
+
* so no answer to a sender. Each reached ship comes with its name, type, kind,
|
|
12
|
+
* status and statement, and each type with how many of its ships it reaches.
|
|
13
|
+
* Ships, never rules; it records nothing, a refusal included.
|
|
14
|
+
*/
|
|
15
|
+
export function createDiscover(deps) {
|
|
16
|
+
return (caller) => deps.uow.run(async (tx) => {
|
|
17
|
+
const { fleetId } = caller;
|
|
18
|
+
const settings = await tx.networkSettings.findForShare(fleetId);
|
|
19
|
+
const inForce = await rulesInForceAt(tx, { settings, now: deps.clock.now() });
|
|
20
|
+
const active = await tx.ships.listActive(fleetId);
|
|
21
|
+
const callerShip = active.find((ship) => ship.id === caller.shipId);
|
|
22
|
+
const sender = callerShip === undefined ? undefined : reaching(await shipAsItIs(tx, callerShip));
|
|
23
|
+
const crews = new Map((await tx.leases.listOpenStatements(fleetId)).map(({ shipId, stated }) => [shipId, stated]));
|
|
24
|
+
const ships = [];
|
|
25
|
+
for (const ship of active) {
|
|
26
|
+
if (ship.id === caller.shipId || ship.kind === 'viewer' || sender === undefined) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const recipient = reaching(await shipAsItIs(tx, ship));
|
|
30
|
+
if (!allowsReach(inForce, { verb: 'send', sender, recipient, isAnswerToSender: false })) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const isCrewed = ship.kind === 'operator' || crews.has(ship.id);
|
|
34
|
+
ships.push({
|
|
35
|
+
id: ship.id,
|
|
36
|
+
name: ship.name,
|
|
37
|
+
type: ship.type,
|
|
38
|
+
kind: ship.kind,
|
|
39
|
+
status: isCrewed ? 'crewed' : 'awaitingCrew',
|
|
40
|
+
statement: discoveredStatementOf(ship, crews.get(ship.id) ?? null),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return ok({ ships, types: typesOf(ships) });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/** Each type of the reached ships with how many of them, in the order the ships come. */
|
|
47
|
+
function typesOf(ships) {
|
|
48
|
+
const counts = new Map();
|
|
49
|
+
for (const ship of ships) {
|
|
50
|
+
counts.set(ship.type, (counts.get(ship.type) ?? 0) + 1);
|
|
51
|
+
}
|
|
52
|
+
return [...counts].map(([type, reachable]) => ({ type, reachable }));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/domain/registry/discover.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAqB,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAWvD;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,IAAmD;IAChF,OAAO,CAAC,MAAM,EAAE,EAAE,CAChB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAsC,EAAE;QAC5D,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;QACjG,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QACnH,MAAM,KAAK,GAAwB,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;YAC1B,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAChF,SAAS;YACX,CAAC;YACD,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;YACvD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;gBACxF,SAAS;YACX,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChE,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc;gBAC5C,SAAS,EAAE,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;aACnE,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACP,CAAC;AAED,yFAAyF;AACzF,SAAS,OAAO,CAAC,KAA0B;IACzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ExplainedReach, type ShipId } from '@aeolus-fleet/common';
|
|
2
2
|
import type { Caller } from '../shared/caller.js';
|
|
3
3
|
import type { Clock } from '../shared/clock.js';
|
|
4
4
|
import { type DomainError } from '../shared/errors.js';
|
|
5
5
|
import { type Result } from '../shared/result.js';
|
|
6
6
|
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
7
7
|
import { type CheckReachTx } from './check-reach.js';
|
|
8
|
-
import type { ShipRepository } from './ports.js';
|
|
8
|
+
import type { DeclaredNetworkRulesRepository, ShipRepository } from './ports.js';
|
|
9
9
|
export interface ExplainReachTx {
|
|
10
10
|
networkSettings: CheckReachTx['networkSettings'];
|
|
11
11
|
ships: Pick<ShipRepository, 'find' | 'listActive'>;
|
|
12
12
|
labels: CheckReachTx['labels'];
|
|
13
13
|
leases: CheckReachTx['leases'];
|
|
14
|
+
declaredNetworkRules: Pick<DeclaredNetworkRulesRepository, 'list'>;
|
|
14
15
|
}
|
|
15
16
|
export type ExplainReachFailure = DomainError<'NOT_THE_OPERATOR_SHIP' | 'SHIP_NOT_FOUND'>;
|
|
16
17
|
export type ExplainReach = (caller: Caller, input: {
|
|
17
18
|
fromShipId: ShipId;
|
|
18
19
|
toShipId?: ShipId;
|
|
19
|
-
}) => Promise<Result<
|
|
20
|
-
reachableShipIds: ShipId[];
|
|
21
|
-
}, ExplainReachFailure>>;
|
|
20
|
+
}) => Promise<Result<ExplainedReach, ExplainReachFailure>>;
|
|
22
21
|
/**
|
|
23
|
-
* Use case: argo asks which ships a ship reaches now, or whether it
|
|
24
|
-
* one ship (
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
22
|
+
* Use case: argo asks which ships a ship reaches now, per verb, or whether it
|
|
23
|
+
* reaches one ship (decision 0034). It answers as a send would be checked at
|
|
24
|
+
* this moment: the rules in force, what the networking plugin declared while
|
|
25
|
+
* it does not respond, the built-in rules. Each ship comes with the rule that
|
|
26
|
+
* allows it: a built-in rule, a rule the plugin supplied, or a rule a ship
|
|
27
|
+
* declared, named by its declarer, when the plugin supplied it as declared.
|
|
28
|
+
* There is no message, so no answer to a sender. It records nothing: an
|
|
29
|
+
* explain is not a send. Only argo.
|
|
30
30
|
*/
|
|
31
31
|
export declare function createExplainReach(deps: {
|
|
32
32
|
uow: UnitOfWork<ExplainReachTx>;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { NETWORK_VERBS } from '@aeolus-fleet/common';
|
|
1
2
|
import { refuse } from '../shared/errors.js';
|
|
2
3
|
import { ok } from '../shared/result.js';
|
|
3
4
|
import { reaching, rulesInForceAt, shipAsItIs } from './check-reach.js';
|
|
4
|
-
import {
|
|
5
|
+
import { reachRuleOf } from './network-settings.js';
|
|
5
6
|
/**
|
|
6
|
-
* Use case: argo asks which ships a ship reaches now, or whether it
|
|
7
|
-
* one ship (
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
7
|
+
* Use case: argo asks which ships a ship reaches now, per verb, or whether it
|
|
8
|
+
* reaches one ship (decision 0034). It answers as a send would be checked at
|
|
9
|
+
* this moment: the rules in force, what the networking plugin declared while
|
|
10
|
+
* it does not respond, the built-in rules. Each ship comes with the rule that
|
|
11
|
+
* allows it: a built-in rule, a rule the plugin supplied, or a rule a ship
|
|
12
|
+
* declared, named by its declarer, when the plugin supplied it as declared.
|
|
13
|
+
* There is no message, so no answer to a sender. It records nothing: an
|
|
14
|
+
* explain is not a send. Only argo.
|
|
13
15
|
*/
|
|
14
16
|
export function createExplainReach(deps) {
|
|
15
17
|
return (caller, input) => deps.uow.run(async (tx) => {
|
|
@@ -28,15 +30,36 @@ export function createExplainReach(deps) {
|
|
|
28
30
|
}
|
|
29
31
|
const settings = await tx.networkSettings.findForShare(fleetId);
|
|
30
32
|
const inForce = await rulesInForceAt(tx, { settings, now: deps.clock.now() });
|
|
33
|
+
const declared = await tx.declaredNetworkRules.list(fleetId);
|
|
31
34
|
const sender = reaching(await shipAsItIs(tx, from));
|
|
32
|
-
const
|
|
35
|
+
const explained = { send: [], read: [], manage: [] };
|
|
33
36
|
for (const ship of others) {
|
|
34
37
|
const recipient = reaching(await shipAsItIs(tx, ship));
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
for (const verb of NETWORK_VERBS) {
|
|
39
|
+
const rule = reachRuleOf(inForce, { verb, sender, recipient, isAnswerToSender: false });
|
|
40
|
+
if (rule !== undefined) {
|
|
41
|
+
explained[verb].push({ shipId: ship.id, rule: namedRule(rule, { rules: inForce.rules, declared }) });
|
|
42
|
+
}
|
|
37
43
|
}
|
|
38
44
|
}
|
|
39
|
-
return ok(
|
|
45
|
+
return ok(explained);
|
|
40
46
|
});
|
|
41
47
|
}
|
|
48
|
+
/** A rule of the settings named as argo reads it: a declared one by its declarer and its place in that ship's list, any other as the plugin's. */
|
|
49
|
+
function namedRule(rule, held) {
|
|
50
|
+
if ('builtIn' in rule) {
|
|
51
|
+
return rule;
|
|
52
|
+
}
|
|
53
|
+
const text = ruleText(held.rules[rule.index]);
|
|
54
|
+
for (const { shipId, rules } of held.declared) {
|
|
55
|
+
const index = rules.findIndex((each) => ruleText(each) === text);
|
|
56
|
+
if (index !== -1) {
|
|
57
|
+
return { declared: shipId, index };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { plugin: rule.index };
|
|
61
|
+
}
|
|
62
|
+
function ruleText(rule) {
|
|
63
|
+
return JSON.stringify(rule === undefined ? null : [rule.verb, rule.from, rule.to]);
|
|
64
|
+
}
|
|
42
65
|
//# sourceMappingURL=explain-reach.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain-reach.js","sourceRoot":"","sources":["../../../src/domain/registry/explain-reach.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"explain-reach.js","sourceRoot":"","sources":["../../../src/domain/registry/explain-reach.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,8 @@ import type { ShipId } from '@aeolus-fleet/common';
|
|
|
2
2
|
import type { Caller } from '../shared/caller.js';
|
|
3
3
|
import { type DomainError } from '../shared/errors.js';
|
|
4
4
|
import { type Result } from '../shared/result.js';
|
|
5
|
-
import { type ListedShip } from './list-fleet.js';
|
|
5
|
+
import { type ListedShip, type ShipOutsideReadReach } from './list-fleet.js';
|
|
6
|
+
import { type ReadReachOf } from './read-reach.js';
|
|
6
7
|
import { type CrewRequest } from './crew-request.js';
|
|
7
8
|
import type { FleetListing } from './ports.js';
|
|
8
9
|
import { type ShownReport } from './ship-report.js';
|
|
@@ -19,16 +20,23 @@ export interface ShipDetail extends Omit<ListedShip, 'report' | 'crewRequest'> {
|
|
|
19
20
|
inFlightDeliveries: number;
|
|
20
21
|
/** Its direct deliveries pending or in flight: what a retire abandons. */
|
|
21
22
|
openDeliveries: number;
|
|
23
|
+
/** Its owner by id and name; null for argo and the viewer (decision 0045). */
|
|
24
|
+
owner: {
|
|
25
|
+
id: ShipId;
|
|
26
|
+
name: string;
|
|
27
|
+
} | null;
|
|
22
28
|
}
|
|
23
29
|
export type GetShip = (caller: Caller, input: {
|
|
24
30
|
shipId: ShipId;
|
|
25
|
-
}) => Promise<Result<ShipDetail, DomainError<'SHIP_NOT_FOUND' | 'CREW_REQUEST_NOT_ASSIGNED_TO_CALLER'>>>;
|
|
31
|
+
}) => Promise<Result<ShipDetail | ShipOutsideReadReach, DomainError<'SHIP_NOT_FOUND' | 'CREW_REQUEST_NOT_ASSIGNED_TO_CALLER'>>>;
|
|
26
32
|
/**
|
|
27
33
|
* Use case: one ship of the caller's fleet, retired ships included: they keep
|
|
28
34
|
* their page. The caller's scope (fleet:read or crew:run) is
|
|
29
35
|
* checked before this runs; crew:run reads only the ships whose crew requests
|
|
30
|
-
* are assigned to the caller's ship.
|
|
36
|
+
* are assigned to the caller's ship, whole. Any other ship outside the
|
|
37
|
+
* caller's read reach shows its name, type and status only (decision 0034).
|
|
31
38
|
*/
|
|
32
39
|
export declare function createGetShip(deps: {
|
|
33
40
|
listing: FleetListing;
|
|
41
|
+
readReach: ReadReachOf;
|
|
34
42
|
}): GetShip;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { refuse } from '../shared/errors.js';
|
|
2
2
|
import { ok } from '../shared/result.js';
|
|
3
|
-
import { listedShipOf } from './list-fleet.js';
|
|
3
|
+
import { listedShipOf, outsideReadReach } from './list-fleet.js';
|
|
4
|
+
import { readsShip } from './read-reach.js';
|
|
4
5
|
import { checkReaches } from './crew-request.js';
|
|
5
6
|
import { shownReportOf } from './ship-report.js';
|
|
6
7
|
/** The scopes that read every ship; crew:run reads only the ships assigned to the caller's ship. */
|
|
@@ -9,7 +10,8 @@ const READ_SCOPES = ['fleet:read'];
|
|
|
9
10
|
* Use case: one ship of the caller's fleet, retired ships included: they keep
|
|
10
11
|
* their page. The caller's scope (fleet:read or crew:run) is
|
|
11
12
|
* checked before this runs; crew:run reads only the ships whose crew requests
|
|
12
|
-
* are assigned to the caller's ship.
|
|
13
|
+
* are assigned to the caller's ship, whole. Any other ship outside the
|
|
14
|
+
* caller's read reach shows its name, type and status only (decision 0034).
|
|
13
15
|
*/
|
|
14
16
|
export function createGetShip(deps) {
|
|
15
17
|
return async (caller, { shipId }) => {
|
|
@@ -22,6 +24,9 @@ export function createGetShip(deps) {
|
|
|
22
24
|
return reaches;
|
|
23
25
|
}
|
|
24
26
|
const listed = listedShipOf(facts);
|
|
27
|
+
if (facts.crewRequest?.assignedTo !== caller.shipId && !readsShip(await deps.readReach(caller), shipId)) {
|
|
28
|
+
return ok(outsideReadReach(listed));
|
|
29
|
+
}
|
|
25
30
|
const counts = await deps.listing.deliveryCounts(caller.fleetId, shipId);
|
|
26
31
|
return ok({
|
|
27
32
|
...listed,
|
|
@@ -31,6 +36,7 @@ export function createGetShip(deps) {
|
|
|
31
36
|
openDeliveries: counts.open,
|
|
32
37
|
commissionedAt: facts.ship.createdAt,
|
|
33
38
|
crewedSince: facts.openLease?.startedAt ?? null,
|
|
39
|
+
owner: facts.owner,
|
|
34
40
|
});
|
|
35
41
|
};
|
|
36
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-ship.js","sourceRoot":"","sources":["../../../src/domain/registry/get-ship.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"get-ship.js","sourceRoot":"","sources":["../../../src/domain/registry/get-ship.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAA8C,MAAM,iBAAiB,CAAC;AAC7G,OAAO,EAAE,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAoB,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAoB,MAAM,kBAAkB,CAAC;AAwBnE,oGAAoG;AACpG,MAAM,WAAW,GAAG,CAAC,YAAY,CAAU,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAuD;IACnF,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,MAAM,CAAC,gBAAgB,EAAE,WAAW,MAAM,gBAAgB,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;QACjH,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,WAAW,EAAE,UAAU,KAAK,MAAM,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;YACxG,OAAO,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzE,OAAO,EAAE,CAAC;YACR,GAAG,MAAM;YACT,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;YAC9E,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,IAAI,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE;YACvH,kBAAkB,EAAE,MAAM,CAAC,QAAQ;YACnC,cAAc,EAAE,MAAM,CAAC,IAAI;YAC3B,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS;YACpC,WAAW,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,IAAI,IAAI;YAC/C,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -5,17 +5,33 @@ 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 NotReachable } from './check-reach.js';
|
|
9
|
+
import { type ManagedOrAssignedTx } from './managed-or-assigned.js';
|
|
8
10
|
import type { CrewRequestRepository, LeaseRepository, ShipRepository } from './ports.js';
|
|
9
11
|
import { type IssuedStartingPrompt, type StartingPromptTx } from './starting-prompt.js';
|
|
10
|
-
export interface GetStartingPromptTx extends StartingPromptTx {
|
|
12
|
+
export interface GetStartingPromptTx extends StartingPromptTx, Omit<ManagedOrAssignedTx, 'ships' | 'leases' | 'crewRequests'> {
|
|
11
13
|
ships: ShipRepository;
|
|
12
14
|
leases: LeaseRepository;
|
|
13
15
|
crewRequests: Pick<CrewRequestRepository, 'find'>;
|
|
14
16
|
}
|
|
15
|
-
export type GetStartingPromptRefusal = DomainError<'SHIP_NOT_FOUND' | 'OPERATOR_SHIP_GETS_NO_STARTING_PROMPT' | 'SHIP_NOT_AWAITING_CREW' | 'CREW_REQUEST_NOT_ASSIGNED_TO_CALLER'
|
|
17
|
+
export type GetStartingPromptRefusal = DomainError<'SHIP_NOT_FOUND' | 'OPERATOR_SHIP_GETS_NO_STARTING_PROMPT' | 'SHIP_NOT_AWAITING_CREW' | 'CREW_REQUEST_NOT_ASSIGNED_TO_CALLER'> | NotReachable;
|
|
16
18
|
export type GetStartingPrompt = (caller: Caller, input: {
|
|
17
19
|
shipId: ShipId;
|
|
18
20
|
}) => Promise<Result<IssuedStartingPrompt, GetStartingPromptRefusal>>;
|
|
21
|
+
/**
|
|
22
|
+
* Use case: a new starting prompt for a ship of the caller's fleet that awaits
|
|
23
|
+
* crew. Its new secret invalidates any earlier one, so at most one is valid; a
|
|
24
|
+
* prompt lost before use costs nothing. The caller's scope (fleet:manage or
|
|
25
|
+
* crew:run) is checked before this runs; crew:run reaches only
|
|
26
|
+
* the ships whose crew requests are assigned to the caller's ship, and
|
|
27
|
+
* fleet:manage the ships in its manage reach (decision 0034).
|
|
28
|
+
*
|
|
29
|
+
* Locks in the fleet's order: the ship first, so concurrent prompts for one
|
|
30
|
+
* ship take turns and the last one issued is the valid one; then its secret;
|
|
31
|
+
* then its lease. The lease is read last, so a session that claimed the ship
|
|
32
|
+
* with the old secret meanwhile is seen, and the refusal rolls the revocation
|
|
33
|
+
* back.
|
|
34
|
+
*/
|
|
19
35
|
export declare function createGetStartingPrompt(deps: {
|
|
20
36
|
uow: UnitOfWork<GetStartingPromptTx>;
|
|
21
37
|
clock: Clock;
|
|
@@ -2,7 +2,8 @@ import { revokeShipSecret } from '../identity/public.js';
|
|
|
2
2
|
import { refuse } from '../shared/errors.js';
|
|
3
3
|
import { shipActor } from '../shared/events.js';
|
|
4
4
|
import { ok } from '../shared/result.js';
|
|
5
|
-
import {
|
|
5
|
+
import { keepingReachRefusal } from './check-reach.js';
|
|
6
|
+
import { checkManagedOrAssigned } from './managed-or-assigned.js';
|
|
6
7
|
import { checkCanIssueStartingPrompt } from './ship.js';
|
|
7
8
|
import { issueStartingPrompt } from './starting-prompt.js';
|
|
8
9
|
/**
|
|
@@ -10,7 +11,8 @@ import { issueStartingPrompt } from './starting-prompt.js';
|
|
|
10
11
|
* crew. Its new secret invalidates any earlier one, so at most one is valid; a
|
|
11
12
|
* prompt lost before use costs nothing. The caller's scope (fleet:manage or
|
|
12
13
|
* crew:run) is checked before this runs; crew:run reaches only
|
|
13
|
-
* the ships whose crew requests are assigned to the caller's ship
|
|
14
|
+
* the ships whose crew requests are assigned to the caller's ship, and
|
|
15
|
+
* fleet:manage the ships in its manage reach (decision 0034).
|
|
14
16
|
*
|
|
15
17
|
* Locks in the fleet's order: the ship first, so concurrent prompts for one
|
|
16
18
|
* ship take turns and the last one issued is the valid one; then its secret;
|
|
@@ -18,21 +20,19 @@ import { issueStartingPrompt } from './starting-prompt.js';
|
|
|
18
20
|
* with the old secret meanwhile is seen, and the refusal rolls the revocation
|
|
19
21
|
* back.
|
|
20
22
|
*/
|
|
21
|
-
/** The scopes that reach every ship for a starting prompt; crew:run reaches only assigned ones. */
|
|
22
|
-
const PROMPT_SCOPES = ['fleet:manage'];
|
|
23
23
|
export function createGetStartingPrompt(deps) {
|
|
24
|
-
return (caller, { shipId }) => deps.uow
|
|
24
|
+
return (caller, { shipId }) => keepingReachRefusal(deps.uow, async (tx) => {
|
|
25
25
|
const { fleetId } = caller;
|
|
26
26
|
const ship = await tx.ships.findForUpdate(fleetId, shipId);
|
|
27
27
|
if (!ship) {
|
|
28
28
|
return refuse('SHIP_NOT_FOUND', `Ship ${shipId} does not exist`);
|
|
29
29
|
}
|
|
30
|
-
const
|
|
30
|
+
const at = deps.clock.now();
|
|
31
|
+
const reaches = await checkManagedOrAssigned({ tx, ids: deps.ids }, { caller, ship, at });
|
|
31
32
|
if (!reaches.isOk) {
|
|
32
33
|
return reaches;
|
|
33
34
|
}
|
|
34
35
|
const actor = shipActor(caller.shipId);
|
|
35
|
-
const at = deps.clock.now();
|
|
36
36
|
await revokeShipSecret({ tx, ids: deps.ids }, { fleetId, shipId, actor, at });
|
|
37
37
|
const lease = await tx.leases.findOpenForUpdate(fleetId, shipId);
|
|
38
38
|
const allowed = checkCanIssueStartingPrompt(ship, { isCrewed: lease !== undefined });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-starting-prompt.js","sourceRoot":"","sources":["../../../src/domain/registry/get-starting-prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAG3E,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"get-starting-prompt.js","sourceRoot":"","sources":["../../../src/domain/registry/get-starting-prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAG3E,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAqB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAA4B,MAAM,0BAA0B,CAAC;AAE5F,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAoD,MAAM,sBAAsB,CAAC;AAiB7G;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAKvC;IACC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAC5B,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,EAAmE,EAAE;QAC1G,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,MAAM,CAAC,gBAAgB,EAAE,QAAQ,MAAM,iBAAiB,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1F,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9E,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,2BAA2B,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC;QACrF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,mBAAmB,CACtC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EACnD,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAC/B,CAAC;QACF,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { IdGenerator, ShipId } from '@aeolus-fleet/common';
|
|
2
|
+
import type { Caller } from '../shared/caller.js';
|
|
3
|
+
import type { Clock } from '../shared/clock.js';
|
|
4
|
+
import { type DomainError } from '../shared/errors.js';
|
|
5
|
+
import { type EventLog } from '../shared/events.js';
|
|
6
|
+
import { type Result } from '../shared/result.js';
|
|
7
|
+
import type { UnitOfWork } from '../shared/unit-of-work.js';
|
|
8
|
+
import type { ScopeNamespaceRepository, ShipRepository } from './ports.js';
|
|
9
|
+
import { type GrantScopesRefusal } from './scope-grant.js';
|
|
10
|
+
export interface GrantScopesTx {
|
|
11
|
+
ships: Pick<ShipRepository, 'find' | 'findForUpdate' | 'setScopes'>;
|
|
12
|
+
scopeNamespaces: Pick<ScopeNamespaceRepository, 'lockNamespace' | 'find'>;
|
|
13
|
+
events: EventLog;
|
|
14
|
+
}
|
|
15
|
+
export type GrantScopes = (caller: Caller, input: {
|
|
16
|
+
shipId: ShipId;
|
|
17
|
+
grant: readonly string[];
|
|
18
|
+
revoke: readonly string[];
|
|
19
|
+
}) => Promise<Result<{
|
|
20
|
+
scopes: readonly string[];
|
|
21
|
+
}, GrantScopesRefusal | DomainError<'SHIP_NOT_FOUND'>>>;
|
|
22
|
+
/**
|
|
23
|
+
* Use case: the caller grants and revokes scopes on a live ship of its fleet
|
|
24
|
+
* (decision 0046), within what its ship may grant, read from the server.
|
|
25
|
+
* Its scope (scopes:grant) is checked before this runs. In one unit of work,
|
|
26
|
+
* holding the ship, then each plugin namespace the scopes name, so a
|
|
27
|
+
* declaration that removes a scope waits: the ship's scopes and
|
|
28
|
+
* ScopesChanged. The ship's crew holds them from its next call.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createGrantScopes(deps: {
|
|
31
|
+
uow: UnitOfWork<GrantScopesTx>;
|
|
32
|
+
clock: Clock;
|
|
33
|
+
ids: IdGenerator;
|
|
34
|
+
}): GrantScopes;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { refuse } from '../shared/errors.js';
|
|
2
|
+
import { recordEvent, shipActor } from '../shared/events.js';
|
|
3
|
+
import { ok } from '../shared/result.js';
|
|
4
|
+
import { grantScopes } from './scope-grant.js';
|
|
5
|
+
import { lockNamedNamespaces } from './named-namespaces.js';
|
|
6
|
+
/**
|
|
7
|
+
* Use case: the caller grants and revokes scopes on a live ship of its fleet
|
|
8
|
+
* (decision 0046), within what its ship may grant, read from the server.
|
|
9
|
+
* Its scope (scopes:grant) is checked before this runs. In one unit of work,
|
|
10
|
+
* holding the ship, then each plugin namespace the scopes name, so a
|
|
11
|
+
* declaration that removes a scope waits: the ship's scopes and
|
|
12
|
+
* ScopesChanged. The ship's crew holds them from its next call.
|
|
13
|
+
*/
|
|
14
|
+
export function createGrantScopes(deps) {
|
|
15
|
+
return (caller, input) => deps.uow.run(async (tx) => {
|
|
16
|
+
const { fleetId } = caller;
|
|
17
|
+
const ship = await tx.ships.findForUpdate(fleetId, input.shipId);
|
|
18
|
+
if (!ship) {
|
|
19
|
+
return refuse('SHIP_NOT_FOUND', `Ship ${input.shipId} does not exist`);
|
|
20
|
+
}
|
|
21
|
+
const namespaces = await lockNamedNamespaces(tx, { fleetId, scopes: [...input.grant, ...input.revoke] });
|
|
22
|
+
const granted = grantScopes({ ship, granter: caller, grant: input.grant, revoke: input.revoke, at: deps.clock.now(), actor: shipActor(caller.shipId) }, { namespaces });
|
|
23
|
+
if (!granted.isOk) {
|
|
24
|
+
return granted;
|
|
25
|
+
}
|
|
26
|
+
if (granted.value.events.length > 0) {
|
|
27
|
+
await tx.ships.setScopes({ fleetId, shipId: ship.id, scopes: granted.value.ship.scopes });
|
|
28
|
+
}
|
|
29
|
+
for (const event of granted.value.events) {
|
|
30
|
+
await recordEvent({ events: tx.events, ids: deps.ids }, event);
|
|
31
|
+
}
|
|
32
|
+
return ok({ scopes: granted.value.ship.scopes });
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=grant-scopes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grant-scopes.js","sourceRoot":"","sources":["../../../src/domain/registry/grant-scopes.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;AAGtD,OAAO,EAAE,WAAW,EAA2B,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAa5D;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAwE;IACxG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAsG,EAAE;QAC5H,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,MAAM,CAAC,gBAAgB,EAAE,QAAQ,KAAK,CAAC,MAAM,iBAAiB,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzG,MAAM,OAAO,GAAG,WAAW,CACzB,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAC1H,EAAE,UAAU,EAAE,CACf,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5F,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACzC,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,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FleetId, type LabelId, type LabelValueId, type ShipId } from '@aeolus-fleet/common';
|
|
1
|
+
import { type FleetId, type LabelId, type LabelValueId, type ShipId, type ShipKind } from '@aeolus-fleet/common';
|
|
2
2
|
import { type DomainError } from '../shared/errors.js';
|
|
3
3
|
import type { Actor, NewEvent } from '../shared/events.js';
|
|
4
4
|
import { type Result } from '../shared/result.js';
|
|
@@ -128,13 +128,15 @@ export declare function deleteLabel({ label, ownerName, carrierNames }: {
|
|
|
128
128
|
}): Result<{
|
|
129
129
|
events: NewEvent[];
|
|
130
130
|
}, DeleteLabelRefusal>;
|
|
131
|
-
|
|
131
|
+
/** A ship the caller may not label: neither its own nor one it commissioned, and the caller is not argo. */
|
|
132
|
+
export type NotYourShipToLabel = DomainError<'NOT_YOUR_SHIP_TO_LABEL'>;
|
|
133
|
+
export type AssignLabelRefusal = NotTheOwner | NotYourShipToLabel | DomainError<'SHIP_ALREADY_RETIRED' | 'SHIP_LABEL_LIMIT_REACHED'>;
|
|
132
134
|
/**
|
|
133
135
|
* The owner gives a ship one of its label's values, by its id: the ship
|
|
134
136
|
* holds a set of values, so it may carry several of one label. A value it
|
|
135
|
-
* carries changes nothing.
|
|
136
|
-
*
|
|
137
|
-
*
|
|
137
|
+
* carries changes nothing. Its own ship and the ships it commissioned, argo
|
|
138
|
+
* any ship (decision 0046), but never a retired ship. A ship carries at most
|
|
139
|
+
* 20 values. LabelAssigned names the ship, with the label and the value.
|
|
138
140
|
*/
|
|
139
141
|
export declare function assignLabel({ label, ownerName, ship, carried, }: {
|
|
140
142
|
label: Label;
|
|
@@ -143,6 +145,7 @@ export declare function assignLabel({ label, ownerName, ship, carried, }: {
|
|
|
143
145
|
carried: readonly ShipLabel[];
|
|
144
146
|
}, input: {
|
|
145
147
|
callerShipId: ShipId;
|
|
148
|
+
callerKind: ShipKind;
|
|
146
149
|
valueId: LabelValueId;
|
|
147
150
|
at: Date;
|
|
148
151
|
actor: Actor;
|
|
@@ -150,18 +153,20 @@ export declare function assignLabel({ label, ownerName, ship, carried, }: {
|
|
|
150
153
|
assignment: ShipLabel | undefined;
|
|
151
154
|
events: NewEvent[];
|
|
152
155
|
}, AssignLabelRefusal>;
|
|
153
|
-
export type UnassignLabelRefusal = NotTheOwner;
|
|
156
|
+
export type UnassignLabelRefusal = NotTheOwner | NotYourShipToLabel;
|
|
154
157
|
/**
|
|
155
158
|
* The owner takes one value of its label off a ship. A ship that does not
|
|
156
159
|
* carry it changes nothing. LabelUnassigned names the ship, with the label
|
|
157
160
|
* and the value it carried.
|
|
158
161
|
*/
|
|
159
|
-
export declare function unassignLabel({ label, ownerName, carried, }: {
|
|
162
|
+
export declare function unassignLabel({ label, ownerName, ship, carried, }: {
|
|
160
163
|
label: Label;
|
|
161
164
|
ownerName: string;
|
|
165
|
+
ship: Ship;
|
|
162
166
|
carried: readonly ShipLabel[];
|
|
163
167
|
}, input: {
|
|
164
168
|
callerShipId: ShipId;
|
|
169
|
+
callerKind: ShipKind;
|
|
165
170
|
valueId: LabelValueId;
|
|
166
171
|
at: Date;
|
|
167
172
|
actor: Actor;
|
|
@@ -173,18 +173,31 @@ function assignmentEvent({ label, assignment }, change) {
|
|
|
173
173
|
},
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Whether the caller may put values on the ship or take them off (decision
|
|
178
|
+
* 0046): its own ship and the ships it commissioned; argo any ship.
|
|
179
|
+
*/
|
|
180
|
+
function checkMayLabel(ship, caller) {
|
|
181
|
+
return caller.kind === 'operator' || ship.id === caller.shipId || ship.commission?.by === caller.shipId
|
|
182
|
+
? ok(undefined)
|
|
183
|
+
: refuse('NOT_YOUR_SHIP_TO_LABEL', `${ship.name} is neither your ship nor one it commissioned: only argo labels it`);
|
|
184
|
+
}
|
|
176
185
|
/**
|
|
177
186
|
* The owner gives a ship one of its label's values, by its id: the ship
|
|
178
187
|
* holds a set of values, so it may carry several of one label. A value it
|
|
179
|
-
* carries changes nothing.
|
|
180
|
-
*
|
|
181
|
-
*
|
|
188
|
+
* carries changes nothing. Its own ship and the ships it commissioned, argo
|
|
189
|
+
* any ship (decision 0046), but never a retired ship. A ship carries at most
|
|
190
|
+
* 20 values. LabelAssigned names the ship, with the label and the value.
|
|
182
191
|
*/
|
|
183
192
|
export function assignLabel({ label, ownerName, ship, carried, }, input) {
|
|
184
193
|
const owned = checkOwner({ label, ownerName }, { shipId: input.callerShipId, act: 'assigns' });
|
|
185
194
|
if (!owned.isOk) {
|
|
186
195
|
return owned;
|
|
187
196
|
}
|
|
197
|
+
const mayLabel = checkMayLabel(ship, { shipId: input.callerShipId, kind: input.callerKind });
|
|
198
|
+
if (!mayLabel.isOk) {
|
|
199
|
+
return mayLabel;
|
|
200
|
+
}
|
|
188
201
|
if (ship.retiredAt !== null) {
|
|
189
202
|
return refuse('SHIP_ALREADY_RETIRED', `${ship.name} is retired`);
|
|
190
203
|
}
|
|
@@ -210,11 +223,15 @@ export function assignLabel({ label, ownerName, ship, carried, }, input) {
|
|
|
210
223
|
* carry it changes nothing. LabelUnassigned names the ship, with the label
|
|
211
224
|
* and the value it carried.
|
|
212
225
|
*/
|
|
213
|
-
export function unassignLabel({ label, ownerName, carried, }, input) {
|
|
226
|
+
export function unassignLabel({ label, ownerName, ship, carried, }, input) {
|
|
214
227
|
const owned = checkOwner({ label, ownerName }, { shipId: input.callerShipId, act: 'unassigns' });
|
|
215
228
|
if (!owned.isOk) {
|
|
216
229
|
return owned;
|
|
217
230
|
}
|
|
231
|
+
const mayLabel = checkMayLabel(ship, { shipId: input.callerShipId, kind: input.callerKind });
|
|
232
|
+
if (!mayLabel.isOk) {
|
|
233
|
+
return mayLabel;
|
|
234
|
+
}
|
|
218
235
|
const current = carried.find((each) => each.valueId === input.valueId);
|
|
219
236
|
if (!current) {
|
|
220
237
|
return ok({ unassigned: undefined, events: [] });
|