@reventlessdev/reventless-aws 3.0.0-alpha.387 → 3.0.0-alpha.389
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/CHANGELOG.md +32 -0
- package/README.md +1 -1
- package/package.json +12 -12
- package/scripts/ProvisionIdentity.res +1 -1
- package/src/Platform.res +14 -14
- package/src/Platform.res.mjs +30 -30
- package/src/Platform_Stack.res +3 -3
- package/src/adapter/AWS_Tags.res +1 -1
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +1 -1
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +7 -7
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res.mjs +5 -5
- package/src/adapter/Auth/Auth_ActiveRolePoolAttachment.res +1 -1
- package/src/adapter/Auth/Auth_ActiveRoleStore_Ops.res +2 -2
- package/src/adapter/Auth/Auth_ActiveRoleStore_Schema.res +1 -1
- package/src/adapter/Auth/Auth_Cognito.res +1 -1
- package/src/adapter/Auth/Auth_LoginIdentifier.res +1 -1
- package/src/adapter/Auth/Auth_SignUpMode.res +1 -1
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +2 -2
- package/src/adapter/EventLog/EventLogBackend.res +1 -1
- package/src/adapter/QueryDb/PgQueryResolver_Lambda.res +2 -2
- package/src/adapter/Runtime/AggregateEntryPoint.mjs +6 -6
- package/src/adapter/Runtime/AggregateEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +20 -10
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +20 -10
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +19 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +19 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +19 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +19 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +6 -6
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +8 -3
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +7 -7
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +7 -7
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res.mjs +2 -2
- package/src/adapter/Runtime/EventCollectorEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +6 -1
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +6 -1
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +4 -4
- package/src/adapter/Runtime/RuntimeExtensionEntryPoint_Ops.res +2 -2
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +6 -1
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +10 -10
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +3 -3
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +6 -1
- package/src/adapter/StateTopic/StateTopic_AppSync.res +2 -2
- package/src/capability/Capability_Messaging.res +2 -2
- package/src/components/Aggregate_Builder_Micro.res +3 -3
- package/src/components/Aggregate_Builder_Micro.res.mjs +3 -3
- package/src/components/Aggregate_Builder_NoResolver.res +3 -3
- package/src/components/Aggregate_Builder_NoResolver.res.mjs +3 -3
- package/src/components/Aggregate_Builder_PerAggregate.res +3 -3
- package/src/components/Aggregate_Builder_PerAggregate.res.mjs +3 -3
- package/src/components/Aggregate_Builder_Single.res +3 -3
- package/src/components/Aggregate_Builder_Single.res.mjs +3 -3
- package/src/components/Aggregate_Builder_Single_Async.res +3 -3
- package/src/components/Aggregate_Builder_Single_Async.res.mjs +3 -3
- package/src/components/Api/AppSync_Adapter.res +3 -3
- package/src/components/Api/AppSync_SdlDecorate.res +3 -3
- package/src/components/SideEffectHandler_PerSideEffectHandler.res +1 -1
- package/src/components/StateChangeSlice_Builder.res +4 -4
- package/src/components/StateChangeSlice_Builder.res.mjs +4 -4
- package/src/plugin/runtime/PluginRuntime_Builder.res +7 -7
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +3 -3
- package/src/plugin/stack/Plugin_Stack.res +1 -1
- package/src/util/Util_Bundle.res +1 -1
- package/tests/AppSync_AdapterTest.res +1 -1
- package/tests/AppSync_RetirementNarrowingTest.res +1 -1
- package/tests/AppSync_SdlDecorateTest.res +1 -1
- package/tests/Auth_LoginIdentifierTest.res +1 -1
- package/tests/Auth_SignUpModeTest.res +1 -1
- package/tests/BakeConvergenceTest.res +11 -11
- package/tests/BakeConvergenceTest.res.mjs +13 -13
- package/tests/QueryDbResolvers_AppSyncTest.res +1 -1
- package/tests/Upload_ClaimTest.res +1 -1
- package/tests/Util_AwsErrorTest.res +1 -1
- package/tests/Util_StoreLayoutTest.res +1 -1
- package/tests/dcbColdStartPartition.mjs +3 -3
- package/tests/integration/{AggTestAggregateBehavior.res → AggTestAggregateDecision.res} +2 -2
- package/tests/integration/{AggTestAggregateBehavior.res.mjs → AggTestAggregateDecision.res.mjs} +1 -1
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res +3 -3
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res.mjs +2 -2
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +5 -5
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res.mjs +4 -4
- package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +1 -1
- package/tests/integration/{EpCompositeSliceBehavior.res → EpCompositeSliceDecision.res} +2 -2
- package/tests/integration/{EpCompositeSliceBehavior.res.mjs → EpCompositeSliceDecision.res.mjs} +1 -1
- package/tests/integration/{EpTestSliceBehavior.res → EpTestSliceDecision.res} +2 -2
- package/tests/integration/{EpTestSliceBehavior.res.mjs → EpTestSliceDecision.res.mjs} +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,38 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.389 (2026-10-21)
|
|
7
|
+
|
|
8
|
+
* feat!: a state view's row key is module Id ([08c9726](https://github.com/ReventlessDev/reventless-core/commit/08c972659a3d689a39fd5e2f2026597155e92210))
|
|
9
|
+
* feat!: a plugin structure's component definitions are read-side and write-side defs ([ea2ab69](https://github.com/ReventlessDev/reventless-core/commit/ea2ab69e928ba16d7e640e4c66ab0e9ba034fe5c))
|
|
10
|
+
|
|
11
|
+
### BREAKING CHANGES
|
|
12
|
+
|
|
13
|
+
* a state view spec declares its row key as module Id. A
|
|
14
|
+
hand-written module Key in a spec under StateView/ or StateViewStream/
|
|
15
|
+
fails the build with "A state view's row key is `module Id`, not
|
|
16
|
+
`module Key`".
|
|
17
|
+
* Plugin.queryableDef, Plugin.writableDef, their schemas,
|
|
18
|
+
isPublicQueryable and encodeQueryableDef no longer exist; a reader names
|
|
19
|
+
readSideDef, writeSideDef, isPublicReadSide and encodeReadSideDef. There
|
|
20
|
+
are no aliases, so the compiler lists every reader.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# 3.0.0-alpha.388 (2026-10-21)
|
|
25
|
+
|
|
26
|
+
* feat!: the write-side logic module is called the decision, and a codemod moves an app over ([cb573ff](https://github.com/ReventlessDev/reventless-core/commit/cb573ff5b928c7d7f3e75988dfaa65066f8c95eb))
|
|
27
|
+
|
|
28
|
+
### BREAKING CHANGES
|
|
29
|
+
|
|
30
|
+
* <Spec>_Behavior.res, @@reventless.behavior,
|
|
31
|
+
Reventless.Behavior.T, StateChangeSlice.Behavior, Behavior_GWT and
|
|
32
|
+
thenRefused no longer exist. Run `npx reventless-rename-to-decision` at an
|
|
33
|
+
app's root, then rebuild; comments are not rewritten. The PPX must be the
|
|
34
|
+
matching release.
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
6
38
|
# 3.0.0-alpha.387 (2026-10-19)
|
|
7
39
|
|
|
8
40
|
### Features
|
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ ReScript modules, consumed by adding the package to your `rescript.json` `depend
|
|
|
21
21
|
|
|
22
22
|
- **`Platform`** — the AWS platform functor (`Platform.Make()` / `Platform.MakeWithConfig({...})`).
|
|
23
23
|
Applying it wires up AWS builders once; your plugin functor then takes only the
|
|
24
|
-
application-defined `Spec`, `
|
|
24
|
+
application-defined `Spec`, `Decision`, and `Mappings`.
|
|
25
25
|
- **Component builders** (`Aggregate_Builder`, `ReadModel_Builder`, `Plugin`,
|
|
26
26
|
the slice builders, `Task_Builder`, `Counter_Builder`, `Scheduler`, …) —
|
|
27
27
|
AWS-preconfigured versions of the core hierarchical components, including the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-aws",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.389",
|
|
4
4
|
"description": "AWS adapters for Reventless",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
"sury": "11.0.0",
|
|
23
23
|
"uuid": "^13.0.0",
|
|
24
24
|
"yaml": "^2.8.3",
|
|
25
|
-
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.
|
|
26
|
-
"@reventlessdev/rescript-
|
|
27
|
-
"@reventlessdev/rescript-
|
|
28
|
-
"@reventlessdev/rescript-
|
|
29
|
-
"@reventlessdev/rescript-
|
|
25
|
+
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.33",
|
|
26
|
+
"@reventlessdev/rescript-effect": "1.0.0-alpha.1",
|
|
27
|
+
"@reventlessdev/rescript-node": "2.0.0-alpha.23",
|
|
28
|
+
"@reventlessdev/rescript-jest": "1.0.0-alpha.13",
|
|
29
|
+
"@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.31",
|
|
30
30
|
"@reventlessdev/rescript-pulumi-pulumi": "3.0.0-alpha.0",
|
|
31
|
-
"@reventlessdev/rescript-web": "1.0.0-alpha.7",
|
|
32
|
-
"@reventlessdev/reventless-core": "3.0.0-alpha.300",
|
|
33
31
|
"@reventlessdev/rescript-uuid": "2.0.0-alpha.1",
|
|
34
|
-
"@reventlessdev/
|
|
35
|
-
"@reventlessdev/reventless-
|
|
36
|
-
"@reventlessdev/reventless-interop": "3.0.0-alpha.
|
|
37
|
-
"@reventlessdev/reventless-
|
|
32
|
+
"@reventlessdev/rescript-web": "1.0.0-alpha.8",
|
|
33
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.199",
|
|
34
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.42",
|
|
35
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.166",
|
|
36
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.171",
|
|
37
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.302"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"rescript": "12.3.1",
|
|
@@ -10,7 +10,7 @@ outside every stack. That is this.
|
|
|
10
10
|
🚨 **It does not attach a pre-token-generation trigger, and must not.** The pool's
|
|
11
11
|
one trigger slot is the deploy's business: a script that filled it would be the
|
|
12
12
|
hand-run `UpdateUserPool` this whole area refuses, leaving the deployment's
|
|
13
|
-
|
|
13
|
+
behavior depending on an act no source describes.
|
|
14
14
|
|
|
15
15
|
The store's name and key schema come from [Auth_ActiveRoleStore_Schema] rather
|
|
16
16
|
than from constants here. A second copy of either would be one edit away from
|
package/src/Platform.res
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Creates a platform instance with pre-wired AWS builders (DynamoDB, Lambda, SQS, SNS).
|
|
4
4
|
// Config is applied once at platform creation; component Make functors then take only
|
|
5
|
-
// the application-defined arguments (Spec,
|
|
5
|
+
// the application-defined arguments (Spec, Decision, Mappings).
|
|
6
6
|
//
|
|
7
7
|
// Example:
|
|
8
8
|
// module Platform = Platform.Make()
|
|
@@ -593,19 +593,19 @@ module MakeWithConfig = (
|
|
|
593
593
|
// _Micro, _NoResolver) — see docs/plans/Backlog/aws-deployment-strategy.md.
|
|
594
594
|
module Make = (
|
|
595
595
|
Spec: Reventless.Aggregate.Spec,
|
|
596
|
-
|
|
596
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
597
597
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
598
598
|
): (
|
|
599
599
|
ReventlessInfra.Aggregate.T with type api = Types.AppSync.api
|
|
600
|
-
) => Aggregate_Builder_Single.Make(Spec,
|
|
600
|
+
) => Aggregate_Builder_Single.Make(Spec, Decision, EventMappings)
|
|
601
601
|
/** Async variant — uses FIFO SQS channel, commands return `CommandPending`. */
|
|
602
602
|
module MakeAsync = (
|
|
603
603
|
Spec: Reventless.Aggregate.Spec,
|
|
604
|
-
|
|
604
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
605
605
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
606
606
|
): (
|
|
607
607
|
ReventlessInfra.Aggregate.T with type api = Types.AppSync.api
|
|
608
|
-
) => Aggregate_Builder_Single_Async.Make(Spec,
|
|
608
|
+
) => Aggregate_Builder_Single_Async.Make(Spec, Decision, EventMappings)
|
|
609
609
|
}
|
|
610
610
|
|
|
611
611
|
module ReadModel = {
|
|
@@ -734,16 +734,16 @@ module MakeWithConfig = (
|
|
|
734
734
|
module StateChangeSlice = {
|
|
735
735
|
module Make = (
|
|
736
736
|
Spec: Reventless.StateChangeSlice.Spec,
|
|
737
|
-
|
|
737
|
+
Decision: Reventless.StateChangeSlice.Decision with module Spec := Spec,
|
|
738
738
|
): (
|
|
739
739
|
ReventlessInfra.StateChangeSlice.T with module Spec = Spec
|
|
740
|
-
) => StateChangeSlice_Builder.Make(Spec,
|
|
740
|
+
) => StateChangeSlice_Builder.Make(Spec, Decision)
|
|
741
741
|
/** Async variant — uses FIFO SQS channel, commands return `CommandPending`. */
|
|
742
742
|
module MakeAsync = (
|
|
743
743
|
Spec: Reventless.StateChangeSlice.Spec,
|
|
744
|
-
|
|
744
|
+
Decision: Reventless.StateChangeSlice.Decision with module Spec := Spec,
|
|
745
745
|
): (ReventlessInfra.StateChangeSlice.T with module Spec = Spec) => {
|
|
746
|
-
include StateChangeSlice_Builder.Make(Spec,
|
|
746
|
+
include StateChangeSlice_Builder.Make(Spec, Decision)
|
|
747
747
|
let isAsync = true
|
|
748
748
|
}
|
|
749
749
|
}
|
|
@@ -769,7 +769,7 @@ module MakeWithConfig = (
|
|
|
769
769
|
// slice's command handler exactly once).
|
|
770
770
|
module UiFragmentRegistrySlice = StateChangeSlice.Make(
|
|
771
771
|
ReventlessCore.UiFragmentRegistry,
|
|
772
|
-
ReventlessCore.
|
|
772
|
+
ReventlessCore.UiFragmentRegistry_Decision,
|
|
773
773
|
)
|
|
774
774
|
module UiFragmentsViewSlice = StateViewSlice.Make(
|
|
775
775
|
ReventlessCore.UiFragments,
|
|
@@ -964,7 +964,7 @@ module MakeWithConfig = (
|
|
|
964
964
|
allQueryDbs->Dict.forEachWithKey((_queryDbOutputs, readModelName) => {
|
|
965
965
|
if QueryDbStorage_DynamoDbStream.streamRegistry->Set.has(readModelName) {
|
|
966
966
|
// Channel root MUST equal what the host-shell subscribes to. The
|
|
967
|
-
// AutoUI manifest sets
|
|
967
|
+
// AutoUI manifest sets readSideDef.queryField = listFieldName
|
|
968
968
|
// (plural, e.g. "Catalog_Products") and AutoLive subscribes on that.
|
|
969
969
|
// Publishing on the singular returnTypeName ("Catalog_Product")
|
|
970
970
|
// would land descriptors on a channel no client listens to.
|
|
@@ -1085,7 +1085,7 @@ module MakeWithConfig = (
|
|
|
1085
1085
|
module PluginAggregate: ReventlessInfra.Aggregate.T
|
|
1086
1086
|
with type api = Types.AppSync.api = Aggregate_Builder_Single.Make(
|
|
1087
1087
|
ReventlessCore.PluginSpec,
|
|
1088
|
-
ReventlessCore.
|
|
1088
|
+
ReventlessCore.PluginDecision,
|
|
1089
1089
|
ReventlessInfra.NoEventMappings.Make(ReventlessCore.PluginSpec),
|
|
1090
1090
|
)
|
|
1091
1091
|
|
|
@@ -2704,7 +2704,7 @@ module MakeWithConfig = (
|
|
|
2704
2704
|
//
|
|
2705
2705
|
// A platform that provisioned no geocoder yields "", and the plugin's client
|
|
2706
2706
|
// reports `Unavailable` — retried, then surfaced by the heartbeat sweep. That
|
|
2707
|
-
// is a
|
|
2707
|
+
// is a modeled outcome, which is the point of the empty string: a plugin
|
|
2708
2708
|
// deployed against a platform without the capability degrades rather than
|
|
2709
2709
|
// failing to deploy.
|
|
2710
2710
|
// The place index, not the Function URL. A slice's Lambda reaches Amazon
|
|
@@ -2907,7 +2907,7 @@ module MakeWithConfig = (
|
|
|
2907
2907
|
// why a *declared* need fails the deploy.
|
|
2908
2908
|
//
|
|
2909
2909
|
// Only a declared need. A plugin that says nothing still degrades
|
|
2910
|
-
// exactly as before: the empty endpoint is a
|
|
2910
|
+
// exactly as before: the empty endpoint is a modeled outcome for a
|
|
2911
2911
|
// deployment that simply has no geocoder, and failing those would break
|
|
2912
2912
|
// deployments that work.
|
|
2913
2913
|
switch Reventless.CapabilityNeed.unmet(
|
package/src/Platform.res.mjs
CHANGED
|
@@ -43,7 +43,7 @@ import * as AppSync_Adapter$ReventlessAws from "./components/Api/AppSync_Adapter
|
|
|
43
43
|
import * as Counter_Builder$ReventlessAws from "./components/Counter_Builder.res.mjs";
|
|
44
44
|
import * as EventLogBackend$ReventlessAws from "./adapter/EventLog/EventLogBackend.res.mjs";
|
|
45
45
|
import * as Platform_Admin$ReventlessCore from "@reventlessdev/reventless-core/src/admin/Platform_Admin.res.mjs";
|
|
46
|
-
import * as
|
|
46
|
+
import * as PluginDecision$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/lifecycle/PluginDecision.res.mjs";
|
|
47
47
|
import * as Plugin_Helpers$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/component/Plugin_Helpers.res.mjs";
|
|
48
48
|
import * as Upload_Claim_S3$ReventlessAws from "./adapter/Upload/Upload_Claim_S3.res.mjs";
|
|
49
49
|
import * as PgProjectionFeed$ReventlessAws from "./adapter/Postgres/PgProjectionFeed.res.mjs";
|
|
@@ -95,7 +95,7 @@ import * as PluginExtensionPointSpec$ReventlessInfra from "@reventlessdev/revent
|
|
|
95
95
|
import * as Platform_UIFragments_Lambda$ReventlessAws from "./adapter/Api/Platform_UIFragments_Lambda.res.mjs";
|
|
96
96
|
import * as CommandTopicChannel_SQS_Sync$ReventlessAws from "./adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs";
|
|
97
97
|
import * as EventLogSubscription_AppSync$ReventlessAws from "./adapter/EventLogSubscription/EventLogSubscription_AppSync.res.mjs";
|
|
98
|
-
import * as
|
|
98
|
+
import * as UiFragmentRegistry_Decision$ReventlessCore from "@reventlessdev/reventless-core/src/admin/UiFragmentRegistry/StateChange/UiFragmentRegistry_Decision.res.mjs";
|
|
99
99
|
import * as CommandTopicChannel_SQS_Async$ReventlessAws from "./adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs";
|
|
100
100
|
import * as Geocoder_AwsLocation_Resolver$ReventlessAws from "./adapter/Geocoder/Geocoder_AwsLocation_Resolver.res.mjs";
|
|
101
101
|
import * as Plugin_ExtensionPoint_Builder$ReventlessAws from "./plugin/stack/Plugin_ExtensionPoint_Builder.res.mjs";
|
|
@@ -383,8 +383,8 @@ function MakeWithConfig(Config) {
|
|
|
383
383
|
api: resolveTargetApi,
|
|
384
384
|
apiRole: resolveTargetApiRole
|
|
385
385
|
};
|
|
386
|
-
let Make = Spec => (
|
|
387
|
-
let MakeAsync = Spec => (
|
|
386
|
+
let Make = Spec => (Decision => (EventMappings => Aggregate_Builder_Single$ReventlessAws.Make(Spec)(Decision)(EventMappings)));
|
|
387
|
+
let MakeAsync = Spec => (Decision => (EventMappings => Aggregate_Builder_Single_Async$ReventlessAws.Make(Spec)(Decision)(EventMappings)));
|
|
388
388
|
let Aggregate = {
|
|
389
389
|
Make: Make,
|
|
390
390
|
MakeAsync: MakeAsync
|
|
@@ -464,12 +464,12 @@ function MakeWithConfig(Config) {
|
|
|
464
464
|
Make: Make$5
|
|
465
465
|
};
|
|
466
466
|
let Counter = Counter_Builder$ReventlessAws.Make(ApiConfig);
|
|
467
|
-
let Make$6 = Spec => (
|
|
468
|
-
let MakeAsync$1 = Spec => (
|
|
469
|
-
let include = StateChangeSlice_Builder$ReventlessAws.Make(Spec)(
|
|
467
|
+
let Make$6 = Spec => (Decision => StateChangeSlice_Builder$ReventlessAws.Make(Spec)(Decision));
|
|
468
|
+
let MakeAsync$1 = Spec => (Decision => {
|
|
469
|
+
let include = StateChangeSlice_Builder$ReventlessAws.Make(Spec)(Decision);
|
|
470
470
|
return {
|
|
471
471
|
Spec: include.Spec,
|
|
472
|
-
|
|
472
|
+
Decision: include.Decision,
|
|
473
473
|
isAsync: true,
|
|
474
474
|
make: include.make
|
|
475
475
|
};
|
|
@@ -498,15 +498,15 @@ function MakeWithConfig(Config) {
|
|
|
498
498
|
};
|
|
499
499
|
let UiFragmentRegistrySlice = StateChangeSlice_Builder$ReventlessAws.Make(Spec)({
|
|
500
500
|
initialState: undefined,
|
|
501
|
-
evolve:
|
|
502
|
-
decide:
|
|
503
|
-
moduleUrl:
|
|
501
|
+
evolve: UiFragmentRegistry_Decision$ReventlessCore.evolve,
|
|
502
|
+
decide: UiFragmentRegistry_Decision$ReventlessCore.decide,
|
|
503
|
+
moduleUrl: UiFragmentRegistry_Decision$ReventlessCore.moduleUrl
|
|
504
504
|
});
|
|
505
505
|
let UiFragmentsViewSlice = Make$7({
|
|
506
506
|
name: UiFragments$ReventlessCore.name,
|
|
507
507
|
moduleUrl: UiFragments$ReventlessCore.moduleUrl,
|
|
508
508
|
stateSchema: UiFragments$ReventlessCore.stateSchema,
|
|
509
|
-
|
|
509
|
+
Id: {
|
|
510
510
|
schema: Id$Reventless.StringPure.schema,
|
|
511
511
|
make: prim => prim,
|
|
512
512
|
makeFromString: prim => prim,
|
|
@@ -692,11 +692,11 @@ function MakeWithConfig(Config) {
|
|
|
692
692
|
commandTransition: PluginSpec$ReventlessCore.commandTransition,
|
|
693
693
|
traits: PluginSpec$ReventlessCore.traits
|
|
694
694
|
})({
|
|
695
|
-
initialState:
|
|
696
|
-
evolve:
|
|
697
|
-
decide:
|
|
695
|
+
initialState: PluginDecision$ReventlessCore.initialState,
|
|
696
|
+
evolve: PluginDecision$ReventlessCore.evolve,
|
|
697
|
+
decide: PluginDecision$ReventlessCore.decide,
|
|
698
698
|
snapshot: undefined,
|
|
699
|
-
moduleUrl:
|
|
699
|
+
moduleUrl: PluginDecision$ReventlessCore.moduleUrl
|
|
700
700
|
})(NoEventMappings$ReventlessInfra.Make({
|
|
701
701
|
name: PluginSpec$ReventlessCore.name,
|
|
702
702
|
Id: Id$Reventless.$$String,
|
|
@@ -1800,8 +1800,8 @@ function Make($star) {
|
|
|
1800
1800
|
api: resolveTargetApi,
|
|
1801
1801
|
apiRole: resolveTargetApiRole
|
|
1802
1802
|
};
|
|
1803
|
-
let Make$1 = Spec => (
|
|
1804
|
-
let MakeAsync = Spec => (
|
|
1803
|
+
let Make$1 = Spec => (Decision => (EventMappings => Aggregate_Builder_Single$ReventlessAws.Make(Spec)(Decision)(EventMappings)));
|
|
1804
|
+
let MakeAsync = Spec => (Decision => (EventMappings => Aggregate_Builder_Single_Async$ReventlessAws.Make(Spec)(Decision)(EventMappings)));
|
|
1805
1805
|
let Aggregate = {
|
|
1806
1806
|
Make: Make$1,
|
|
1807
1807
|
MakeAsync: MakeAsync
|
|
@@ -1881,12 +1881,12 @@ function Make($star) {
|
|
|
1881
1881
|
Make: Make$6
|
|
1882
1882
|
};
|
|
1883
1883
|
let Counter = Counter_Builder$ReventlessAws.Make(ApiConfig);
|
|
1884
|
-
let Make$7 = Spec => (
|
|
1885
|
-
let MakeAsync$1 = Spec => (
|
|
1886
|
-
let include = StateChangeSlice_Builder$ReventlessAws.Make(Spec)(
|
|
1884
|
+
let Make$7 = Spec => (Decision => StateChangeSlice_Builder$ReventlessAws.Make(Spec)(Decision));
|
|
1885
|
+
let MakeAsync$1 = Spec => (Decision => {
|
|
1886
|
+
let include = StateChangeSlice_Builder$ReventlessAws.Make(Spec)(Decision);
|
|
1887
1887
|
return {
|
|
1888
1888
|
Spec: include.Spec,
|
|
1889
|
-
|
|
1889
|
+
Decision: include.Decision,
|
|
1890
1890
|
isAsync: true,
|
|
1891
1891
|
make: include.make
|
|
1892
1892
|
};
|
|
@@ -1915,15 +1915,15 @@ function Make($star) {
|
|
|
1915
1915
|
};
|
|
1916
1916
|
let UiFragmentRegistrySlice = StateChangeSlice_Builder$ReventlessAws.Make(Spec)({
|
|
1917
1917
|
initialState: undefined,
|
|
1918
|
-
evolve:
|
|
1919
|
-
decide:
|
|
1920
|
-
moduleUrl:
|
|
1918
|
+
evolve: UiFragmentRegistry_Decision$ReventlessCore.evolve,
|
|
1919
|
+
decide: UiFragmentRegistry_Decision$ReventlessCore.decide,
|
|
1920
|
+
moduleUrl: UiFragmentRegistry_Decision$ReventlessCore.moduleUrl
|
|
1921
1921
|
});
|
|
1922
1922
|
let UiFragmentsViewSlice = Make$8({
|
|
1923
1923
|
name: UiFragments$ReventlessCore.name,
|
|
1924
1924
|
moduleUrl: UiFragments$ReventlessCore.moduleUrl,
|
|
1925
1925
|
stateSchema: UiFragments$ReventlessCore.stateSchema,
|
|
1926
|
-
|
|
1926
|
+
Id: {
|
|
1927
1927
|
schema: Id$Reventless.StringPure.schema,
|
|
1928
1928
|
make: prim => prim,
|
|
1929
1929
|
makeFromString: prim => prim,
|
|
@@ -2109,11 +2109,11 @@ function Make($star) {
|
|
|
2109
2109
|
commandTransition: PluginSpec$ReventlessCore.commandTransition,
|
|
2110
2110
|
traits: PluginSpec$ReventlessCore.traits
|
|
2111
2111
|
})({
|
|
2112
|
-
initialState:
|
|
2113
|
-
evolve:
|
|
2114
|
-
decide:
|
|
2112
|
+
initialState: PluginDecision$ReventlessCore.initialState,
|
|
2113
|
+
evolve: PluginDecision$ReventlessCore.evolve,
|
|
2114
|
+
decide: PluginDecision$ReventlessCore.decide,
|
|
2115
2115
|
snapshot: undefined,
|
|
2116
|
-
moduleUrl:
|
|
2116
|
+
moduleUrl: PluginDecision$ReventlessCore.moduleUrl
|
|
2117
2117
|
})(NoEventMappings$ReventlessInfra.Make({
|
|
2118
2118
|
name: PluginSpec$ReventlessCore.name,
|
|
2119
2119
|
Id: Id$Reventless.$$String,
|
package/src/Platform_Stack.res
CHANGED
|
@@ -110,7 +110,7 @@ let _identityProviderId = (~cfg: Pulumi.Config.t): option<string> => {
|
|
|
110
110
|
`platform:loginIdentifier` (or `REVENTLESS_LOGIN_IDENTIFIER` / the sidecar).
|
|
111
111
|
|
|
112
112
|
Absent means `email`, which is what every pool so far was created with. An
|
|
113
|
-
|
|
113
|
+
unrecognized spelling fails the deploy — see [Auth_LoginIdentifier] for why
|
|
114
114
|
defaulting past a typo here is unrecoverable. */
|
|
115
115
|
let _loginIdentifier = (~cfg: Pulumi.Config.t): Auth_LoginIdentifier.t => {
|
|
116
116
|
let raw = switch Util_LocalConfig.get("loginIdentifier") {
|
|
@@ -128,7 +128,7 @@ let _loginIdentifier = (~cfg: Pulumi.Config.t): Auth_LoginIdentifier.t => {
|
|
|
128
128
|
|
|
129
129
|
Absent means `adminOnly`, which is what every pool so far was created with, so
|
|
130
130
|
an existing stack redeploys unchanged. Unlike the sign-in attribute this is an
|
|
131
|
-
ordinary in-place update on a live pool — but an
|
|
131
|
+
ordinary in-place update on a live pool — but an unrecognized spelling still
|
|
132
132
|
fails the deploy, because defaulting past it would refuse every registration
|
|
133
133
|
while the config read as if it allowed them. See [Auth_SignUpMode]. */
|
|
134
134
|
let _signUpMode = (~cfg: Pulumi.Config.t): Auth_SignUpMode.t => {
|
|
@@ -215,7 +215,7 @@ let _resolveUncached = (): cognitoUserPool => {
|
|
|
215
215
|
// separate attachment resource — so the trigger is attached by a declared
|
|
216
216
|
// resource that describes the pool, merges into what it finds, and sends the
|
|
217
217
|
// result back whole. Never a hand-run command: that would leave the
|
|
218
|
-
// deployment's
|
|
218
|
+
// deployment's behavior depending on an act no source describes.
|
|
219
219
|
// The code hash is an input so a new build of the trigger reaches this
|
|
220
220
|
// resource: the function ARN is stable, so it alone would let a broken
|
|
221
221
|
// version onto the pool unchecked after the first deploy.
|
package/src/adapter/AWS_Tags.res
CHANGED
|
@@ -14,7 +14,7 @@ dimension; the bare spelling bought nothing.
|
|
|
14
14
|
The three attribution facts are independent and all three are needed to identify
|
|
15
15
|
a resource (see `ResourceAttribution`):
|
|
16
16
|
|
|
17
|
-
- `~kind` — the
|
|
17
|
+
- `~kind` — the modeling kind of the owning component (Aggregate, …)
|
|
18
18
|
- `~role` — the deployment piece this resource implements (EventLog, Runtime, …)
|
|
19
19
|
- `~scope` — component / plugin / platform
|
|
20
20
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// handler wraps each persisted structure with `pluginId` without decoding.
|
|
9
9
|
// One caveat: the persisted structure is PRE-filter — it still carries Internal
|
|
10
10
|
// ReadModels / StateViewSlices for developer tooling. The handler re-applies the
|
|
11
|
-
// `
|
|
11
|
+
// `isPublicReadSide` filter (mirroring `encodePluginStructureEntry`) so Internal
|
|
12
12
|
// components stay out of the deployed AutoUI, matching the in-memory adapter.
|
|
13
13
|
|
|
14
14
|
open PulumiAws
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
//
|
|
7
7
|
// Scans the Plugin read model for Connected plugins carrying a `structure`,
|
|
8
8
|
// collapses to the highest version per plugin name, re-applies the
|
|
9
|
-
// `
|
|
9
|
+
// `isPublicReadSide` filter (the persisted structure is PRE-filter — it still
|
|
10
10
|
// carries Internal ReadModels / StateViewSlices for developer tooling), and
|
|
11
11
|
// prepends the built-in Platform_Admin entry. The persisted structure is
|
|
12
12
|
// sury-encoded with the same shape as the in-memory adapter's
|
|
@@ -128,9 +128,9 @@ let healStructure = (structure: dict<JSON.t>): dict<JSON.t> => {
|
|
|
128
128
|
out
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
// Mirror ReventlessCore.Platform_ComponentDefinitionsApi.
|
|
131
|
+
// Mirror ReventlessCore.Platform_ComponentDefinitionsApi.isPublicReadSide on
|
|
132
132
|
// the read path: a component is public unless its visibility is "Internal".
|
|
133
|
-
let
|
|
133
|
+
let isPublicReadSide = (q: JSON.t): bool =>
|
|
134
134
|
switch q
|
|
135
135
|
->JSON.Decode.object
|
|
136
136
|
->Option.flatMap(o => o->Dict.get("visibility"))
|
|
@@ -154,15 +154,15 @@ let filterStructure = (structure: dict<JSON.t>): dict<JSON.t> => {
|
|
|
154
154
|
let arrAt = key => out->Dict.get(key)->Option.flatMap(JSON.Decode.array)->Option.getOr([])
|
|
155
155
|
let readModels = arrAt("readModels")
|
|
156
156
|
let stateViewSlices = arrAt("stateViewSlices")
|
|
157
|
-
out->Dict.set("readModels", readModels->Array.filter(
|
|
157
|
+
out->Dict.set("readModels", readModels->Array.filter(isPublicReadSide)->JSON.Encode.array)
|
|
158
158
|
out->Dict.set(
|
|
159
159
|
"stateViewSlices",
|
|
160
|
-
stateViewSlices->Array.filter(
|
|
160
|
+
stateViewSlices->Array.filter(isPublicReadSide)->JSON.Encode.array,
|
|
161
161
|
)
|
|
162
162
|
out->Dict.set(
|
|
163
163
|
"internalQueryables",
|
|
164
164
|
Array.concat(readModels, stateViewSlices)
|
|
165
|
-
->Array.filter(q => !
|
|
165
|
+
->Array.filter(q => !isPublicReadSide(q))
|
|
166
166
|
->JSON.Encode.array,
|
|
167
167
|
)
|
|
168
168
|
out
|
|
@@ -173,7 +173,7 @@ let filterStructure = (structure: dict<JSON.t>): dict<JSON.t> => {
|
|
|
173
173
|
// no decodable structure (former `!item.structure`).
|
|
174
174
|
//
|
|
175
175
|
// `~filter` is what separates the two fields this handler serves: AutoUI
|
|
176
|
-
// (`Platform_ComponentDefinitions`) gets the public-
|
|
176
|
+
// (`Platform_ComponentDefinitions`) gets the public read-side subset, developer
|
|
177
177
|
// tooling (`Platform_PluginStructures`) gets the structure exactly as persisted,
|
|
178
178
|
// including Internal components and the producer-side `extensionPoints` that the
|
|
179
179
|
// AutoUI entry type does not declare. Both are healed first — the SDL's non-null
|
|
@@ -182,7 +182,7 @@ function healStructure(structure) {
|
|
|
182
182
|
return out;
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
function
|
|
185
|
+
function isPublicReadSide(q) {
|
|
186
186
|
let match = Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(q), o => o["visibility"]), Stdlib_JSON.Decode.string);
|
|
187
187
|
if (match !== undefined) {
|
|
188
188
|
return match !== "Internal";
|
|
@@ -196,9 +196,9 @@ function filterStructure(structure) {
|
|
|
196
196
|
let arrAt = key => Stdlib_Option.getOr(Stdlib_Option.flatMap(out[key], Stdlib_JSON.Decode.array), []);
|
|
197
197
|
let readModels = arrAt("readModels");
|
|
198
198
|
let stateViewSlices = arrAt("stateViewSlices");
|
|
199
|
-
out["readModels"] = readModels.filter(
|
|
200
|
-
out["stateViewSlices"] = stateViewSlices.filter(
|
|
201
|
-
out["internalQueryables"] = readModels.concat(stateViewSlices).filter(q => !
|
|
199
|
+
out["readModels"] = readModels.filter(isPublicReadSide);
|
|
200
|
+
out["stateViewSlices"] = stateViewSlices.filter(isPublicReadSide);
|
|
201
|
+
out["internalQueryables"] = readModels.concat(stateViewSlices).filter(q => !isPublicReadSide(q));
|
|
202
202
|
return out;
|
|
203
203
|
}
|
|
204
204
|
|
|
@@ -644,7 +644,7 @@ export {
|
|
|
644
644
|
fillLifecycleField,
|
|
645
645
|
readSideCollections,
|
|
646
646
|
healStructure,
|
|
647
|
-
|
|
647
|
+
isPublicReadSide,
|
|
648
648
|
filterStructure,
|
|
649
649
|
toEntryWith,
|
|
650
650
|
adminEntry,
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
attachment resource, so something has to call `UpdateUserPool` against a pool
|
|
15
15
|
no stack owns. That belongs in a declared resource executed at deploy time,
|
|
16
16
|
never a hand-run command against a live pool, which would leave the
|
|
17
|
-
deployment's
|
|
17
|
+
deployment's behavior depending on an act no source describes.
|
|
18
18
|
|
|
19
19
|
🚨 **The slot is the pool's, and this resource takes it only when it is
|
|
20
20
|
free or already ours.** Cognito allows a pool exactly one
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// the pre-token-generation trigger ([Auth_ActiveRoleTrigger_Ops.res]) reads this
|
|
9
9
|
// row on the next refresh and narrows the group claim to it. Nothing here can
|
|
10
10
|
// grant anything: the trigger re-checks the stored role against real membership
|
|
11
|
-
// before applying it, so a row is at most a request that the trigger may
|
|
11
|
+
// before applying it, so a row is at most a request that the trigger may honor.
|
|
12
12
|
//
|
|
13
13
|
// 🚨 **The subject is taken from the verified identity, never from the arguments.**
|
|
14
14
|
// The row key is `ctx.identity.sub` as the AppSync Cognito authorizer resolved it.
|
|
@@ -115,7 +115,7 @@ type appSyncEvent = {
|
|
|
115
115
|
The name to address this caller by when asking Cognito what groups they are in.
|
|
116
116
|
|
|
117
117
|
The username when the authorizer supplied one, the subject otherwise. The
|
|
118
|
-
fallback is not a guess at a username: it is the
|
|
118
|
+
fallback is not a guess at a username: it is the behavior this handler had
|
|
119
119
|
before the username was forwarded, kept for the pool shapes where it is correct —
|
|
120
120
|
one whose username *is* the subject — rather than turning a working deployment
|
|
121
121
|
into a hard failure on an absent field. Pure so the choice can be tested without
|
|
@@ -74,7 +74,7 @@ repaired for. So adoption checks the schema and refuses, rather than reporting
|
|
|
74
74
|
success.
|
|
75
75
|
|
|
76
76
|
The pre-`clientId` store is exactly this case: keyed on the subject alone. An
|
|
77
|
-
operator upgrading meets a sentence instead of a silent
|
|
77
|
+
operator upgrading meets a sentence instead of a silent misbehavior.
|
|
78
78
|
|
|
79
79
|
Order-insensitive, because `DescribeTable` does not promise one.
|
|
80
80
|
*/
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
//
|
|
12
12
|
// * `fromAppSyncIdentity` — AppSync-resolver path. Reads the
|
|
13
13
|
// already-validated identity context attached by AppSync to the
|
|
14
|
-
// resolver event (`event.identity`).
|
|
14
|
+
// resolver event (`event.identity`). Recognizes both the Cognito
|
|
15
15
|
// UserPool shape (`sub`, `username`, `claims['cognito:groups']`) and
|
|
16
16
|
// the AWS_IAM additional-provider shape (`userArn`, `accountId`) used
|
|
17
17
|
// by server-to-server lambdas signed via the existing IAM role.
|
|
@@ -44,7 +44,7 @@ let usernameAttributes = (identifier: t): array<string> =>
|
|
|
44
44
|
/**
|
|
45
45
|
The deploy-time choice, or why the deploy cannot proceed.
|
|
46
46
|
|
|
47
|
-
An
|
|
47
|
+
An unrecognized spelling refuses rather than falling back to the default: a typo
|
|
48
48
|
that defaulted would create a pool signing in on the wrong attribute, which is
|
|
49
49
|
the one property no later deploy can correct.
|
|
50
50
|
*/
|
|
@@ -53,7 +53,7 @@ let allowAdminCreateUserOnly = (mode: t): bool =>
|
|
|
53
53
|
/**
|
|
54
54
|
The deploy-time choice, or why the deploy cannot proceed.
|
|
55
55
|
|
|
56
|
-
An
|
|
56
|
+
An unrecognized spelling refuses rather than falling back to the default, and the
|
|
57
57
|
reason is *not* [Auth_LoginIdentifier]'s — this setting is correctable at any
|
|
58
58
|
time. It is that the mistake would be silent. The default is closed, so a typo
|
|
59
59
|
fails safe, but it fails safe *invisibly*: the deploy is green, the config says
|
|
@@ -138,7 +138,7 @@ let toItem = (
|
|
|
138
138
|
item->Dict.set("tags", tagsJson->JSON.Encode.array)
|
|
139
139
|
|
|
140
140
|
// Flatten meta.* to top-level item attributes so individual meta keys stay
|
|
141
|
-
// GSI-projectable (matches the EventLog adapter
|
|
141
|
+
// GSI-projectable (matches the EventLog adapter behavior). The DCB read
|
|
142
142
|
// path reassembles meta via `Reventless.Message.composeMeta`.
|
|
143
143
|
event.meta
|
|
144
144
|
->ReventlessCore.Message.decomposeMeta
|
|
@@ -986,7 +986,7 @@ let appendUnconditional = async (
|
|
|
986
986
|
// The synthetic fence tag is keyed on `getCompositePartitionKeyValue` — the same
|
|
987
987
|
// value `derivePartitionKey` uses for the base-table `id` — so it is exactly as
|
|
988
988
|
// selective as the entity's storage partition (and the `tag_composite` read
|
|
989
|
-
// scope). Fencing per-member (the historical
|
|
989
|
+
// scope). Fencing per-member (the historical behavior) gave every low-cardinality
|
|
990
990
|
// member (e.g. `environment`, `platformName`) its own fence, which a deploy-time
|
|
991
991
|
// fan-out sharing those prefixes turns into a hot partition → `TransactionConflict`
|
|
992
992
|
// → `retries exhausted`; it also over-fenced (two DISTINCT composite entities
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// its plugin's EventCollector SQS queue.
|
|
15
15
|
//
|
|
16
16
|
// All classic EventLogs in the platform share one selection, mirroring the DCB
|
|
17
|
-
// toggle. Only the Single (sync/async) aggregate strategies
|
|
17
|
+
// toggle. Only the Single (sync/async) aggregate strategies honor it; the
|
|
18
18
|
// PerAggregate and Micro strategies stay DynamoDB-only.
|
|
19
19
|
|
|
20
20
|
type selection = {
|
|
@@ -143,7 +143,7 @@ let emptyConnection = (): JSON.t =>
|
|
|
143
143
|
|
|
144
144
|
// Spec-level authorization then the (optional) user interceptor — mirrors
|
|
145
145
|
// QueryDbResolvers_GraphQL.runInterceptor. Denials return the kind's empty shape
|
|
146
|
-
// (the provider-agnostic resolver
|
|
146
|
+
// (the provider-agnostic resolver behavior), not an error.
|
|
147
147
|
let runInterceptor = async (
|
|
148
148
|
~binding,
|
|
149
149
|
~payload,
|
|
@@ -192,7 +192,7 @@ let dispatch = async (
|
|
|
192
192
|
| RefuseOwned => false
|
|
193
193
|
| ScopeTo(field, required) => item->argStr(field)->Option.mapOr(false, v => v == required)
|
|
194
194
|
}
|
|
195
|
-
// The caller's request to see the archive,
|
|
195
|
+
// The caller's request to see the archive, honored only where the
|
|
196
196
|
// classification says it counts.
|
|
197
197
|
let askedForRetired =
|
|
198
198
|
payload.arguments
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Aggregate Lambda entry point.
|
|
2
|
-
// At cold start: reads HANDLER_CONFIG, dynamically imports Spec+
|
|
2
|
+
// At cold start: reads HANDLER_CONFIG, dynamically imports Spec+Decision modules,
|
|
3
3
|
// wires EventLog_Operations, Aggregate_Callback, CommandTopic_Callback.
|
|
4
4
|
// Handles both SQS CommandTopic events (Route 2) and AppSync direct invocation (Route 1).
|
|
5
5
|
|
|
@@ -135,7 +135,7 @@ async function checkPluginStatus(event) {
|
|
|
135
135
|
// Postgres EventLog runtime; absence keeps the DynamoDB path byte-identical.
|
|
136
136
|
// `eventLogTableName` doubles as the Postgres `event_log.log_name` discriminator
|
|
137
137
|
// (all aggregates share one Postgres table, unlike DynamoDB's table-per-aggregate).
|
|
138
|
-
function buildAggregateParts(specModule,
|
|
138
|
+
function buildAggregateParts(specModule, decisionModule, eventLogTableName, queueUrl, pgConnection) {
|
|
139
139
|
const patchedSpec = patchSpecId(specModule);
|
|
140
140
|
// Typed core: backend-specific EventLog storage ops (Postgres when pgConnection
|
|
141
141
|
// is present, else DynamoDB). Returns the full 6-field EventLog_Adapter.operations
|
|
@@ -147,7 +147,7 @@ function buildAggregateParts(specModule, behaviorModule, eventLogTableName, queu
|
|
|
147
147
|
eventTopic: { publish: async () => {} },
|
|
148
148
|
storage: rawStorageOps,
|
|
149
149
|
});
|
|
150
|
-
const aggregateCallback = aggregateCallbackMake(patchedSpec)(
|
|
150
|
+
const aggregateCallback = aggregateCallbackMake(patchedSpec)(decisionModule)({
|
|
151
151
|
Spec: patchedSpec,
|
|
152
152
|
EventLog: { Spec: patchedSpec },
|
|
153
153
|
eventLog: eventLogOps,
|
|
@@ -227,7 +227,7 @@ const DISPATCH_MODE = process.env["DISPATCH_MODE"] === "async" ? "async" : "sync
|
|
|
227
227
|
// already-parsed `HANDLER_CONFIG` shape, with an injectable module loader. In
|
|
228
228
|
// production, `buildAllHandlers` wraps this with the env config + the Lambda's
|
|
229
229
|
// `/var/task/node_modules` dynamic import; the integration test injects a loader
|
|
230
|
-
// returning pre-imported spec/
|
|
230
|
+
// returning pre-imported spec/decision modules so it can drive the real
|
|
231
231
|
// cmdGenHandler end-to-end against DynamoDB Local. (Mirrors the DCB entry point.)
|
|
232
232
|
export async function buildHandlersForConfig(config, opts = {}) {
|
|
233
233
|
const loadModule = opts.loadModule ?? dynamicImport;
|
|
@@ -236,8 +236,8 @@ export async function buildHandlersForConfig(config, opts = {}) {
|
|
|
236
236
|
const cmdGenHandlers = {};
|
|
237
237
|
await Promise.all((config.handlers || []).map(async h => {
|
|
238
238
|
const specModule = await loadModule(h.specModule);
|
|
239
|
-
const
|
|
240
|
-
const parts = buildAggregateParts(specModule,
|
|
239
|
+
const decisionModule = await loadModule(h.decisionModule);
|
|
240
|
+
const parts = buildAggregateParts(specModule, decisionModule, h.eventLogTable, h.queueUrl, h.pgConnection);
|
|
241
241
|
// Pair each handler with the comp of the aggregate it belongs to: this
|
|
242
242
|
// Lambda can host every aggregate in the platform, so the comp is what keeps
|
|
243
243
|
// their log lines separable.
|