@reventlessdev/reventless-aws 3.0.0-alpha.387 → 3.0.0-alpha.388
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 +14 -0
- package/README.md +1 -1
- package/package.json +12 -12
- package/scripts/ProvisionIdentity.res +1 -1
- package/src/Platform.res +13 -13
- package/src/Platform.res.mjs +28 -28
- package/src/Platform_Stack.res +3 -3
- package/src/adapter/AWS_Tags.res +1 -1
- 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 +8 -8
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +8 -8
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +7 -7
- 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 +2 -2
- 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/RuntimeEnvironment_Lambda.res +2 -2
- package/src/adapter/Runtime/RuntimeExtensionEntryPoint_Ops.res +2 -2
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +10 -10
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +3 -3
- package/src/adapter/StateTopic/StateTopic_AppSync.res +1 -1
- 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 +4 -4
- 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
|
@@ -21,7 +21,7 @@ let log = ReventlessCore.Logger.fromEnv()
|
|
|
21
21
|
extension is registered, which is the only reason a runtime skips the seam.
|
|
22
22
|
|
|
23
23
|
`modules` are npm specifiers resolvable under `/var/task/node_modules` — the
|
|
24
|
-
extension packages ride in the code archive alongside the spec and
|
|
24
|
+
extension packages ride in the code archive alongside the spec and decision
|
|
25
25
|
packages. The remaining fields are this runtime's identity, resolved at
|
|
26
26
|
provisioning time from the ambient `ResourceAttribution` context.
|
|
27
27
|
*/
|
|
@@ -88,7 +88,7 @@ Fire every loaded extension's `onColdStart`, in the order the deploy program
|
|
|
88
88
|
registered them, each isolated from the others (see
|
|
89
89
|
`ReventlessCore.RuntimeExtension`).
|
|
90
90
|
|
|
91
|
-
An
|
|
91
|
+
An unrecognized `runtimeKind` means the layer's `ComponentType` and the
|
|
92
92
|
deploy-time one disagree — a framework version skew, not anything an extension
|
|
93
93
|
can fix. Logged at ERROR and skipped rather than fired under a guessed kind: an
|
|
94
94
|
extension that routes on kind would otherwise attach to the wrong runtime
|
|
@@ -27,7 +27,7 @@ type inboundSlicePaths = {
|
|
|
27
27
|
auditTableName: Pulumi.Output.t<string>,
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
// `slicePaths`: `(specPath,
|
|
30
|
+
// `slicePaths`: `(specPath, decisionPath)` per StateChangeSlice (already merged
|
|
31
31
|
// from auto- and manually-registered sources by the caller).
|
|
32
32
|
let forDcbCommandTopic = (
|
|
33
33
|
~slicePaths: array<(string, string)>,
|
|
@@ -124,9 +124,9 @@ let forDcbCommandTopic = (
|
|
|
124
124
|
envVars->Dict.set("LOG_LEVEL", level->Pulumi.Output.make->Pulumi.Output.asInput)
|
|
125
125
|
)
|
|
126
126
|
|
|
127
|
-
// The slice registry: an array of {spec,
|
|
127
|
+
// The slice registry: an array of {spec, decision} objects so the entry point
|
|
128
128
|
// can dynamically import both modules and apply the curried StateChangeSlice_Callback.Make
|
|
129
|
-
// functor (Make(Spec)(
|
|
129
|
+
// functor (Make(Spec)(Decision)).
|
|
130
130
|
//
|
|
131
131
|
// Shipped as a `sliceModules.json` asset rather than inline in HANDLER_CONFIG.
|
|
132
132
|
// Two absolute module specifiers per slice is the one term here that grows
|
|
@@ -136,10 +136,10 @@ let forDcbCommandTopic = (
|
|
|
136
136
|
// and it fails at deploy with the registry already committed to the stack.
|
|
137
137
|
let sliceModulesJson =
|
|
138
138
|
slicePaths
|
|
139
|
-
->Array.map(((specPath,
|
|
139
|
+
->Array.map(((specPath, decisionPath)) => {
|
|
140
140
|
let s = specPath->JSON.stringifyAny->Option.getOr(`""`)
|
|
141
|
-
let b =
|
|
142
|
-
`{"spec":${s},"
|
|
141
|
+
let b = decisionPath->JSON.stringifyAny->Option.getOr(`""`)
|
|
142
|
+
`{"spec":${s},"decision":${b}}`
|
|
143
143
|
})
|
|
144
144
|
->Array.join(",")
|
|
145
145
|
|
|
@@ -163,7 +163,7 @@ let forDcbCommandTopic = (
|
|
|
163
163
|
// InboundTranslationSlice modules — spec + translation paths and the resolved
|
|
164
164
|
// audit table name (Pulumi-generated, so it must be resolved here). Emitted as
|
|
165
165
|
// a `,"inboundTranslationSliceModules":[…]` fragment merged into HANDLER_CONFIG
|
|
166
|
-
// (absent → the entry point has no Route 0 registry, unchanged
|
|
166
|
+
// (absent → the entry point has no Route 0 registry, unchanged behavior).
|
|
167
167
|
let inboundFragment = switch inboundSlices {
|
|
168
168
|
| [] => Pulumi.Output.make("")
|
|
169
169
|
| slices =>
|
|
@@ -201,11 +201,11 @@ let forDcbCommandTopic = (
|
|
|
201
201
|
|
|
202
202
|
// Build code asset
|
|
203
203
|
let packageDirs: dict<string> = Dict.make()
|
|
204
|
-
slicePaths->Array.forEach(((specPath,
|
|
204
|
+
slicePaths->Array.forEach(((specPath, decisionPath)) => {
|
|
205
205
|
let specPkg = Util_Bundle.extractPackageName(specPath)
|
|
206
206
|
packageDirs->Dict.set(specPkg, Util_Bundle.resolvePackageRoot(specPkg))
|
|
207
|
-
let
|
|
208
|
-
packageDirs->Dict.set(
|
|
207
|
+
let decisionPkg = Util_Bundle.extractPackageName(decisionPath)
|
|
208
|
+
packageDirs->Dict.set(decisionPkg, Util_Bundle.resolvePackageRoot(decisionPkg))
|
|
209
209
|
})
|
|
210
210
|
// Inbound slice spec + translation packages the entry point imports for Route 0.
|
|
211
211
|
inboundSlices->Array.forEach(s => {
|
|
@@ -67,7 +67,7 @@ function forDcbCommandTopic(slicePaths, inboundSlicesOpt, dcbTableName, pluginNa
|
|
|
67
67
|
let sliceModulesJson = slicePaths.map(param => {
|
|
68
68
|
let s = Stdlib_Option.getOr(JSON.stringify(param[0]), `""`);
|
|
69
69
|
let b = Stdlib_Option.getOr(JSON.stringify(param[1]), `""`);
|
|
70
|
-
return `{"spec":` + s + `,"
|
|
70
|
+
return `{"spec":` + s + `,"decision":` + b + `}`;
|
|
71
71
|
}).join(",");
|
|
72
72
|
let pgConnectionFragment = pgSelection !== undefined ? pgSelection.connectionConfig.apply(cc => `,"pgConnection":` + JSON.stringify(PgConnection$ReventlessAws.connectionConfigToJson(pgSelection.lockStrategy, cc))) : Pulumi.output("");
|
|
73
73
|
let inboundFragment = inboundSlices.length !== 0 ? Pulumi.all(inboundSlices.map(s => s.auditTableName)).apply(tableNames => {
|
|
@@ -96,8 +96,8 @@ function forDcbCommandTopic(slicePaths, inboundSlicesOpt, dcbTableName, pluginNa
|
|
|
96
96
|
slicePaths.forEach(param => {
|
|
97
97
|
let specPkg = Util_Bundle$ReventlessAws.extractPackageName(param[0]);
|
|
98
98
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(undefined, specPkg);
|
|
99
|
-
let
|
|
100
|
-
packageDirs[
|
|
99
|
+
let decisionPkg = Util_Bundle$ReventlessAws.extractPackageName(param[1]);
|
|
100
|
+
packageDirs[decisionPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(undefined, decisionPkg);
|
|
101
101
|
});
|
|
102
102
|
inboundSlices.forEach(s => {
|
|
103
103
|
let specPkg = Util_Bundle$ReventlessAws.extractPackageName(s.specPath);
|
|
@@ -388,7 +388,7 @@ let finish = (~eventsApi: AppSync_EventsApi.t, ~opts: Pulumi.CustomResourceOptio
|
|
|
388
388
|
// One EventSourceMapping per stream, all targeting the shared Lambda.
|
|
389
389
|
// Retry posture: the handler throws on 5xx / network errors and logs-and-
|
|
390
390
|
// continues on 4xx. `maximumRetryAttempts: 3` bounds the per-record
|
|
391
|
-
// retries so a permanently broken record (default DDB stream
|
|
391
|
+
// retries so a permanently broken record (default DDB stream behavior is
|
|
392
392
|
// -1 → forever, which would wedge the shard); `bisectBatchOnFunctionError`
|
|
393
393
|
// isolates the bad record across those retries instead of redelivering
|
|
394
394
|
// the whole batch each time.
|
|
@@ -36,7 +36,7 @@ let smsSenderKey = "messagingSmsSender"
|
|
|
36
36
|
Blank matters because the ways to write "nothing" must not differ: a stray
|
|
37
37
|
`REVENTLESS_MESSAGING_EMAIL_SENDER=` in CI, a blank line in
|
|
38
38
|
`Pulumi.local.yaml`, and a key left with a space after the colon all mean the
|
|
39
|
-
stack named no sender.
|
|
39
|
+
stack named no sender. Honoring any of them would ask SES for an identity
|
|
40
40
|
with a blank address — a deploy failure whose cause is whitespace, and one
|
|
41
41
|
that reaches AWS before anything here explains it.
|
|
42
42
|
|
|
@@ -69,7 +69,7 @@ Which transport this stack asked for. SES is the default, so a deployment that
|
|
|
69
69
|
says nothing gets the real one — the safe direction is that mail works, and a
|
|
70
70
|
stack opting out of sending says so explicitly.
|
|
71
71
|
|
|
72
|
-
An
|
|
72
|
+
An unrecognized value is refused rather than defaulted. Falling back to SES on a
|
|
73
73
|
typo would provision a real identity for a stack that asked to only log, which
|
|
74
74
|
is the one mistake this key exists to prevent.
|
|
75
75
|
*/
|
|
@@ -11,7 +11,7 @@ module type MappingsConfig = {
|
|
|
11
11
|
|
|
12
12
|
module Make = (
|
|
13
13
|
Spec: Reventless.Aggregate.Spec,
|
|
14
|
-
|
|
14
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
15
15
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
16
16
|
MappingsConfig: MappingsConfig,
|
|
17
17
|
): (
|
|
@@ -21,7 +21,7 @@ module Make = (
|
|
|
21
21
|
) => {
|
|
22
22
|
module Inner = ReventlessCore.Aggregate_Builder.Make(
|
|
23
23
|
Spec,
|
|
24
|
-
|
|
24
|
+
Decision,
|
|
25
25
|
EventMappings,
|
|
26
26
|
RuntimeEnvironment,
|
|
27
27
|
CommandGeneratorResolvers,
|
|
@@ -49,7 +49,7 @@ module Make = (
|
|
|
49
49
|
AggregateRuntimeBuilder.registerAggregate(
|
|
50
50
|
~aggregateName=Spec.name,
|
|
51
51
|
~specModulePath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
52
|
-
~
|
|
52
|
+
~decisionModulePath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
53
53
|
~eventLogTableName,
|
|
54
54
|
~mappingsModulePath=?MappingsConfig.mappingsModulePath,
|
|
55
55
|
)
|
|
@@ -12,8 +12,8 @@ import * as EventTopicPublisher_DynamoDbStream$ReventlessAws from "../adapter/Ev
|
|
|
12
12
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
13
13
|
|
|
14
14
|
function Make(Spec) {
|
|
15
|
-
return
|
|
16
|
-
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(
|
|
15
|
+
return Decision => (EventMappings => (MappingsConfig => {
|
|
16
|
+
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(Decision)({
|
|
17
17
|
mappings: EventMappings.mappings,
|
|
18
18
|
counter: EventMappings.counter
|
|
19
19
|
})({
|
|
@@ -48,7 +48,7 @@ function Make(Spec) {
|
|
|
48
48
|
let eventLogOutputs = Inner.outputs(aggregate).eventLog;
|
|
49
49
|
let tableResource = eventLogOutputs.resources[0];
|
|
50
50
|
let eventLogTableName = tableResource.name;
|
|
51
|
-
AggregateRuntime_Builder_Micro$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(
|
|
51
|
+
AggregateRuntime_Builder_Micro$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Decision.moduleUrl), eventLogTableName, MappingsConfig.mappingsModulePath);
|
|
52
52
|
return aggregate;
|
|
53
53
|
};
|
|
54
54
|
let finish = () => AggregateRuntime_Builder_Micro$ReventlessAws.finish();
|
|
@@ -11,7 +11,7 @@ module AggregateRuntimeBuilder = AggregateRuntime_Builder_Single
|
|
|
11
11
|
|
|
12
12
|
module Make = (
|
|
13
13
|
Spec: Reventless.Aggregate.Spec,
|
|
14
|
-
|
|
14
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
15
15
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
16
16
|
): (
|
|
17
17
|
ReventlessInfra.Aggregate.T
|
|
@@ -20,7 +20,7 @@ module Make = (
|
|
|
20
20
|
) => {
|
|
21
21
|
module Inner = ReventlessCore.Aggregate_Builder.Make(
|
|
22
22
|
Spec,
|
|
23
|
-
|
|
23
|
+
Decision,
|
|
24
24
|
EventMappings,
|
|
25
25
|
RuntimeEnvironment,
|
|
26
26
|
CommandGeneratorResolvers,
|
|
@@ -48,7 +48,7 @@ module Make = (
|
|
|
48
48
|
AggregateRuntimeBuilder.registerAggregate(
|
|
49
49
|
~aggregateName=Spec.name,
|
|
50
50
|
~specModulePath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
51
|
-
~
|
|
51
|
+
~decisionModulePath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
52
52
|
~eventLogTableName,
|
|
53
53
|
)
|
|
54
54
|
|
|
@@ -12,8 +12,8 @@ import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../adapter/
|
|
|
12
12
|
import * as CommandGeneratorResolvers_AppSync_NoOp$ReventlessAws from "../adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res.mjs";
|
|
13
13
|
|
|
14
14
|
function Make(Spec) {
|
|
15
|
-
return
|
|
16
|
-
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(
|
|
15
|
+
return Decision => (EventMappings => {
|
|
16
|
+
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(Decision)({
|
|
17
17
|
mappings: EventMappings.mappings,
|
|
18
18
|
counter: EventMappings.counter
|
|
19
19
|
})({
|
|
@@ -48,7 +48,7 @@ function Make(Spec) {
|
|
|
48
48
|
let eventLogOutputs = Inner.outputs(aggregate).eventLog;
|
|
49
49
|
let tableResource = eventLogOutputs.resources[0];
|
|
50
50
|
let eventLogTableName = tableResource.name;
|
|
51
|
-
AggregateRuntime_Builder_Single$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(
|
|
51
|
+
AggregateRuntime_Builder_Single$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Decision.moduleUrl), eventLogTableName);
|
|
52
52
|
return aggregate;
|
|
53
53
|
};
|
|
54
54
|
let finish = () => AggregateRuntime_Builder_Single$ReventlessAws.finish();
|
|
@@ -7,7 +7,7 @@ module AggregateRuntimeBuilder = AggregateRuntime_Builder_PerAggregate
|
|
|
7
7
|
|
|
8
8
|
module Make = (
|
|
9
9
|
Spec: Reventless.Aggregate.Spec,
|
|
10
|
-
|
|
10
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
11
11
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
12
12
|
): (
|
|
13
13
|
ReventlessInfra.Aggregate.T
|
|
@@ -16,7 +16,7 @@ module Make = (
|
|
|
16
16
|
) => {
|
|
17
17
|
module Inner = ReventlessCore.Aggregate_Builder.Make(
|
|
18
18
|
Spec,
|
|
19
|
-
|
|
19
|
+
Decision,
|
|
20
20
|
EventMappings,
|
|
21
21
|
RuntimeEnvironment,
|
|
22
22
|
CommandGeneratorResolvers,
|
|
@@ -44,7 +44,7 @@ module Make = (
|
|
|
44
44
|
AggregateRuntimeBuilder.registerAggregate(
|
|
45
45
|
~aggregateName=Spec.name,
|
|
46
46
|
~specModulePath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
47
|
-
~
|
|
47
|
+
~decisionModulePath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
48
48
|
~eventLogTableName,
|
|
49
49
|
)
|
|
50
50
|
|
|
@@ -12,8 +12,8 @@ import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../adapter/
|
|
|
12
12
|
import * as AggregateRuntime_Builder_PerAggregate$ReventlessAws from "../adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs";
|
|
13
13
|
|
|
14
14
|
function Make(Spec) {
|
|
15
|
-
return
|
|
16
|
-
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(
|
|
15
|
+
return Decision => (EventMappings => {
|
|
16
|
+
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(Decision)({
|
|
17
17
|
mappings: EventMappings.mappings,
|
|
18
18
|
counter: EventMappings.counter
|
|
19
19
|
})({
|
|
@@ -48,7 +48,7 @@ function Make(Spec) {
|
|
|
48
48
|
let eventLogOutputs = Inner.outputs(aggregate).eventLog;
|
|
49
49
|
let tableResource = eventLogOutputs.resources[0];
|
|
50
50
|
let eventLogTableName = tableResource.name;
|
|
51
|
-
AggregateRuntime_Builder_PerAggregate$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(
|
|
51
|
+
AggregateRuntime_Builder_PerAggregate$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Decision.moduleUrl), eventLogTableName);
|
|
52
52
|
return aggregate;
|
|
53
53
|
};
|
|
54
54
|
let finish = () => AggregateRuntime_Builder_PerAggregate$ReventlessAws.finish();
|
|
@@ -7,7 +7,7 @@ module AggregateRuntimeBuilder = AggregateRuntime_Builder_Single
|
|
|
7
7
|
|
|
8
8
|
module Make = (
|
|
9
9
|
Spec: Reventless.Aggregate.Spec,
|
|
10
|
-
|
|
10
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
11
11
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
12
12
|
): (
|
|
13
13
|
ReventlessInfra.Aggregate.T
|
|
@@ -16,7 +16,7 @@ module Make = (
|
|
|
16
16
|
) => {
|
|
17
17
|
module Inner = ReventlessCore.Aggregate_Builder.Make(
|
|
18
18
|
Spec,
|
|
19
|
-
|
|
19
|
+
Decision,
|
|
20
20
|
EventMappings,
|
|
21
21
|
RuntimeEnvironment,
|
|
22
22
|
CommandGeneratorResolvers,
|
|
@@ -53,7 +53,7 @@ module Make = (
|
|
|
53
53
|
AggregateRuntimeBuilder.registerAggregate(
|
|
54
54
|
~aggregateName=Spec.name,
|
|
55
55
|
~specModulePath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
56
|
-
~
|
|
56
|
+
~decisionModulePath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
57
57
|
~eventLogTableName,
|
|
58
58
|
)
|
|
59
59
|
|
|
@@ -14,8 +14,8 @@ import * as EventTopicPublisher_DynamoDbStream$ReventlessAws from "../adapter/Ev
|
|
|
14
14
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
15
15
|
|
|
16
16
|
function Make(Spec) {
|
|
17
|
-
return
|
|
18
|
-
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(
|
|
17
|
+
return Decision => (EventMappings => {
|
|
18
|
+
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(Decision)({
|
|
19
19
|
mappings: EventMappings.mappings,
|
|
20
20
|
counter: EventMappings.counter
|
|
21
21
|
})({
|
|
@@ -54,7 +54,7 @@ function Make(Spec) {
|
|
|
54
54
|
let eventLogOutputs = Inner.outputs(aggregate).eventLog;
|
|
55
55
|
eventLogTableName = eventLogOutputs.resources[0].name;
|
|
56
56
|
}
|
|
57
|
-
AggregateRuntime_Builder_Single$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(
|
|
57
|
+
AggregateRuntime_Builder_Single$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Decision.moduleUrl), eventLogTableName);
|
|
58
58
|
return aggregate;
|
|
59
59
|
};
|
|
60
60
|
let finish = () => AggregateRuntime_Builder_Single$ReventlessAws.finish();
|
|
@@ -7,7 +7,7 @@ module AggregateRuntimeBuilder = AggregateRuntime_Builder_Single_Async
|
|
|
7
7
|
|
|
8
8
|
module Make = (
|
|
9
9
|
Spec: Reventless.Aggregate.Spec,
|
|
10
|
-
|
|
10
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
11
11
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
12
12
|
): (
|
|
13
13
|
ReventlessInfra.Aggregate.T
|
|
@@ -16,7 +16,7 @@ module Make = (
|
|
|
16
16
|
) => {
|
|
17
17
|
module Inner = ReventlessCore.Aggregate_Builder.Make(
|
|
18
18
|
Spec,
|
|
19
|
-
|
|
19
|
+
Decision,
|
|
20
20
|
EventMappings,
|
|
21
21
|
RuntimeEnvironment,
|
|
22
22
|
CommandGeneratorResolvers,
|
|
@@ -53,7 +53,7 @@ module Make = (
|
|
|
53
53
|
AggregateRuntimeBuilder.registerAggregate(
|
|
54
54
|
~aggregateName=Spec.name,
|
|
55
55
|
~specModulePath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
56
|
-
~
|
|
56
|
+
~decisionModulePath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
57
57
|
~eventLogTableName,
|
|
58
58
|
)
|
|
59
59
|
|
|
@@ -14,8 +14,8 @@ import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../adapter/
|
|
|
14
14
|
import * as AggregateRuntime_Builder_Single_Async$ReventlessAws from "../adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs";
|
|
15
15
|
|
|
16
16
|
function Make(Spec) {
|
|
17
|
-
return
|
|
18
|
-
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(
|
|
17
|
+
return Decision => (EventMappings => {
|
|
18
|
+
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(Decision)({
|
|
19
19
|
mappings: EventMappings.mappings,
|
|
20
20
|
counter: EventMappings.counter
|
|
21
21
|
})({
|
|
@@ -54,7 +54,7 @@ function Make(Spec) {
|
|
|
54
54
|
let eventLogOutputs = Inner.outputs(aggregate).eventLog;
|
|
55
55
|
eventLogTableName = eventLogOutputs.resources[0].name;
|
|
56
56
|
}
|
|
57
|
-
AggregateRuntime_Builder_Single_Async$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(
|
|
57
|
+
AggregateRuntime_Builder_Single_Async$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Decision.moduleUrl), eventLogTableName);
|
|
58
58
|
return aggregate;
|
|
59
59
|
};
|
|
60
60
|
let finish = () => AggregateRuntime_Builder_Single_Async$ReventlessAws.finish();
|
|
@@ -197,13 +197,13 @@ let rec waitForMergeSuccess = async (
|
|
|
197
197
|
// the opposite of what the spec says. AppSync has no anonymous mode to emit
|
|
198
198
|
// instead (`authenticationType` is API_KEY | AWS_IAM | AMAZON_COGNITO_USER_POOLS
|
|
199
199
|
// | OPENID_CONNECT, and this adapter provisions Cognito primary with AWS_IAM
|
|
200
|
-
// additional), so there is no directive that means "no auth". The old
|
|
200
|
+
// additional), so there is no directive that means "no auth". The old behavior
|
|
201
201
|
// deployed green, passed `assertGateable`, worked on the local platform — whose
|
|
202
|
-
// resolvers call `Authorization.isAllowed` and
|
|
202
|
+
// resolvers call `Authorization.isAllowed` and honor the rule — and refused
|
|
203
203
|
// anonymous callers only on AWS. It failed CLOSED, which is why nothing
|
|
204
204
|
// surfaced it.
|
|
205
205
|
//
|
|
206
|
-
// Refusing follows `Auth_LoginIdentifier`'s rule for an
|
|
206
|
+
// Refusing follows `Auth_LoginIdentifier`'s rule for an unrecognized spelling:
|
|
207
207
|
// a silent contradiction of the source is worse than a stopped deploy, because
|
|
208
208
|
// only one of the two is discoverable. AppSync mutations have no runtime
|
|
209
209
|
// authorization check to fall back on — the only `Authorization.isAllowed` call
|
|
@@ -71,7 +71,7 @@ let injectAwsSubscribe = (
|
|
|
71
71
|
// Cognito group gate. `@aws_cognito_user_pools(cognito_groups: [...])` — NOT the
|
|
72
72
|
// single-mode `@aws_auth(cognito_groups: [...])`.
|
|
73
73
|
//
|
|
74
|
-
// `@aws_auth` is
|
|
74
|
+
// `@aws_auth` is honored only on an API whose sole authorization mode is
|
|
75
75
|
// AMAZON_COGNITO_USER_POOLS. This adapter always configures AWS_IAM as an
|
|
76
76
|
// additional provider (see AppSync_Adapter's api args — the server-to-server
|
|
77
77
|
// lambdas need it), so every API we provision is multi-auth and the service
|
|
@@ -323,7 +323,7 @@ let stampTypeDualAuth = (decl: string): string =>
|
|
|
323
323
|
//
|
|
324
324
|
// Two conditions, and the second is the one that matters:
|
|
325
325
|
//
|
|
326
|
-
// 1. A root field or object type carrying NO directive AppSync
|
|
326
|
+
// 1. A root field or object type carrying NO directive AppSync honors here
|
|
327
327
|
// is reachable by any authenticated Cognito caller under `ALLOW`.
|
|
328
328
|
// 2. ANY `@aws_auth` at all. It is the single-mode form, silently ignored on
|
|
329
329
|
// a multi-auth API — so its presence means something believes it is gated
|
|
@@ -332,7 +332,7 @@ let stampTypeDualAuth = (decl: string): string =>
|
|
|
332
332
|
// Condition 2 is why this is not merely "does it have a directive?". The
|
|
333
333
|
// original outage had `@aws_auth(cognito_groups: ["Admin"])` present on all 18
|
|
334
334
|
// admin fields for its entire life; a presence check would have passed it every
|
|
335
|
-
// single time. Only a check that knows WHICH directive the service
|
|
335
|
+
// single time. Only a check that knows WHICH directive the service honors
|
|
336
336
|
// would have failed that deploy.
|
|
337
337
|
let enforcedDirectives = ["@aws_cognito_user_pools", "@aws_iam"]
|
|
338
338
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// in that registry, so it took the builder's `None` arm, logged
|
|
14
14
|
// "no bundled info registered", and created nothing — silently.
|
|
15
15
|
//
|
|
16
|
-
// Matching signatures are not matching
|
|
16
|
+
// Matching signatures are not matching behavior. The registry a builder reads is
|
|
17
17
|
// the part that has to line up: side-effect handlers need `sideEffectInfos` and
|
|
18
18
|
// `SideEffectEntryPoint.mjs`, which is what `SideEffectHandler_Single` registers into.
|
|
19
19
|
//
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
module Make = (
|
|
4
4
|
Spec: Reventless.StateChangeSlice.Spec,
|
|
5
|
-
|
|
5
|
+
Decision: Reventless.StateChangeSlice.Decision with module Spec := Spec,
|
|
6
6
|
): (ReventlessCore.StateChangeSlice.T with module Spec = Spec) => {
|
|
7
7
|
PluginRuntime_Builder.registerStateChangeSliceSpec(
|
|
8
8
|
~specPath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
9
|
-
~
|
|
9
|
+
~decisionPath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
10
10
|
)
|
|
11
|
-
module Inner = ReventlessCore.StateChangeSlice_Builder.Make(Spec,
|
|
11
|
+
module Inner = ReventlessCore.StateChangeSlice_Builder.Make(Spec, Decision)
|
|
12
12
|
module Spec = Spec
|
|
13
|
-
module
|
|
13
|
+
module Decision = Decision
|
|
14
14
|
let isAsync = Inner.isAsync
|
|
15
15
|
type component = Inner.component
|
|
16
16
|
let make = Inner.make
|
|
@@ -5,12 +5,12 @@ import * as PluginRuntime_Builder$ReventlessAws from "../plugin/runtime/PluginRu
|
|
|
5
5
|
import * as StateChangeSlice_Builder$ReventlessCore from "@reventlessdev/reventless-core/src/components/StateChangeSlice/StateChangeSlice_Builder.res.mjs";
|
|
6
6
|
|
|
7
7
|
function Make(Spec) {
|
|
8
|
-
return
|
|
9
|
-
PluginRuntime_Builder$ReventlessAws.registerStateChangeSliceSpec(Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(
|
|
10
|
-
let Inner = StateChangeSlice_Builder$ReventlessCore.Make(Spec)(
|
|
8
|
+
return Decision => {
|
|
9
|
+
PluginRuntime_Builder$ReventlessAws.registerStateChangeSliceSpec(Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Decision.moduleUrl));
|
|
10
|
+
let Inner = StateChangeSlice_Builder$ReventlessCore.Make(Spec)(Decision);
|
|
11
11
|
return {
|
|
12
12
|
Spec: Spec,
|
|
13
|
-
|
|
13
|
+
Decision: Decision,
|
|
14
14
|
isAsync: Inner.isAsync,
|
|
15
15
|
make: Inner.make
|
|
16
16
|
};
|
|
@@ -93,7 +93,7 @@ let messagingProvisioned = () => messagingProvisionedRef.contents
|
|
|
93
93
|
|
|
94
94
|
type sliceModulePaths = {
|
|
95
95
|
specPath: string,
|
|
96
|
-
|
|
96
|
+
decisionPath: string,
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
type dcbConfig = {
|
|
@@ -110,8 +110,8 @@ let dcbConfigRef: ref<dcbConfig> = ref({
|
|
|
110
110
|
|
|
111
111
|
let registeredSliceModulePaths: array<sliceModulePaths> = []
|
|
112
112
|
|
|
113
|
-
let registerStateChangeSliceSpec = (~specPath: string, ~
|
|
114
|
-
let _ = registeredSliceModulePaths->Array.push({specPath,
|
|
113
|
+
let registerStateChangeSliceSpec = (~specPath: string, ~decisionPath: string) => {
|
|
114
|
+
let _ = registeredSliceModulePaths->Array.push({specPath, decisionPath})
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
// InboundTranslationSlice registration for the shared DCB command Lambda. Unlike
|
|
@@ -933,7 +933,7 @@ module Make = (
|
|
|
933
933
|
let slicePaths =
|
|
934
934
|
registeredSliceModulePaths
|
|
935
935
|
->Array.concat(dcbConfig.stateChangeSliceModulePaths)
|
|
936
|
-
->Array.map(({specPath,
|
|
936
|
+
->Array.map(({specPath, decisionPath}) => (specPath, decisionPath))
|
|
937
937
|
// Drop registrations that never received their module paths (a bare
|
|
938
938
|
// audit-table registration with no matching spec functor — shouldn't happen,
|
|
939
939
|
// but keeps a half-registered slice out of HANDLER_CONFIG).
|
|
@@ -101,10 +101,10 @@ let dcbConfigRef = {
|
|
|
101
101
|
|
|
102
102
|
let registeredSliceModulePaths = [];
|
|
103
103
|
|
|
104
|
-
function registerStateChangeSliceSpec(specPath,
|
|
104
|
+
function registerStateChangeSliceSpec(specPath, decisionPath) {
|
|
105
105
|
registeredSliceModulePaths.push({
|
|
106
106
|
specPath: specPath,
|
|
107
|
-
|
|
107
|
+
decisionPath: decisionPath
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -547,7 +547,7 @@ function Make(EventCollectorChannel) {
|
|
|
547
547
|
let dcbConfig = dcbConfigRef.contents;
|
|
548
548
|
let slicePaths = registeredSliceModulePaths.concat(dcbConfig.stateChangeSliceModulePaths).map(param => [
|
|
549
549
|
param.specPath,
|
|
550
|
-
param.
|
|
550
|
+
param.decisionPath
|
|
551
551
|
]);
|
|
552
552
|
let inboundSlices = Stdlib_Array.filterMap(Object.values(registeredInboundSlices), reg => {
|
|
553
553
|
if (reg.specPath === "") {
|
|
@@ -524,7 +524,7 @@ let makeUiBundleDistribution = (
|
|
|
524
524
|
|
|
525
525
|
// Auto-invalidate CloudFront once every object is (re)uploaded. Stable-named
|
|
526
526
|
// entry files (index.html, the module-federation mf-entry-bootstrap-*.js)
|
|
527
|
-
// are served by the long-TTL default cache
|
|
527
|
+
// are served by the long-TTL default cache behavior, so without this a
|
|
528
528
|
// `pulumi up` lands the new bundle in S3 while CloudFront keeps serving the
|
|
529
529
|
// prior build until its TTL expires. Chained on the upload etags so it runs
|
|
530
530
|
// AFTER the new content is in S3; `/*` is a single invalidation path (well
|
package/src/util/Util_Bundle.res
CHANGED
|
@@ -254,7 +254,7 @@ type codeArchive = {
|
|
|
254
254
|
*
|
|
255
255
|
* `ReventlessCore.RuntimeExtension` carries `import.meta.url`s because that is
|
|
256
256
|
* what an extension module can state about itself; the npm specifier a Lambda
|
|
257
|
-
* resolves is derived here, the same conversion spec and
|
|
257
|
+
* resolves is derived here, the same conversion spec and decision modules go
|
|
258
258
|
* through.
|
|
259
259
|
*/
|
|
260
260
|
let runtimeExtensionSpecifiers = (): array<string> =>
|
|
@@ -330,7 +330,7 @@ describe("AppSync_Adapter.injectAwsAuth — Stage E2 permission lifting", () =>
|
|
|
330
330
|
// and emitted the same group-less directive, which on this Cognito-primary
|
|
331
331
|
// API means *any authenticated caller* — the inverse of the declaration. It
|
|
332
332
|
// deployed green, passed `assertGateable`, and worked on the local platform,
|
|
333
|
-
// whose resolvers call `Authorization.isAllowed` and
|
|
333
|
+
// whose resolvers call `Authorization.isAllowed` and honor the rule. It
|
|
334
334
|
// failed closed, so no deployment ever reported it.
|
|
335
335
|
|
|
336
336
|
let refuses = (run: unit => 'a): bool =>
|
|
@@ -192,7 +192,7 @@ describe("the by-index door's owner scoping", () => {
|
|
|
192
192
|
)->Expect.toBe(true)
|
|
193
193
|
)
|
|
194
194
|
|
|
195
|
-
// The generic argument loop turns an
|
|
195
|
+
// The generic argument loop turns an unrecognized arg into a `contains` filter.
|
|
196
196
|
// `includeRetired` is a request to lift a restriction, and filtering on it
|
|
197
197
|
// would match no row at all.
|
|
198
198
|
testSync("never treats includeRetired as a column to match on", () =>
|
|
@@ -270,7 +270,7 @@ describe("AppSync_SdlDecorate.assertGateable", () => {
|
|
|
270
270
|
|
|
271
271
|
// The original outage, exactly. A "does it have a directive?" check passes
|
|
272
272
|
// this — @aws_auth was present on all 18 admin fields the whole time it was
|
|
273
|
-
// inert. Only knowing WHICH directive the service
|
|
273
|
+
// inert. Only knowing WHICH directive the service honors catches it.
|
|
274
274
|
testSync("refuses @aws_auth, the directive AppSync ignores here", () => {
|
|
275
275
|
let sdl = `type Query @aws_cognito_user_pools {\n Admin_Thing: String @aws_auth(cognito_groups: ["Admin"])\n}`
|
|
276
276
|
expect(refuses(sdl))->toBe(true)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
open JestGlobals
|
|
2
2
|
|
|
3
3
|
// The sign-in attribute is the one pool setting no later deploy can correct, so
|
|
4
|
-
// what these cover is the parse: absent must mean today's
|
|
4
|
+
// what these cover is the parse: absent must mean today's behavior, and a
|
|
5
5
|
// spelling this build does not know must refuse rather than default.
|
|
6
6
|
|
|
7
7
|
module LoginIdentifier = Auth_LoginIdentifier
|
|
@@ -2,7 +2,7 @@ open JestGlobals
|
|
|
2
2
|
|
|
3
3
|
// Sign-up mode is correctable on a live pool, unlike the sign-in attribute, so
|
|
4
4
|
// what these cover is not permanence but silence: absent must mean today's
|
|
5
|
-
//
|
|
5
|
+
// behavior, an unknown spelling must refuse rather than quietly close the pool,
|
|
6
6
|
// and the mapping onto Cognito's inverted field must not be readable backwards.
|
|
7
7
|
|
|
8
8
|
module SignUpMode = Auth_SignUpMode
|