@reventlessdev/reventless-aws 3.0.0-alpha.396 → 3.0.0-alpha.398
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 +40 -0
- package/package.json +8 -8
- package/scripts/BakeManifest.res +15 -15
- package/scripts/DeployApp.res +8 -9
- package/scripts/DeployApp.res.mjs +4 -13
- package/scripts/DeployManifest.res +4 -5
- package/scripts/DeployManifest.res.mjs +0 -1
- package/scripts/ProvisionAccounts.res +41 -33
- package/scripts/ProvisionAccounts.res.mjs +6 -9
- package/scripts/ProvisionAdmin.res +10 -10
- package/scripts/ProvisionIdentity.res +2 -2
- package/scripts/ResolveEnvironment.res +3 -3
- package/src/Platform.res +6 -4
- package/src/Platform.res.mjs +6 -4
- package/src/Platform_ProvidedGroups.res +4 -4
- package/src/Platform_Stack.res +2 -3
- package/src/Platform_Stack.res.mjs +1 -2
- package/src/adapter/Api/AppSyncEventsSigner_Ops.res +2 -2
- package/src/adapter/Api/AppSync_EventsApi.res +2 -2
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +6 -6
- package/src/adapter/Auth/Auth_ActiveRoleTrigger.res +15 -8
- package/src/adapter/Auth/Auth_ActiveRoleTrigger.res.mjs +7 -7
- package/src/adapter/Auth/Auth_IdentityStore.res +41 -2
- package/src/adapter/Auth/Auth_IdentityStore.res.mjs +42 -3
- package/src/adapter/DcbEventLog/DcbBackend.res +3 -3
- package/src/adapter/DcbEventLog/DcbBackend.res.mjs +1 -3
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +11 -9
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res.mjs +4 -6
- package/src/adapter/EventLog/EventLogBackend.res +3 -3
- package/src/adapter/EventLog/EventLogBackend.res.mjs +1 -3
- package/src/adapter/Geocoder/Geocoder_AwsLocation_Backend.res +1 -1
- package/src/adapter/QueryDb/PgQueryResolver_Lambda.res +5 -5
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +2 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +2 -2
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +32 -32
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res.mjs +4 -3
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +6 -6
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +16 -5
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res.mjs +3 -3
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +5 -5
- package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res +24 -18
- package/src/adapter/Runtime/ReadModelEntryPoint_Ops.res +16 -14
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +2 -2
- package/src/adapter/Runtime/RuntimeExtensionEntryPoint_Ops.res +4 -4
- package/src/adapter/Runtime/SideEffectEntryPoint_Ops.res +4 -4
- package/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res +9 -9
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +11 -9
- package/src/components/Api/AppSync_Adapter.res +4 -4
- package/src/components/InboundTranslationSlice_Builder.res +19 -0
- package/src/components/InboundTranslationSlice_Builder.res.mjs +12 -2
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +4 -7
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs +1 -4
- package/src/plugin/runtime/PluginRuntime_Builder.res +17 -26
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +7 -22
- package/tests/AppSyncEventsSigner_OpsTest.res +1 -1
- package/tests/AppSync_AdapterTest.res +4 -4
- package/tests/AppSync_AdapterTest.res.mjs +4 -8
- package/tests/Auth_ActiveRoleStoreTest.res +1 -1
- package/tests/Auth_ActiveRoleTrigger_OpsTest.res +1 -1
- package/tests/AutomationSliceEntryPoint_OpsTest.res +0 -2
- package/tests/AutomationSliceEntryPoint_OpsTest.res.mjs +3 -6
- package/tests/BakeConvergenceTest.res +1 -8
- package/tests/BakeConvergenceTest.res.mjs +3 -23
- package/tests/BakeManifestTest.res +5 -10
- package/tests/BakeManifestTest.res.mjs +1 -6
- package/tests/CommandLineTest.res +3 -3
- package/tests/DeployAppTest.res +3 -4
- package/tests/DeployAppTest.res.mjs +6 -15
- package/tests/EpInboundTestSlice.res +1 -0
- package/tests/EpInboundTestSlice.res.mjs +3 -0
- package/tests/EventCollectorPluginDefinitionAssetTest.res +1 -2
- package/tests/EventCollectorPluginDefinitionAssetTest.res.mjs +11 -21
- package/tests/IdentityProvider_Cognito_BackendTest.res +0 -3
- package/tests/IdentityProvider_Cognito_BackendTest.res.mjs +0 -3
- package/tests/PgQueryResolver_LambdaTest.res +6 -10
- package/tests/PgQueryResolver_LambdaTest.res.mjs +4 -34
- package/tests/Platform_ProvidedGroupsTest.res +2 -2
- package/tests/Platform_ProvidedGroupsTest.res.mjs +1 -2
- package/tests/ProvisionAccountsTest.res +5 -10
- package/tests/ProvisionAccountsTest.res.mjs +0 -9
- package/tests/ProvisionAdminTest.res +4 -9
- package/tests/ProvisionAdminTest.res.mjs +0 -7
- package/tests/ProvisionIdentityTest.res +2 -4
- package/tests/ProvisionIdentityTest.res.mjs +0 -2
- package/tests/SideEffectEntryPoint_OpsTest.res +2 -2
- package/tests/Util_ShellConfigTest.res +3 -3
- package/tests/Util_ShellConfigTest.res.mjs +1 -2
|
@@ -29,11 +29,11 @@ type handlerEntry = {
|
|
|
29
29
|
/** Whether `dcbQueueUrl` is a FIFO queue. Absent in a config written before
|
|
30
30
|
the flavor travelled with the URL, where `false` — a standard queue — is
|
|
31
31
|
what these command topics actually are. */
|
|
32
|
-
commandQueueIsFifo
|
|
32
|
+
commandQueueIsFifo?: bool,
|
|
33
33
|
sourceUrn: string,
|
|
34
|
-
context
|
|
34
|
+
context?: Reventless.AutomationSlice.context,
|
|
35
35
|
/** The slice's schedules store; absent for a slice that maps no `Clock`. */
|
|
36
|
-
schedulesTableName
|
|
36
|
+
schedulesTableName?: string,
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
let strOf = (obj: dict<JSON.t>, key: string): option<string> =>
|
|
@@ -58,10 +58,10 @@ let decodeEntry = (json: JSON.t): option<handlerEntry> =>
|
|
|
58
58
|
callbackType: h->strOf("callbackType")->Option.getOr("automation"),
|
|
59
59
|
queryDbTableName: h->strOf("queryDbTableName")->Option.getOr(""),
|
|
60
60
|
dcbQueueUrl: h->strOf("dcbQueueUrl")->Option.getOr(""),
|
|
61
|
-
commandQueueIsFifo: h->Dict.get("commandQueueIsFifo")->Option.flatMap(JSON.Decode.bool),
|
|
61
|
+
commandQueueIsFifo: ?(h->Dict.get("commandQueueIsFifo")->Option.flatMap(JSON.Decode.bool)),
|
|
62
62
|
sourceUrn: h->strOf("sourceUrn")->Option.getOr(""),
|
|
63
|
-
context: h->Dict.get("context")->Option.flatMap(decodeContext),
|
|
64
|
-
schedulesTableName: h->strOf("schedulesTableName"),
|
|
63
|
+
context: ?(h->Dict.get("context")->Option.flatMap(decodeContext)),
|
|
64
|
+
schedulesTableName: ?(h->strOf("schedulesTableName")),
|
|
65
65
|
})
|
|
66
66
|
|
|
67
67
|
// A compact entry names its slice and carries only what the deploy resolved;
|
|
@@ -91,15 +91,15 @@ let decodeCompactEntry = (
|
|
|
91
91
|
callbackType: m->strOf("callbackType")->Option.getOr("automation"),
|
|
92
92
|
queryDbTableName: h->strOf("q")->Option.getOr(""),
|
|
93
93
|
dcbQueueUrl: h->strOf("k")->Option.getOr(sharedQueueUrl),
|
|
94
|
-
commandQueueIsFifo: switch h->Dict.get("f")->Option.flatMap(JSON.Decode.bool) {
|
|
94
|
+
commandQueueIsFifo: ?switch h->Dict.get("f")->Option.flatMap(JSON.Decode.bool) {
|
|
95
95
|
| Some(f) => Some(f)
|
|
96
96
|
| None => sharedIsFifo
|
|
97
97
|
},
|
|
98
98
|
// Only the first, which is all the shell registers today. The remaining
|
|
99
99
|
// urns stay in the config for the multi-source registration to use.
|
|
100
100
|
sourceUrn: urns->Array.get(0)->Option.getOr(""),
|
|
101
|
-
context: m->Dict.get("context")->Option.flatMap(decodeContext),
|
|
102
|
-
schedulesTableName: h->strOf("s"),
|
|
101
|
+
context: ?(m->Dict.get("context")->Option.flatMap(decodeContext)),
|
|
102
|
+
schedulesTableName: ?(h->strOf("s")),
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -428,6 +428,9 @@ let capabilities = (): Reventless.Capabilities.t => {
|
|
|
428
428
|
~identityStore=NodeProcess.env->Dict.get("IDENTITY_STORE_TABLE")->Option.getOr(""),
|
|
429
429
|
),
|
|
430
430
|
secrets: ReventlessCore.Secrets_Node_Backend.provider,
|
|
431
|
+
// None deployed yet: a slice declaring the need is refused by the deploy gate,
|
|
432
|
+
// and this answers `Unavailable` should one run regardless.
|
|
433
|
+
stash: Reventless.Capabilities.none.stash,
|
|
431
434
|
}
|
|
432
435
|
|
|
433
436
|
// ── Phase-1/phase-2 pipelines ───────────────────────────────────────────────
|
|
@@ -576,7 +579,7 @@ type builtSlice = {
|
|
|
576
579
|
tick: option<(~key: string, ~at: float) => promise<unit>>,
|
|
577
580
|
/** Brings the slice's schedules in line with its spec and its rows, at a deploy;
|
|
578
581
|
`None` for an outbound slice. */
|
|
579
|
-
reconcile
|
|
582
|
+
reconcile?: unit => promise<unit>,
|
|
580
583
|
}
|
|
581
584
|
|
|
582
585
|
let makeAutomationRegisteredHandler = (
|
|
@@ -651,27 +654,25 @@ let makeAutomationRegisteredHandler = (
|
|
|
651
654
|
await syncTodoItems()
|
|
652
655
|
},
|
|
653
656
|
),
|
|
654
|
-
reconcile:
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
},
|
|
674
|
-
),
|
|
657
|
+
reconcile: async () =>
|
|
658
|
+
switch schedules() {
|
|
659
|
+
| Some({load, sync, platform}) =>
|
|
660
|
+
await load()
|
|
661
|
+
await ReventlessCore.AutomationSlice_Schedules.reconcile(
|
|
662
|
+
callback.schedules,
|
|
663
|
+
platform,
|
|
664
|
+
~declaredTime=schedule,
|
|
665
|
+
~now=Date.now(),
|
|
666
|
+
)
|
|
667
|
+
await sync()
|
|
668
|
+
// No Clock mapping, so no schedule of the slice may stay on the platform.
|
|
669
|
+
| None =>
|
|
670
|
+
let platform = platformSchedulesOf(~slice=sliceName)
|
|
671
|
+
let names = await platform.names()
|
|
672
|
+
for i in 0 to names->Array.length - 1 {
|
|
673
|
+
await platform.removeName(names->Array.getUnsafe(i))
|
|
674
|
+
}
|
|
675
|
+
},
|
|
675
676
|
}
|
|
676
677
|
}
|
|
677
678
|
|
|
@@ -718,7 +719,6 @@ let makeOutboundRegisteredHandler = (
|
|
|
718
719
|
comp,
|
|
719
720
|
name: sliceName,
|
|
720
721
|
tick: None,
|
|
721
|
-
reconcile: None,
|
|
722
722
|
}
|
|
723
723
|
}
|
|
724
724
|
|
|
@@ -13,6 +13,7 @@ import * as DcbDecode$Reventless from "@reventlessdev/reventless-spec/src/compon
|
|
|
13
13
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
14
14
|
import * as Util_Sury$Reventless from "@reventlessdev/reventless-spec/src/util/Util_Sury.res.mjs";
|
|
15
15
|
import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
|
|
16
|
+
import * as Capabilities$Reventless from "@reventlessdev/reventless-spec/src/semantic/Capabilities.res.mjs";
|
|
16
17
|
import * as EffectLogger$ReventlessCore from "@reventlessdev/reventless-core/src/util/EffectLogger.res.mjs";
|
|
17
18
|
import * as DynamoDb_Error$ReventlessAws from "../../errors/DynamoDb_Error.res.mjs";
|
|
18
19
|
import * as Messaging_Ses_Backend$ReventlessAws from "../Messaging/Messaging_Ses_Backend.res.mjs";
|
|
@@ -276,7 +277,8 @@ function capabilities() {
|
|
|
276
277
|
geocode: text => Geocoder_AwsLocation_Backend$ReventlessAws.search(Stdlib_Option.getOr(process.env["PLACE_INDEX_NAME"], ""), text, undefined),
|
|
277
278
|
messaging: messagingEmailProvider(),
|
|
278
279
|
identityProvider: IdentityProvider_Cognito_Backend$ReventlessAws.provider(Stdlib_Option.getOr(process.env["IDENTITY_PROVIDER_ID"], ""), Stdlib_Option.getOr(process.env["IDENTITY_STORE_TABLE"], "")),
|
|
279
|
-
secrets: Secrets_Node_Backend$ReventlessCore.provider
|
|
280
|
+
secrets: Secrets_Node_Backend$ReventlessCore.provider,
|
|
281
|
+
stash: Capabilities$Reventless.none.stash
|
|
280
282
|
};
|
|
281
283
|
}
|
|
282
284
|
|
|
@@ -422,8 +424,7 @@ function makeOutboundRegisteredHandler(entry, sliceName, consumedEventSchema, ca
|
|
|
422
424
|
},
|
|
423
425
|
comp: comp,
|
|
424
426
|
name: sliceName,
|
|
425
|
-
tick: undefined
|
|
426
|
-
reconcile: undefined
|
|
427
|
+
tick: undefined
|
|
427
428
|
};
|
|
428
429
|
}
|
|
429
430
|
|
|
@@ -23,7 +23,7 @@ type sliceInfo = {
|
|
|
23
23
|
queryDbResources: array<ReventlessInfra.Adapter.resource>,
|
|
24
24
|
// Threaded to phase 1 collect/resolve on the automation path (mirrors the
|
|
25
25
|
// in-process builder's `~context`); outbound slices take no context.
|
|
26
|
-
context
|
|
26
|
+
context?: Reventless.AutomationSlice.context,
|
|
27
27
|
// The non-DCB topics this slice subscribes to — an Aggregate's EventTopic when
|
|
28
28
|
// it names one by `Spec.name`. Empty for the common DCB-only slice.
|
|
29
29
|
//
|
|
@@ -47,10 +47,10 @@ type sliceInfo = {
|
|
|
47
47
|
// Resolved in the finalizer rather than here: an Aggregate's CommandTopic is
|
|
48
48
|
// created *after* the slices that target it, so a lookup at registration time
|
|
49
49
|
// finds nothing. Only the name is knowable this early.
|
|
50
|
-
commandTargetName
|
|
50
|
+
commandTargetName?: string,
|
|
51
51
|
// The automation's declared time; what the deploy's reconcile puts on the
|
|
52
52
|
// platform, and what re-runs it when it changes.
|
|
53
|
-
schedule
|
|
53
|
+
schedule?: Reventless.Schedule.time,
|
|
54
54
|
// The schedules store's table, empty for a slice that maps no `Clock`. Granted to
|
|
55
55
|
// the Lambda with the to-do tables, and named in the slice's handler config.
|
|
56
56
|
schedulesResources: array<ReventlessInfra.Adapter.resource>,
|
|
@@ -116,11 +116,11 @@ let registerAutomationSlice = (
|
|
|
116
116
|
callbackType,
|
|
117
117
|
queryDbTableName,
|
|
118
118
|
queryDbResources,
|
|
119
|
-
context,
|
|
119
|
+
?context,
|
|
120
120
|
sourceTopics,
|
|
121
121
|
consumesDcbLog,
|
|
122
|
-
commandTargetName,
|
|
123
|
-
schedule,
|
|
122
|
+
?commandTargetName,
|
|
123
|
+
?schedule,
|
|
124
124
|
schedulesResources,
|
|
125
125
|
capabilityNeeds,
|
|
126
126
|
},
|
|
@@ -45,7 +45,7 @@ type derivedScope = {
|
|
|
45
45
|
crossPartitionTagKeys: array<string>,
|
|
46
46
|
tagKeysByEventType: dict<array<string>>,
|
|
47
47
|
/** `None` only for a Lambda hosting no StateChangeSlices, which never appends. */
|
|
48
|
-
partitionTag
|
|
48
|
+
partitionTag?: Reventless.DcbTag.derivedPartitionTag,
|
|
49
49
|
/** Slice name -> its partition: the handler's entity id and each command's envelope id. */
|
|
50
50
|
partitionTagBySlice: dict<Reventless.DcbTag.derivedPartitionTag>,
|
|
51
51
|
}
|
|
@@ -55,7 +55,6 @@ let deriveScope = (specs: array<specModule>): derivedScope =>
|
|
|
55
55
|
| [] => {
|
|
56
56
|
crossPartitionTagKeys: [],
|
|
57
57
|
tagKeysByEventType: Dict.make(),
|
|
58
|
-
partitionTag: None,
|
|
59
58
|
partitionTagBySlice: Dict.make(),
|
|
60
59
|
}
|
|
61
60
|
| _ =>
|
|
@@ -89,7 +88,7 @@ let deriveScope = (specs: array<specModule>): derivedScope =>
|
|
|
89
88
|
{
|
|
90
89
|
crossPartitionTagKeys: scope.crossPartitionTagKeys,
|
|
91
90
|
tagKeysByEventType: scope.tagKeysByEventType,
|
|
92
|
-
partitionTag:
|
|
91
|
+
partitionTag: boundary.partitionTag,
|
|
93
92
|
partitionTagBySlice,
|
|
94
93
|
}
|
|
95
94
|
}
|
|
@@ -257,6 +256,7 @@ type inboundCallback = {
|
|
|
257
256
|
receive: (
|
|
258
257
|
ReventlessInfra.CommandTopic.publishJsons,
|
|
259
258
|
JSON.t,
|
|
259
|
+
~capabilities: Reventless.Capabilities.t,
|
|
260
260
|
~caller: Reventless.Identity.t=?,
|
|
261
261
|
~door: ReventlessInfra.InboundTranslationSlice.door=?,
|
|
262
262
|
) => promise<ReventlessInfra.InboundTranslationSlice.receiveResult>,
|
|
@@ -265,7 +265,7 @@ type inboundCallback = {
|
|
|
265
265
|
~errorCode: string,
|
|
266
266
|
string,
|
|
267
267
|
) => ReventlessInfra.InboundTranslationSlice.receiveResult,
|
|
268
|
-
webhook
|
|
268
|
+
webhook?: ReventlessCore.InboundTranslationSlice_Webhook.route,
|
|
269
269
|
auditLog: dict<ReventlessCore.InboundTranslationSlice_Callback.auditRow>,
|
|
270
270
|
}
|
|
271
271
|
@module(
|
|
@@ -324,9 +324,12 @@ let buildInboundReceiver = (
|
|
|
324
324
|
) => {
|
|
325
325
|
let callback = makeInboundCallback(spec)(translation)
|
|
326
326
|
async (args: JSON.t, identity: Nullable.t<Reventless.Identity.t>): JSON.t => {
|
|
327
|
+
// No capabilities in this Lambda: a slice declaring a need is refused at
|
|
328
|
+
// deploy, so `none` is what every slice reaching here expects.
|
|
327
329
|
let result = await callback.receive(
|
|
328
330
|
publishJsons,
|
|
329
331
|
args,
|
|
332
|
+
~capabilities=Reventless.Capabilities.none,
|
|
330
333
|
~caller=ReventlessCore.InboundTranslationSlice_Callback.doorCaller(identity),
|
|
331
334
|
)
|
|
332
335
|
await persistAudit(callback, auditQueryDbOps, result)
|
|
@@ -354,7 +357,15 @@ let buildWebhookSlice = (
|
|
|
354
357
|
->Option.map((route): ReventlessCore.InboundTranslationSlice_Webhook.slice => {
|
|
355
358
|
route,
|
|
356
359
|
receive: async (input, ~caller) =>
|
|
357
|
-
await persisted(
|
|
360
|
+
await persisted(
|
|
361
|
+
await callback.receive(
|
|
362
|
+
publishJsons,
|
|
363
|
+
input,
|
|
364
|
+
~capabilities=Reventless.Capabilities.none,
|
|
365
|
+
~caller,
|
|
366
|
+
~door=Webhook,
|
|
367
|
+
),
|
|
368
|
+
),
|
|
358
369
|
refuse: async (~body, ~errorCode, error) =>
|
|
359
370
|
await persisted(callback.refuse(~body, ~errorCode, error)),
|
|
360
371
|
})
|
|
@@ -12,6 +12,7 @@ import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_excep
|
|
|
12
12
|
import * as Util_Sury$Reventless from "@reventlessdev/reventless-spec/src/util/Util_Sury.res.mjs";
|
|
13
13
|
import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
|
|
14
14
|
import * as QueryDb$ReventlessCore from "@reventlessdev/reventless-core/src/components/QueryDb/QueryDb.res.mjs";
|
|
15
|
+
import * as Capabilities$Reventless from "@reventlessdev/reventless-spec/src/semantic/Capabilities.res.mjs";
|
|
15
16
|
import * as EffectLogger$ReventlessCore from "@reventlessdev/reventless-core/src/util/EffectLogger.res.mjs";
|
|
16
17
|
import * as CommandTopic_Helpers$ReventlessCore from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic_Helpers.res.mjs";
|
|
17
18
|
import * as InboundTranslationSlice_Webhook$ReventlessCore from "@reventlessdev/reventless-core/src/components/InboundTranslationSlice/InboundTranslationSlice_Webhook.res.mjs";
|
|
@@ -26,7 +27,6 @@ function deriveScope(specs) {
|
|
|
26
27
|
return {
|
|
27
28
|
crossPartitionTagKeys: [],
|
|
28
29
|
tagKeysByEventType: {},
|
|
29
|
-
partitionTag: undefined,
|
|
30
30
|
partitionTagBySlice: {}
|
|
31
31
|
};
|
|
32
32
|
}
|
|
@@ -147,7 +147,7 @@ async function persistAudit(callback, auditQueryDbOps, result) {
|
|
|
147
147
|
function buildInboundReceiver(spec, translation, publishJsons, auditQueryDbOps) {
|
|
148
148
|
let callback = InboundTranslationSlice_CallbackResMjs.Make(spec)(translation);
|
|
149
149
|
return async (args, identity) => {
|
|
150
|
-
let result = await callback.receive(publishJsons, args, InboundTranslationSlice_Callback$ReventlessCore.doorCaller(identity), undefined);
|
|
150
|
+
let result = await callback.receive(publishJsons, args, Capabilities$Reventless.none, InboundTranslationSlice_Callback$ReventlessCore.doorCaller(identity), undefined);
|
|
151
151
|
await persistAudit(callback, auditQueryDbOps, result);
|
|
152
152
|
return CommandTopic_Helpers$ReventlessCore.commandOutcomeToJson(InboundTranslationSlice_Callback$ReventlessCore.receiveResultToOutcome(result));
|
|
153
153
|
};
|
|
@@ -161,7 +161,7 @@ function buildWebhookSlice(spec, translation, publishJsons, auditQueryDbOps) {
|
|
|
161
161
|
};
|
|
162
162
|
return Stdlib_Nullable.fromOption(Stdlib_Option.map(callback.webhook, route => ({
|
|
163
163
|
route: route,
|
|
164
|
-
receive: async (input, caller) => await persisted(await callback.receive(publishJsons, input, caller, "Webhook")),
|
|
164
|
+
receive: async (input, caller) => await persisted(await callback.receive(publishJsons, input, Capabilities$Reventless.none, caller, "Webhook")),
|
|
165
165
|
refuse: async (body, errorCode, error) => await persisted(callback.refuse(body, errorCode, error))
|
|
166
166
|
})));
|
|
167
167
|
}
|
|
@@ -106,7 +106,7 @@ type handlerConfig = {
|
|
|
106
106
|
schedulerQueueArn: string,
|
|
107
107
|
schedulerQueueName: string,
|
|
108
108
|
extensionPoints: array<extensionPointConfig>,
|
|
109
|
-
connectExtension
|
|
109
|
+
connectExtension?: connectExtensionConfig,
|
|
110
110
|
extensions: array<extensionConfig>,
|
|
111
111
|
readModelNamesForSourceName: dict<array<string>>,
|
|
112
112
|
}
|
|
@@ -234,7 +234,7 @@ let parseHandlerConfig = (rawJson: string): handlerConfig => {
|
|
|
234
234
|
schedulerQueueArn: obj->strOf("schedulerQueueArn")->Option.getOr(""),
|
|
235
235
|
schedulerQueueName: obj->strOf("schedulerQueueName")->Option.getOr(""),
|
|
236
236
|
extensionPoints,
|
|
237
|
-
connectExtension,
|
|
237
|
+
?connectExtension,
|
|
238
238
|
extensions,
|
|
239
239
|
readModelNamesForSourceName,
|
|
240
240
|
}
|
|
@@ -253,7 +253,7 @@ type pluginProjection = {
|
|
|
253
253
|
eventCollector: string,
|
|
254
254
|
extensions: array<Reventless.Plugin.extensionDefinition>,
|
|
255
255
|
extensionPoints: array<Reventless.Plugin.extensionPointDefinition>,
|
|
256
|
-
dcbEventLog
|
|
256
|
+
dcbEventLog?: Reventless.Plugin.dcbEventLogDefinition,
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
let projectPluginRow = (row: JSON.t): option<pluginProjection> =>
|
|
@@ -323,7 +323,7 @@ let projectPluginRow = (row: JSON.t): option<pluginProjection> =>
|
|
|
323
323
|
eventCollector: obj->strOf("eventCollector")->Option.getOr(""),
|
|
324
324
|
extensions,
|
|
325
325
|
extensionPoints,
|
|
326
|
-
dcbEventLog,
|
|
326
|
+
?dcbEventLog,
|
|
327
327
|
})
|
|
328
328
|
| _ => None
|
|
329
329
|
}
|
|
@@ -339,7 +339,7 @@ let projectionOfDefinition = (d: Reventless.Plugin.pluginDefinition): pluginProj
|
|
|
339
339
|
eventCollector: d.eventCollector,
|
|
340
340
|
extensions: d.extensions,
|
|
341
341
|
extensionPoints: d.extensionPoints,
|
|
342
|
-
dcbEventLog: d.dcbEventLog->jsOption,
|
|
342
|
+
dcbEventLog: ?(d.dcbEventLog->jsOption),
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
// ── Cross-plugin SNS subscription manager ───────────────────────────────────
|
|
@@ -26,7 +26,7 @@ type handlerEntry = {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
type resolverConfig = {
|
|
29
|
-
pgConnection
|
|
29
|
+
pgConnection?: PgConnection.connectionConfig,
|
|
30
30
|
handlers: array<handlerEntry>,
|
|
31
31
|
nodeTypes: dict<string>,
|
|
32
32
|
}
|
|
@@ -59,10 +59,12 @@ let parseResolverConfig = (rawJson: string): resolverConfig => {
|
|
|
59
59
|
->JSON.Decode.object
|
|
60
60
|
->Option.getOr(Dict.make())
|
|
61
61
|
{
|
|
62
|
-
pgConnection:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
pgConnection: ?(
|
|
63
|
+
obj
|
|
64
|
+
->Dict.get("pgConnection")
|
|
65
|
+
->Option.filter(j => j != JSON.Null)
|
|
66
|
+
->Option.map(asPgConnection)
|
|
67
|
+
),
|
|
66
68
|
handlers: obj
|
|
67
69
|
->Dict.get("handlers")
|
|
68
70
|
->Option.flatMap(JSON.Decode.array)
|
|
@@ -118,8 +120,8 @@ let makePushdowns = (
|
|
|
118
120
|
// Reventless.Authorization.isAllowed matches on.
|
|
119
121
|
|
|
120
122
|
type specInfo = {
|
|
121
|
-
config
|
|
122
|
-
subIdConfig
|
|
123
|
+
config?: ProjectionEntryPoint_Ops.specConfig,
|
|
124
|
+
subIdConfig?: Reventless.ReadModel.subIdConfig<JSON.t>,
|
|
123
125
|
stateSchema: S.t<unknown>,
|
|
124
126
|
authorization: Reventless.Authorization.permission,
|
|
125
127
|
}
|
|
@@ -143,7 +145,7 @@ let registerBinding = (
|
|
|
143
145
|
),
|
|
144
146
|
pushdowns,
|
|
145
147
|
indexes,
|
|
146
|
-
subIdField,
|
|
148
|
+
?subIdField,
|
|
147
149
|
capability: ReventlessCore.GraphQL_FragmentGenerator.deriveServerCapability(
|
|
148
150
|
~entityName=entry.readModelName,
|
|
149
151
|
spec.stateSchema,
|
|
@@ -153,24 +155,28 @@ let registerBinding = (
|
|
|
153
155
|
authorization: spec.authorization->Reventless.Authorization.named,
|
|
154
156
|
// From the same schema `capability` is derived from, one line above, so the
|
|
155
157
|
// two cannot end up disagreeing about this read model's fields.
|
|
156
|
-
ownerField: Reventless.Owner.fieldNames(spec.stateSchema)->Array.get(0),
|
|
157
|
-
retiredField:
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
ownerField: ?(Reventless.Owner.fieldNames(spec.stateSchema)->Array.get(0)),
|
|
159
|
+
retiredField: ?(
|
|
160
|
+
spec.stateSchema
|
|
161
|
+
->Reventless.StateAnnotations.getSpec
|
|
162
|
+
->Option.flatMap(a => a.retired)
|
|
163
|
+
->Option.map(r => r.field)
|
|
164
|
+
),
|
|
161
165
|
// The state form's other half. Carried beside the field rather than
|
|
162
166
|
// re-derived at predicate time, so one place decides which rows are retired.
|
|
163
|
-
retiredValues:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
+
retiredValues: ?(
|
|
168
|
+
spec.stateSchema
|
|
169
|
+
->Reventless.StateAnnotations.getSpec
|
|
170
|
+
->Option.flatMap(a => a.retired)
|
|
171
|
+
->Option.flatMap(r => r.values)
|
|
172
|
+
),
|
|
167
173
|
// Read off the retirement rather than from a second annotation: a record
|
|
168
174
|
// cannot declare the reach of a retirement it does not have.
|
|
169
175
|
namedWhenRetired: spec.stateSchema
|
|
170
176
|
->Reventless.StateAnnotations.getSpec
|
|
171
177
|
->Option.flatMap(a => a.retired)
|
|
172
178
|
->Option.mapOr(false, r => r.namedWhenRetired),
|
|
173
|
-
imageSource: spec.stateSchema->Reventless.RowImage.sourceFrom,
|
|
179
|
+
imageSource: ?(spec.stateSchema->Reventless.RowImage.sourceFrom),
|
|
174
180
|
},
|
|
175
181
|
)
|
|
176
182
|
logDebug("registered resolver binding for " ++ entry.readModelName, {comp: "PgQueryResolver"})
|
|
@@ -22,10 +22,10 @@ type handlerEntry = {
|
|
|
22
22
|
// ReScript dispatch boundary's `EventCollector(<Name>)` byte for byte. This
|
|
23
23
|
// Lambda hosts every read model, so the comp is what separates their log
|
|
24
24
|
// lines; the plugin beats the Lambda-name-derived fallback in runEffect.
|
|
25
|
-
comp
|
|
26
|
-
plugin
|
|
27
|
-
pgConnection
|
|
28
|
-
stateTopicName
|
|
25
|
+
comp?: string,
|
|
26
|
+
plugin?: string,
|
|
27
|
+
pgConnection?: PgConnection.connectionConfig,
|
|
28
|
+
stateTopicName?: string,
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// The builder writes `pgConnection` via PgConnection.connectionConfigToJson, so
|
|
@@ -44,13 +44,15 @@ let decodeEntry = (json: JSON.t): option<handlerEntry> =>
|
|
|
44
44
|
mappingsModule: h->strOf("mappingsModule")->Option.getOr(""),
|
|
45
45
|
queryDbTableName: h->strOf("queryDbTableName")->Option.getOr(""),
|
|
46
46
|
sourceUrn: h->strOf("sourceUrn")->Option.getOr(""),
|
|
47
|
-
comp: h->strOf("comp"),
|
|
48
|
-
plugin: h->strOf("plugin"),
|
|
49
|
-
pgConnection:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
comp: ?(h->strOf("comp")),
|
|
48
|
+
plugin: ?(h->strOf("plugin")),
|
|
49
|
+
pgConnection: ?(
|
|
50
|
+
h
|
|
51
|
+
->Dict.get("pgConnection")
|
|
52
|
+
->Option.filter(j => j != JSON.Null)
|
|
53
|
+
->Option.map(asPgConnection)
|
|
54
|
+
),
|
|
55
|
+
stateTopicName: ?(h->strOf("stateTopicName")),
|
|
54
56
|
})
|
|
55
57
|
|
|
56
58
|
let parseHandlerConfig = (rawJson: string): array<handlerEntry> =>
|
|
@@ -88,10 +90,10 @@ let withInjectedId = (
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
type specInfo = {
|
|
91
|
-
config
|
|
92
|
-
subIdConfig
|
|
93
|
+
config?: ProjectionEntryPoint_Ops.specConfig,
|
|
94
|
+
subIdConfig?: Reventless.ReadModel.subIdConfig<JSON.t>,
|
|
93
95
|
// Read off the runtime-loaded spec module; `None` on a module that predates it.
|
|
94
|
-
stateSchema
|
|
96
|
+
stateSchema?: S.t<unknown>,
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
let buildOperations = (
|
|
@@ -269,8 +269,8 @@ let makeFromCodeAsset: (
|
|
|
269
269
|
// registered — an extension-free deployment gets the env it always had.
|
|
270
270
|
if !ReventlessCore.RuntimeExtension.isEmpty() {
|
|
271
271
|
let {
|
|
272
|
-
ReventlessCore.ResourceAttribution.plugin: plugin,
|
|
273
|
-
platform,
|
|
272
|
+
ReventlessCore.ResourceAttribution.plugin: ?plugin,
|
|
273
|
+
?platform,
|
|
274
274
|
} = ReventlessCore.ResourceAttribution.current.contents
|
|
275
275
|
let orNull = o => o->Option.mapOr(JSON.Null, s => JSON.String(s))
|
|
276
276
|
let config = JSON.Object(
|
|
@@ -29,8 +29,8 @@ type config = {
|
|
|
29
29
|
modules: array<string>,
|
|
30
30
|
runtimeKind: string,
|
|
31
31
|
component: string,
|
|
32
|
-
plugin
|
|
33
|
-
platform
|
|
32
|
+
plugin?: string,
|
|
33
|
+
platform?: string,
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
let decodeString = (obj: dict<JSON.t>, key: string): option<string> =>
|
|
@@ -70,8 +70,8 @@ let parseConfig = (raw: option<string>): option<config> =>
|
|
|
70
70
|
modules,
|
|
71
71
|
runtimeKind,
|
|
72
72
|
component,
|
|
73
|
-
plugin: obj->decodeString("plugin"),
|
|
74
|
-
platform: obj->decodeString("platform"),
|
|
73
|
+
plugin: ?(obj->decodeString("plugin")),
|
|
74
|
+
platform: ?(obj->decodeString("platform")),
|
|
75
75
|
})
|
|
76
76
|
| _ =>
|
|
77
77
|
log.error(
|
|
@@ -14,8 +14,8 @@ type handlerEntry = {
|
|
|
14
14
|
// Resolved at deploy time and baked into HANDLER_CONFIG
|
|
15
15
|
// (SideEffectHandlerRuntime_Builder_Single) — the shell has only module paths
|
|
16
16
|
// to identify a handler by.
|
|
17
|
-
comp
|
|
18
|
-
plugin
|
|
17
|
+
comp?: string,
|
|
18
|
+
plugin?: string,
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
let strOf = (obj: dict<JSON.t>, key: string): option<string> =>
|
|
@@ -31,8 +31,8 @@ let decodeEntry = (json: JSON.t): option<handlerEntry> =>
|
|
|
31
31
|
->Option.flatMap(JSON.Decode.array)
|
|
32
32
|
->Option.getOr([])
|
|
33
33
|
->Array.filterMap(JSON.Decode.string),
|
|
34
|
-
comp: h->strOf("comp"),
|
|
35
|
-
plugin: h->strOf("plugin"),
|
|
34
|
+
comp: ?(h->strOf("comp")),
|
|
35
|
+
plugin: ?(h->strOf("plugin")),
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
let parseHandlerConfig = (rawJson: string): array<handlerEntry> =>
|
|
@@ -17,8 +17,8 @@ type handlerEntry = {
|
|
|
17
17
|
sourceUrn: string,
|
|
18
18
|
// B3.3: per-slice AppSync Events channel root (list field name). Present only
|
|
19
19
|
// for subscription-enabled (Stream) Postgres view slices.
|
|
20
|
-
stateTopicName
|
|
21
|
-
pgConnection
|
|
20
|
+
stateTopicName?: string,
|
|
21
|
+
pgConnection?: PgConnection.connectionConfig,
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// The builder writes `pgConnection` via PgConnection.connectionConfigToJson, so
|
|
@@ -67,16 +67,16 @@ let parseHandlerConfig = (rawJson: string): array<handlerEntry> =>
|
|
|
67
67
|
projectionModule: h->strOf("projectionModule")->Option.getOr(""),
|
|
68
68
|
queryDbTableName: h->strOf("queryDbTableName")->Option.getOr(""),
|
|
69
69
|
sourceUrn: h->strOf("sourceUrn")->Option.getOr(""),
|
|
70
|
-
stateTopicName: h->strOf("stateTopicName"),
|
|
71
|
-
pgConnection: h->pgConnectionOf,
|
|
70
|
+
stateTopicName: ?(h->strOf("stateTopicName")),
|
|
71
|
+
pgConnection: ?(h->pgConnectionOf),
|
|
72
72
|
}
|
|
73
73
|
| None => {
|
|
74
74
|
specModule: base ++ h->strOf("s")->Option.getOr(""),
|
|
75
75
|
projectionModule: base ++ h->strOf("p")->Option.getOr(""),
|
|
76
76
|
queryDbTableName: h->strOf("q")->Option.getOr(""),
|
|
77
77
|
sourceUrn: h->strOf("u")->Option.getOr(sharedUrn),
|
|
78
|
-
stateTopicName: h->strOf("t"),
|
|
79
|
-
pgConnection: sharedPgConnection,
|
|
78
|
+
stateTopicName: ?(h->strOf("t")),
|
|
79
|
+
pgConnection: ?sharedPgConnection,
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
)
|
|
@@ -197,10 +197,10 @@ type sliceModules<'event> = {
|
|
|
197
197
|
project: Reventless.StateViewSlice.consumed<'event> => array<
|
|
198
198
|
Reventless.Projection.action<string, JSON.t>,
|
|
199
199
|
>,
|
|
200
|
-
config
|
|
201
|
-
subIdConfig
|
|
200
|
+
config?: ProjectionEntryPoint_Ops.specConfig,
|
|
201
|
+
subIdConfig?: Reventless.ReadModel.subIdConfig<JSON.t>,
|
|
202
202
|
// Same union stamp the read-model path needs; a slice's state can hold one too.
|
|
203
|
-
stateSchema
|
|
203
|
+
stateSchema?: S.t<unknown>,
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
let makeRegisteredHandler = (
|
|
@@ -24,7 +24,7 @@ type handlerConfig = {
|
|
|
24
24
|
callbackModule: string,
|
|
25
25
|
// aggregateName → env-var name holding the aggregate's cmd-topic SQS URL.
|
|
26
26
|
publishToAggregates: dict<string>,
|
|
27
|
-
scheduler
|
|
27
|
+
scheduler?: schedulerEnvConfig,
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
let strOf = (obj: dict<JSON.t>, key: string): option<string> =>
|
|
@@ -45,14 +45,16 @@ let parseHandlerConfig = (rawJson: string): handlerConfig => {
|
|
|
45
45
|
->Dict.toArray
|
|
46
46
|
->Array.filterMap(((k, v)) => v->JSON.Decode.string->Option.map(s => (k, s)))
|
|
47
47
|
->Dict.fromArray,
|
|
48
|
-
scheduler:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
scheduler: ?(
|
|
49
|
+
obj
|
|
50
|
+
->Dict.get("scheduler")
|
|
51
|
+
->Option.flatMap(JSON.Decode.object)
|
|
52
|
+
->Option.map(s => {
|
|
53
|
+
roleArnEnv: s->strOf("roleArnEnv")->Option.getOr(""),
|
|
54
|
+
targetArnEnv: s->strOf("targetArnEnv")->Option.getOr(""),
|
|
55
|
+
targetNameEnv: s->strOf("targetNameEnv")->Option.getOr(""),
|
|
56
|
+
})
|
|
57
|
+
),
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -68,7 +68,7 @@ let startSchemaCreationRetrying = (client: appSyncClient, input: startSchemaCrea
|
|
|
68
68
|
// GetSchemaCreationStatus — poll until schema is ACTIVE
|
|
69
69
|
type getSchemaCreationStatusInput = {apiId: string}
|
|
70
70
|
type getSchemaCreationStatusCommand
|
|
71
|
-
type getSchemaCreationStatusResult = {status: string, details
|
|
71
|
+
type getSchemaCreationStatusResult = {status: string, details?: string}
|
|
72
72
|
|
|
73
73
|
@module("@aws-sdk/client-appsync") @new
|
|
74
74
|
external makeGetSchemaCreationStatusCommand: getSchemaCreationStatusInput => getSchemaCreationStatusCommand =
|
|
@@ -119,10 +119,10 @@ type getSourceApiAssociationInput = {
|
|
|
119
119
|
}
|
|
120
120
|
type getSourceApiAssociationCommand
|
|
121
121
|
type sourceApiAssociationSummary = {
|
|
122
|
-
sourceApiAssociationStatus
|
|
123
|
-
sourceApiAssociationStatusDetail
|
|
122
|
+
sourceApiAssociationStatus?: string,
|
|
123
|
+
sourceApiAssociationStatusDetail?: string,
|
|
124
124
|
}
|
|
125
|
-
type getSourceApiAssociationResult = {sourceApiAssociation
|
|
125
|
+
type getSourceApiAssociationResult = {sourceApiAssociation?: sourceApiAssociationSummary}
|
|
126
126
|
|
|
127
127
|
@module("@aws-sdk/client-appsync") @new
|
|
128
128
|
external makeGetSourceApiAssociationCommand: getSourceApiAssociationInput => getSourceApiAssociationCommand =
|