@reventlessdev/reventless-aws 3.0.0-alpha.344 → 3.0.0-alpha.345
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 +8 -0
- package/package.json +11 -11
- package/scripts/ProvisionIdentity.res +8 -3
- package/src/Platform.res +327 -328
- package/src/Platform.res.mjs +4 -2
- package/src/Platform_Casts.res +13 -4
- package/src/adapter/Api/AppSyncEventsSigner_Ops.res +8 -4
- package/src/adapter/Api/AppSync_EventsApi.res +12 -14
- package/src/adapter/Api/AppSync_Resolver_Native.res +3 -4
- package/src/adapter/Api/AppSync_Resolver_Retrying.res +78 -70
- package/src/adapter/Api/AppSync_SourceApiAssociation_Retrying.res +11 -8
- package/src/adapter/Api/Platform_AdminScan_Ops.res +15 -14
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +10 -2
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +40 -50
- package/src/adapter/Api/Platform_UIFragments_Lambda.res +39 -32
- package/src/adapter/Api/Platform_UIFragments_Lambda_Ops.res +5 -2
- package/src/adapter/Auth/Auth_ActiveRolePoolAttachment.res +0 -1
- package/src/adapter/Auth/Auth_ActiveRoleStore.res +1 -2
- package/src/adapter/Auth/Auth_ActiveRoleStore_Schema.res +1 -4
- package/src/adapter/Auth/Auth_ActiveRoleTrigger_Ops.res +5 -2
- package/src/adapter/Auth/Auth_Cognito.res +3 -9
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +1 -4
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res +3 -1
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res +1 -4
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +7 -4
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +6 -1
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +7 -4
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res +24 -18
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +9 -4
- package/src/adapter/CommandTopic/CommandTopicRegistry.res +1 -4
- package/src/adapter/Counter/CounterHandler_DynamoDbStream.res +15 -15
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res +9 -5
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +179 -213
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +5 -5
- package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res +6 -2
- package/src/adapter/EventCollector/EventCollectorChannel_SQS.res +14 -7
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res +14 -7
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res +6 -3
- package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res +6 -1
- package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res +13 -17
- package/src/adapter/EventLog/EventLogStorage_Postgres.res +7 -4
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +12 -7
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync_Ops.res +4 -2
- package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res +3 -2
- package/src/adapter/EventTopic/EventTopicPublisher_SNS.res +20 -12
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res +21 -9
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res +5 -3
- package/src/adapter/Geocoder/Geocoder_AwsLocation_Resolver.res +6 -3
- package/src/adapter/Mcp/MCP_Lambda.res +31 -46
- package/src/adapter/Messaging/Messaging_Ses_Backend.res +11 -7
- package/src/adapter/Messaging/Messaging_Ses_Backend.res.mjs +2 -4
- package/src/adapter/Monitoring/Monitoring_CloudWatch.res +16 -16
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res +5 -10
- package/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res +4 -2
- package/src/adapter/Postgres/PgConnection.res +6 -5
- package/src/adapter/Postgres/PgMigration_Builder.res +4 -8
- package/src/adapter/Postgres/PgRuntime.res +4 -7
- package/src/adapter/QueryDb/PgQueryResolver_Builder.res +9 -11
- package/src/adapter/QueryDb/PgQueryResolver_Lambda.res +22 -21
- package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res +114 -111
- package/src/adapter/QueryDb/QueryDbResolvers_Lambda.res +1 -7
- package/src/adapter/QueryDb/QueryDbStorage.res +4 -2
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res +23 -24
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res +8 -2
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res +71 -73
- package/src/adapter/QueryDb/QueryDbStorage_Postgres.res +5 -2
- package/src/adapter/QueryDb/QueryInterceptor_Provisioning.res +1 -4
- package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res +8 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +73 -81
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +72 -78
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +44 -67
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +44 -67
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +53 -82
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +47 -77
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +18 -11
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +80 -97
- package/src/adapter/Runtime/CounterEntryPoint_Ops.res +2 -7
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +16 -10
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +24 -15
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +17 -37
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +31 -57
- package/src/adapter/Runtime/EventMapperEntryPoint_Ops.res +18 -24
- package/src/adapter/Runtime/ExtensionPointEntryPoint_Ops.res +1 -5
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +4 -3
- package/src/adapter/Runtime/HeartbeatEntryPoint.res +0 -1
- package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.res +4 -2
- package/src/adapter/Runtime/PgMigrationEntryPoint.res +0 -1
- package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res +3 -2
- package/src/adapter/Runtime/PluginExtensionPointEntryPoint.res +1 -2
- package/src/adapter/Runtime/ProjectionEntryPoint_Ops.res +4 -5
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +22 -10
- package/src/adapter/Runtime/RuntimeExtensionEntryPoint_Ops.res +8 -2
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +14 -31
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +16 -17
- package/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res +10 -9
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +46 -52
- package/src/adapter/Runtime/StreamRoutedEntryPoint_Ops.res +36 -41
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +31 -37
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +6 -7
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +4 -6
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res +2 -6
- package/src/adapter/StateTopic/StateTopic_AppSync.res +21 -16
- package/src/adapter/StateTopic/StateTopic_AppSync_Ops.res +36 -32
- package/src/adapter/Task/TaskBucket_S3.res +6 -1
- package/src/adapter/Upload/Upload_Claim_S3.res +17 -20
- package/src/adapter/Upload/Upload_Claim_S3_Ops.res +5 -2
- package/src/adapter/Upload/Upload_Presign_S3.res +51 -49
- package/src/capability/Capability_Geocoding_AwsLocation.res +4 -1
- package/src/capability/Capability_Messaging.res +4 -5
- package/src/capability/Capability_Messaging_Ses.res +3 -1
- package/src/capability/Capability_ObjectStore_S3.res +1 -7
- package/src/components/Api/AppSync_Adapter.res +28 -41
- package/src/components/Api/AppSync_SdlDecorate.res +38 -30
- package/src/components/AutomationSlice_Builder.res +6 -4
- package/src/components/ExtensionPoint_Builder.res +9 -10
- package/src/components/InboundTranslationSlice_Builder.res +7 -8
- package/src/components/OutboundTranslationSlice_Builder.res +14 -8
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +1 -1
- package/src/components/SideEffectHandler_Single.res +4 -4
- package/src/components/StateViewSlice_Builder.res +6 -4
- package/src/components/StateViewSlice_Builder_Stream.res +6 -4
- package/src/components/Task_Builder_PerBucket.res +10 -11
- package/src/plugin/cloner/ClonerRunner_Fargate.res +3 -10
- package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res +1 -4
- package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res +5 -5
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +19 -21
- package/src/plugin/runtime/PluginRuntime_Builder.res +167 -188
- package/src/plugin/runtime/Util_PluginMessage_Runtime.res +6 -5
- package/src/plugin/stack/Plugin_Stack.res +104 -103
- package/src/util/Util_AlarmSpec.res +2 -1
- package/src/util/Util_AppSync.res +8 -2
- package/src/util/Util_AppSync_Caller.res +15 -14
- package/src/util/Util_Bundle.res +46 -42
- package/src/util/Util_CognitoGroupUser_Runtime.res +32 -34
- package/src/util/Util_Cognito_Runtime.res +11 -7
- package/src/util/Util_DeadLetterQueue.res +12 -2
- package/src/util/Util_DynamoDb.res +5 -3
- package/src/util/Util_DynamoDbStream.res +7 -3
- package/src/util/Util_DynamoDbStream_Runtime.res +1 -2
- package/src/util/Util_DynamoDb_Runtime.res +23 -41
- package/src/util/Util_HostUiDomain.res +6 -1
- package/src/util/Util_Kinesis_Runtime.res +10 -11
- package/src/util/Util_Lambda.res +12 -5
- package/src/util/Util_LambdaEnvBudget.res +5 -5
- package/src/util/Util_LambdaLogging.res +1 -2
- package/src/util/Util_LogGroup_Adopting.res +1 -4
- package/src/util/Util_ResourceNaming.res +1 -2
- package/src/util/Util_SNS.res +8 -3
- package/src/util/Util_SNS_FIFO.res +1 -1
- package/src/util/Util_SNS_Runtime.res +11 -10
- package/src/util/Util_SQS.res +4 -2
- package/src/util/Util_SQS_FIFO.res +5 -2
- package/src/util/Util_SQS_Runtime.res +37 -36
- package/src/util/Util_ShellConfig.res +3 -2
- package/src/util/Util_StaticBundle.res +1 -3
- package/src/util/Util_StoreLayout.res +4 -1
- package/tests/AWS_TagsTest.res +16 -5
- package/tests/AppSyncEventsSigner_OpsTest.res +11 -2
- package/tests/AppSync_AdapterTest.res +203 -224
- package/tests/AppSync_Resolver_RetryingTest.res +64 -44
- package/tests/AppSync_RetirementNarrowingTest.res +59 -46
- package/tests/AppSync_SdlDecorateTest.res +22 -20
- package/tests/AppSync_SourceApiAssociation_RetryingTest.res +40 -22
- package/tests/Auth_ActiveRolePoolAttachmentTest.res +114 -107
- package/tests/Auth_ActiveRoleStoreTest.res +12 -9
- package/tests/Auth_ActiveRoleStore_SchemaTest.res +2 -1
- package/tests/Auth_ActiveRoleTrigger_OpsTest.res +20 -16
- package/tests/Auth_CognitoTest.res +31 -46
- package/tests/AutomationSliceEntryPoint_OpsTest.res +69 -67
- package/tests/BakeConvergenceTest.res +22 -25
- package/tests/Capability_MessagingTest.res +28 -12
- package/tests/CommandTopicQueuePolicyTest.res +1 -2
- package/tests/CounterEntryPoint_OpsTest.res +3 -7
- package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res +306 -210
- package/tests/EventCollectorConnectLambdaPreviewTest.res +14 -7
- package/tests/EventCollectorEntryPoint_OpsTest.res +12 -4
- package/tests/EventCollectorPluginDefinitionAssetTest.res +18 -11
- package/tests/EventCollectorReadyGateTest.res +5 -4
- package/tests/EventLogStorage_DynamoDb_RuntimeTest.res +1 -2
- package/tests/EventMapperEntryPoint_OpsTest.res +1 -3
- package/tests/ExtensionPointEntryPoint_OpsTest.res +1 -4
- package/tests/HandlerFactoryDispatchTest.res +97 -70
- package/tests/MCP_LambdaTest.res +16 -27
- package/tests/PgChangeFeedRelay_IntegrationTest.res +123 -93
- package/tests/PgChangeFeedRelay_RuntimeTest.res +13 -10
- package/tests/PgMigrationEntryPoint_IntegrationTest.res +0 -1
- package/tests/PgPipeline_IntegrationTest.res +80 -66
- package/tests/PgQueryDbUnion_IntegrationTest.res +1 -2
- package/tests/PgQueryResolverEntryPoint_OpsTest.res +2 -6
- package/tests/PgQueryResolver_LambdaTest.res +41 -24
- package/tests/Platform_AdminScan_OpsTest.res +4 -1
- package/tests/Platform_ComponentDefinitions_Lambda_OpsTest.res +137 -129
- package/tests/ProjectionEntryPoint_DisplayNameTest.res +7 -3
- package/tests/ProjectionEntryPoint_UnionStampTest.res +3 -2
- package/tests/ProvisionIdentityTest.res +2 -6
- package/tests/QueryDbOwnerIndexTableTest.res +6 -4
- package/tests/QueryDbResolvers_AppSyncTest.res +23 -16
- package/tests/QueryInterceptor_LambdaTest.res +11 -13
- package/tests/ReadModelEntryPoint_OpsTest.res +43 -41
- package/tests/RuntimeExtensionEntryPoint_OpsTest.res +4 -3
- package/tests/SideEffectEntryPoint_OpsTest.res +23 -18
- package/tests/StateChangeDescriptorParityTest.res +28 -26
- package/tests/StateTopicKeySchemaTest.res +18 -15
- package/tests/StateViewSliceEntryPoint_OpsTest.res +55 -44
- package/tests/TaskBucketEntryPoint_OpsTest.res +13 -13
- package/tests/Upload_ClaimTest.res +3 -3
- package/tests/Util_AwsErrorTest.res +4 -7
- package/tests/Util_BundleDependencyClosureTest.res +15 -3
- package/tests/Util_BundleEsmLoaderTest.res +3 -3
- package/tests/Util_BundleResolveTest.res +4 -6
- package/tests/Util_BundleRuntimeExtensionTest.res +17 -18
- package/tests/Util_DcbMetricsTest.res +6 -6
- package/tests/Util_DynamoDbStreamTest.res +4 -5
- package/tests/Util_DynamoDbTest.res +3 -2
- package/tests/Util_LambdaEnvBudgetTest.res +22 -18
- package/tests/Util_LambdaLoggingTest.res +9 -8
- package/tests/Util_LogGroup_AdoptingTest.res +10 -5
- package/tests/Util_LogRetentionTest.res +6 -2
- package/tests/Util_OwnerScopeEnvTest.res +10 -8
- package/tests/Util_SQS_RuntimeTest.res +5 -7
- package/tests/Util_ShellConfigTest.res +7 -17
- package/tests/Util_StaticBundleTest.res +3 -8
- package/tests/Util_StoreLayoutTest.res +17 -12
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res +1 -4
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +15 -15
- package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +296 -232
- package/tests/integration/DcbIntegrationHarness.res +8 -8
- package/tests/integration/EpCompositeSlice.res +16 -8
- package/tests/integration/QueryDbUnion_DynamoDb_IntegrationTest.res +8 -10
- package/tests/integration/StateViewSliceEntryPoint_IntegrationTest.res +10 -10
- package/tests/integration/SvsTestSlice_Projection.res +1 -3
- package/tests/util/Util_AlarmSpecTest.res +62 -49
|
@@ -75,7 +75,9 @@ let subscribeQueue2SnsTopic = (
|
|
|
75
75
|
~topic=resource->ReventlessCore.AdapterDeploytime.resolvedToResource,
|
|
76
76
|
~opts,
|
|
77
77
|
)
|
|
78
|
-
subscription.id->Pulumi.Output.apply(id =>
|
|
78
|
+
subscription.id->Pulumi.Output.apply(id =>
|
|
79
|
+
log.debug(~comp="EventCollector", `created SNS subscription: ${id} ${name}`)
|
|
80
|
+
)
|
|
79
81
|
})
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -143,7 +145,9 @@ let connectLambda = (
|
|
|
143
145
|
->Pulumi.Output.flatMap(((eventTopicResources, queueArns, resources)) => {
|
|
144
146
|
log.debug(
|
|
145
147
|
~comp="EventCollector",
|
|
146
|
-
`connectLambda ${name}: ${eventTopicResources
|
|
148
|
+
`connectLambda ${name}: ${eventTopicResources
|
|
149
|
+
->Array.length
|
|
150
|
+
->Int.toString} topic resource(s), ${resources->Array.length->Int.toString} resource(s)`,
|
|
147
151
|
)
|
|
148
152
|
|
|
149
153
|
let dynamoDbStreamResources = eventTopicResources->dynamoDbStreamResources
|
|
@@ -30,14 +30,19 @@ let connect = (
|
|
|
30
30
|
lambda->connectLambda(name, lambdaRole, queues, eventTopics, resources, opts)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
let make: ReventlessCore.EventCollector_Adapter.channelMaker<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
) => {
|
|
33
|
+
let make: ReventlessCore.EventCollector_Adapter.channelMaker<
|
|
34
|
+
callbackEvent,
|
|
35
|
+
'context,
|
|
36
|
+
channelParts,
|
|
37
|
+
> = (~name, ~eventTopics, ~owner, ~opts) => {
|
|
38
38
|
let opts = opts->ReventlessCore.Util.Pulumi.ComponentResourceOptions.toCustomResourceOptions
|
|
39
39
|
|
|
40
|
-
let tags = AWS.Tags.make(
|
|
40
|
+
let tags = AWS.Tags.make(
|
|
41
|
+
~name,
|
|
42
|
+
~kind=ReventlessCore.EventCollector.componentType,
|
|
43
|
+
~role=EventCollector,
|
|
44
|
+
~owner?,
|
|
45
|
+
)
|
|
41
46
|
let queue = PulumiAws.SQS.Queue.make(
|
|
42
47
|
~name,
|
|
43
48
|
~args={
|
|
@@ -74,7 +79,9 @@ let make: ReventlessCore.EventCollector_Adapter.channelMaker<callbackEvent, 'con
|
|
|
74
79
|
|
|
75
80
|
{
|
|
76
81
|
ReventlessCore.EventCollector_Adapter.parts: {queue: queue},
|
|
77
|
-
resources: eventTopicResources->Array.concat([
|
|
82
|
+
resources: eventTopicResources->Array.concat([
|
|
83
|
+
queue->Util_SQS.toResource(~tags=tags->Pulumi.Output.fromInput),
|
|
84
|
+
]),
|
|
78
85
|
enqueueEvent,
|
|
79
86
|
handleChannelEvent,
|
|
80
87
|
}
|
|
@@ -4,14 +4,19 @@ type runtimeParts = Util.Lambda.runtimeParts
|
|
|
4
4
|
|
|
5
5
|
let connect = EventCollectorChannel_SQS.connect
|
|
6
6
|
|
|
7
|
-
let make: ReventlessCore.EventCollector_Adapter.channelMaker<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
) => {
|
|
7
|
+
let make: ReventlessCore.EventCollector_Adapter.channelMaker<
|
|
8
|
+
callbackEvent,
|
|
9
|
+
'context,
|
|
10
|
+
channelParts,
|
|
11
|
+
> = (~name, ~eventTopics, ~owner, ~opts) => {
|
|
12
12
|
let opts = opts->ReventlessCore.Util.Pulumi.ComponentResourceOptions.toCustomResourceOptions
|
|
13
13
|
|
|
14
|
-
let tags = AWS.Tags.make(
|
|
14
|
+
let tags = AWS.Tags.make(
|
|
15
|
+
~name,
|
|
16
|
+
~kind=ReventlessCore.EventCollector.componentType,
|
|
17
|
+
~role=EventCollector,
|
|
18
|
+
~owner?,
|
|
19
|
+
)
|
|
15
20
|
let queue = PulumiAws.SQS.Queue.make(
|
|
16
21
|
~name,
|
|
17
22
|
~args={
|
|
@@ -52,7 +57,9 @@ let make: ReventlessCore.EventCollector_Adapter.channelMaker<callbackEvent, 'con
|
|
|
52
57
|
|
|
53
58
|
{
|
|
54
59
|
ReventlessCore.EventCollector_Adapter.parts: {queue: queue},
|
|
55
|
-
resources: eventTopicResources->Array.concat([
|
|
60
|
+
resources: eventTopicResources->Array.concat([
|
|
61
|
+
queue->Util_SQS.toResource(~tags=tags->Pulumi.Output.fromInput),
|
|
62
|
+
]),
|
|
56
63
|
enqueueEvent,
|
|
57
64
|
handleChannelEvent,
|
|
58
65
|
}
|
|
@@ -39,8 +39,7 @@ let handleDynamoDbOrSqsEvent = (queue, handleEvents) =>
|
|
|
39
39
|
switch entries {
|
|
40
40
|
| [] => Effect.succeed()
|
|
41
41
|
| entries =>
|
|
42
|
-
Util.SQS_Runtime.deleteMessages(entries, queue)
|
|
43
|
-
->Effect.catchAll(_err => Effect.succeed())
|
|
42
|
+
Util.SQS_Runtime.deleteMessages(entries, queue)->Effect.catchAll(_err => Effect.succeed())
|
|
44
43
|
}
|
|
45
44
|
)
|
|
46
45
|
}
|
|
@@ -84,7 +83,11 @@ let enqueueFifoEvent = (queue: Util_SQS_Runtime.resolvedQueue, delay, id, messag
|
|
|
84
83
|
)
|
|
85
84
|
->Effect.flatMap(_ =>
|
|
86
85
|
Effect.promise(() =>
|
|
87
|
-
queue->Util_SQS_Runtime.sendFifoMessage(
|
|
86
|
+
queue->Util_SQS_Runtime.sendFifoMessage(
|
|
87
|
+
~delay,
|
|
88
|
+
~messageGroupId=Util_SQS_Runtime.safeGroupId(id),
|
|
89
|
+
messageBody,
|
|
90
|
+
)
|
|
88
91
|
)
|
|
89
92
|
)
|
|
90
93
|
->Effect.map(_ => ())
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
let make: ReventlessCore.EventLog_Adapter.storageMaker = (~name, ~owner, ~opts) => {
|
|
2
|
-
let tags = AWS.Tags.make(
|
|
2
|
+
let tags = AWS.Tags.make(
|
|
3
|
+
~name,
|
|
4
|
+
~kind=ReventlessCore.EventLog.componentType,
|
|
5
|
+
~role=EventLog,
|
|
6
|
+
~owner?,
|
|
7
|
+
)
|
|
3
8
|
let table = Util.DynamoDbStream.makeTable(
|
|
4
9
|
name,
|
|
5
10
|
~attributes=[{name: "id", type_: "S"}, {name: "position", type_: "S"}],
|
|
@@ -29,9 +29,8 @@ let transactWriteConditional = (tableName, jsons) => {
|
|
|
29
29
|
let input: TransactWriteCommand.input = {
|
|
30
30
|
transactItems: buildTransactItems(tableName, jsons),
|
|
31
31
|
}
|
|
32
|
-
Effect.tryPromise(
|
|
33
|
-
|
|
34
|
-
() => input->TransactWriteCommand.make->TransactWriteCommand.send,
|
|
32
|
+
Effect.tryPromise(~catch=DynamoDb_Error.classify, () =>
|
|
33
|
+
input->TransactWriteCommand.make->TransactWriteCommand.send
|
|
35
34
|
)->Effect.map(_ => Ok())
|
|
36
35
|
}
|
|
37
36
|
|
|
@@ -46,9 +45,8 @@ let appendWithCondition = (tableName, jsons) => {
|
|
|
46
45
|
),
|
|
47
46
|
)
|
|
48
47
|
} else if count == 1 {
|
|
49
|
-
Effect.tryPromise(
|
|
50
|
-
|
|
51
|
-
() => putItemConditional(tableName, jsons->Array.getUnsafe(0)),
|
|
48
|
+
Effect.tryPromise(~catch=DynamoDb_Error.classify, () =>
|
|
49
|
+
putItemConditional(tableName, jsons->Array.getUnsafe(0))
|
|
52
50
|
)->Effect.map(_ => Ok())
|
|
53
51
|
} else {
|
|
54
52
|
transactWriteConditional(tableName, jsons)
|
|
@@ -60,12 +58,13 @@ let append = table =>
|
|
|
60
58
|
appendWithCondition(table.name, jsons)
|
|
61
59
|
->Effect.catchAll(err =>
|
|
62
60
|
switch err {
|
|
63
|
-
| DynamoDb_Error.StaleState(_) =>
|
|
64
|
-
Effect.succeed(Error(ReventlessCore.EventLog.Conflict))
|
|
61
|
+
| DynamoDb_Error.StaleState(_) => Effect.succeed(Error(ReventlessCore.EventLog.Conflict))
|
|
65
62
|
| _ =>
|
|
66
63
|
let msg = DynamoDb_Error.message(err)
|
|
67
64
|
Effect.succeed(
|
|
68
|
-
Error(
|
|
65
|
+
Error(
|
|
66
|
+
ReventlessCore.EventLog.StorageFailure(`DynamoDB conditional append failed: ${msg}`),
|
|
67
|
+
),
|
|
69
68
|
)
|
|
70
69
|
}
|
|
71
70
|
)
|
|
@@ -170,8 +169,9 @@ let writeSnapshot = table =>
|
|
|
170
169
|
// pays for the events it returns.
|
|
171
170
|
let replayStream = table =>
|
|
172
171
|
(id, ~fromSeq=?) =>
|
|
173
|
-
queryStream(
|
|
174
|
-
|
|
172
|
+
queryStream(
|
|
173
|
+
replayQueryInput(table.Util_DynamoDb_Runtime.name, id, ~fromSeq?),
|
|
174
|
+
)->Stream.catchAll(err => {
|
|
175
175
|
let msg = DynamoDb_Error.message(err)
|
|
176
176
|
Stream.fromEffect(Effect.fail(msg))
|
|
177
177
|
})
|
|
@@ -185,8 +185,7 @@ let replay = table =>
|
|
|
185
185
|
ReventlessCore.EffectLogger.logError(
|
|
186
186
|
~comp=__MODULE__,
|
|
187
187
|
`Couldn't replay events for id ${id} after retries: ${msg}`,
|
|
188
|
-
)
|
|
189
|
-
->Effect.flatMap(_ => Effect.fail(msg))
|
|
188
|
+
)->Effect.flatMap(_ => Effect.fail(msg))
|
|
190
189
|
})
|
|
191
190
|
->Effect.runPromise
|
|
192
191
|
|
|
@@ -196,10 +195,7 @@ let appendStream = table =>
|
|
|
196
195
|
(startingSeqNr, _id, stream) => {
|
|
197
196
|
let seqNrRef = ref(startingSeqNr)
|
|
198
197
|
stream->Stream.runForEach(json =>
|
|
199
|
-
Effect.tryPromise(
|
|
200
|
-
~catch=DynamoDb_Error.classify,
|
|
201
|
-
() => putItemConditional(table.name, json),
|
|
202
|
-
)
|
|
198
|
+
Effect.tryPromise(~catch=DynamoDb_Error.classify, () => putItemConditional(table.name, json))
|
|
203
199
|
->Effect.map(_ => {
|
|
204
200
|
seqNrRef := seqNrRef.contents + 1
|
|
205
201
|
})
|
|
@@ -16,9 +16,10 @@ let make: ReventlessCore.EventLog_Adapter.storageMaker = (~name, ~owner as _, ~o
|
|
|
16
16
|
// `event_log.log_name`. Register it so `makePlatform` can wire the change-feed
|
|
17
17
|
// relay; the collector queue is attached later in forPluginEventCollector,
|
|
18
18
|
// keyed by the aggregate name (the `~eventTopics` dict key).
|
|
19
|
-
let aggregateName =
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
let aggregateName =
|
|
20
|
+
name->String.endsWith("EventLog")
|
|
21
|
+
? name->String.slice(~start=0, ~end=name->String.length - 8)
|
|
22
|
+
: name
|
|
22
23
|
EventLogBackend.registerRelayLog(~logName=name, ~aggregateName)
|
|
23
24
|
|
|
24
25
|
let operations = switch EventLogBackend.get() {
|
|
@@ -28,7 +29,9 @@ let make: ReventlessCore.EventLog_Adapter.storageMaker = (~name, ~owner as _, ~o
|
|
|
28
29
|
)
|
|
29
30
|
| None =>
|
|
30
31
|
// Selectable only routes here when a selection is set; guard defensively.
|
|
31
|
-
JsError.throwWithMessage(
|
|
32
|
+
JsError.throwWithMessage(
|
|
33
|
+
"EventLogStorage_Postgres.make called without an EventLogBackend selection",
|
|
34
|
+
)
|
|
32
35
|
}
|
|
33
36
|
{
|
|
34
37
|
ReventlessCore.EventLog_Adapter.resources: [],
|
|
@@ -21,7 +21,7 @@ open PulumiAws
|
|
|
21
21
|
// carrying `@/./:` etc. doesn't hit a silent-drop. Mirrors
|
|
22
22
|
// AppSyncEventsSigner_Ops.pathSegment (the runtime handler's equivalent).
|
|
23
23
|
let channelNameOf = (topicName: string): string =>
|
|
24
|
-
topicName->String.replaceRegExp(
|
|
24
|
+
topicName->String.replaceRegExp(/[^A-Za-z0-9-]/g, "-")
|
|
25
25
|
|
|
26
26
|
// ── Deploy-time resource builder ──────────────────────────────────────────────
|
|
27
27
|
|
|
@@ -114,10 +114,7 @@ let make = (
|
|
|
114
114
|
|
|
115
115
|
// IAM policy: SQS receive + AppSync Events publish
|
|
116
116
|
let _ =
|
|
117
|
-
(
|
|
118
|
-
queue.arn,
|
|
119
|
-
eventsApi.api.apiArn,
|
|
120
|
-
)
|
|
117
|
+
(queue.arn, eventsApi.api.apiArn)
|
|
121
118
|
->Pulumi.Output.all2
|
|
122
119
|
->Pulumi.Output.apply(((queueArn, apiArn)) => {
|
|
123
120
|
open PolicyDocument
|
|
@@ -165,7 +162,10 @@ let make = (
|
|
|
165
162
|
// resolve-hook so `@rescript/runtime` resolves from the layer.
|
|
166
163
|
let channelName = channelNameOf(topicName)
|
|
167
164
|
let packageDirs = Dict.fromArray([
|
|
168
|
-
(
|
|
165
|
+
(
|
|
166
|
+
"@reventlessdev/reventless-aws",
|
|
167
|
+
Util_Bundle.resolvePackageRoot("@reventlessdev/reventless-aws"),
|
|
168
|
+
),
|
|
169
169
|
])
|
|
170
170
|
let {code, sourceCodeHash} = Util_Bundle.buildCodeArchive(
|
|
171
171
|
~entryPointModule="@reventlessdev/reventless-aws/src/adapter/EventLogSubscription/EventLogSubscription_AppSync_Ops.res.mjs",
|
|
@@ -192,7 +192,12 @@ let make = (
|
|
|
192
192
|
memorySize: 128->Pulumi.Input.make,
|
|
193
193
|
timeout: 30->Pulumi.Input.make,
|
|
194
194
|
layers,
|
|
195
|
-
tags: AWS.Tags.make(
|
|
195
|
+
tags: AWS.Tags.make(
|
|
196
|
+
~name=name ++ "EventLogSub",
|
|
197
|
+
~kind=ReventlessCore.EventTopic.componentType,
|
|
198
|
+
~role=EventLogSubscription,
|
|
199
|
+
~component=name,
|
|
200
|
+
),
|
|
196
201
|
environment: (
|
|
197
202
|
{
|
|
198
203
|
Lambda.Function.variables: Dict.fromArray([
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
// body, wraps it as a `{position, eventType, payload}` event, and publishes it
|
|
8
8
|
// to the fixed plugin event-log channel on the AppSync Events API.
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
// Baked at deploy time: the normalised channel segment for this event log.
|
|
12
11
|
let channel = "/default/" ++ NodeProcess.env->Dict.get("EVENT_LOG_CHANNEL")->Option.getOr("")
|
|
13
12
|
let endpoint = NodeProcess.env->Dict.get("APPSYNC_ENDPOINT")->Option.getOr("")
|
|
@@ -37,7 +36,10 @@ let processRecord = async (
|
|
|
37
36
|
Dict.fromArray([
|
|
38
37
|
("id", JSON.Encode.string(record.messageId)),
|
|
39
38
|
("channel", JSON.Encode.string(channel)),
|
|
40
|
-
(
|
|
39
|
+
(
|
|
40
|
+
"events",
|
|
41
|
+
JSON.Encode.array([JSON.Encode.string(payload->JSON.Encode.object->JSON.stringify)]),
|
|
42
|
+
),
|
|
41
43
|
])
|
|
42
44
|
->JSON.Encode.object
|
|
43
45
|
->JSON.stringify
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
let make: ReventlessCore.EventTopic_Adapter.publisherMaker = (
|
|
2
2
|
~name as _,
|
|
3
3
|
~storageResources,
|
|
4
|
-
~owner as _,
|
|
4
|
+
~owner as _,
|
|
5
|
+
~opts as _,
|
|
5
6
|
) => {
|
|
6
7
|
let storageResource = storageResources->Util.DynamoDbStream.findResource
|
|
7
8
|
|
|
@@ -20,6 +21,6 @@ let make: ReventlessCore.EventTopic_Adapter.publisherMaker = (
|
|
|
20
21
|
->ReventlessCore.Adapter.outputToResource,
|
|
21
22
|
],
|
|
22
23
|
publishJson: Pulumi.Output.make((_, _, _) => Promise.resolve()), // ignore
|
|
23
|
-
publishJsonStream: Pulumi.Output.make(_stream => Effect.succeed(
|
|
24
|
+
publishJsonStream: Pulumi.Output.make(_stream => Effect.succeed()), // ignore
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -4,14 +4,20 @@ open PulumiAws
|
|
|
4
4
|
Read by subscriptionInfraHook (Phase 5) to skip non-SNS entries. */
|
|
5
5
|
let snsRegistry: Set.t<string> = Set.make()
|
|
6
6
|
|
|
7
|
-
let make: ReventlessCore.EventTopic_Adapter.publisherMaker = (
|
|
7
|
+
let make: ReventlessCore.EventTopic_Adapter.publisherMaker = (
|
|
8
|
+
~name,
|
|
9
|
+
~storageResources as _,
|
|
10
|
+
~owner,
|
|
11
|
+
~opts,
|
|
12
|
+
) => {
|
|
8
13
|
snsRegistry->Set.add(name)
|
|
9
|
-
let tags = AWS.Tags.make(
|
|
10
|
-
let topic = SNS.Topic.make(
|
|
14
|
+
let tags = AWS.Tags.make(
|
|
11
15
|
~name,
|
|
12
|
-
~
|
|
13
|
-
~
|
|
16
|
+
~kind=ReventlessCore.EventTopic.componentType,
|
|
17
|
+
~role=EventTopic,
|
|
18
|
+
~owner?,
|
|
14
19
|
)
|
|
20
|
+
let topic = SNS.Topic.make(~name, ~args={SNS.Topic.tags: tags}, ~opts)
|
|
15
21
|
|
|
16
22
|
let resolvedTopicOutput = topic->Util_SNS.toResolvedTopicOutput
|
|
17
23
|
|
|
@@ -26,13 +32,15 @@ let make: ReventlessCore.EventTopic_Adapter.publisherMaker = (~name, ~storageRes
|
|
|
26
32
|
stream
|
|
27
33
|
->Stream.grouped(10)
|
|
28
34
|
->Stream.runForEach(items =>
|
|
29
|
-
Effect.promise(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
Effect.promise(
|
|
36
|
+
() =>
|
|
37
|
+
items
|
|
38
|
+
->Array.map(
|
|
39
|
+
({ReventlessInfra.EventTopic.service: service, meta, json}) =>
|
|
40
|
+
publishJson(service, meta, json),
|
|
41
|
+
)
|
|
42
|
+
->Promise.all
|
|
43
|
+
->Promise.thenResolve(_ => ()),
|
|
36
44
|
)
|
|
37
45
|
)
|
|
38
46
|
}),
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
open PulumiAws
|
|
2
2
|
|
|
3
|
-
let make: ReventlessCore.EventTopic_Adapter.publisherMaker = (
|
|
4
|
-
|
|
3
|
+
let make: ReventlessCore.EventTopic_Adapter.publisherMaker = (
|
|
4
|
+
~name,
|
|
5
|
+
~storageResources as _,
|
|
6
|
+
~owner,
|
|
7
|
+
~opts,
|
|
8
|
+
) => {
|
|
9
|
+
let tags = AWS.Tags.make(
|
|
10
|
+
~name,
|
|
11
|
+
~kind=ReventlessCore.EventTopic.componentType,
|
|
12
|
+
~role=EventTopic,
|
|
13
|
+
~owner?,
|
|
14
|
+
)
|
|
5
15
|
let topic = SNS.Topic.make(
|
|
6
16
|
~name,
|
|
7
17
|
~args={
|
|
@@ -25,13 +35,15 @@ let make: ReventlessCore.EventTopic_Adapter.publisherMaker = (~name, ~storageRes
|
|
|
25
35
|
stream
|
|
26
36
|
->Stream.grouped(10)
|
|
27
37
|
->Stream.runForEach(items =>
|
|
28
|
-
Effect.promise(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
Effect.promise(
|
|
39
|
+
() =>
|
|
40
|
+
items
|
|
41
|
+
->Array.map(
|
|
42
|
+
({ReventlessInfra.EventTopic.service: service, meta, json}) =>
|
|
43
|
+
publishJson(service, meta, json),
|
|
44
|
+
)
|
|
45
|
+
->Promise.all
|
|
46
|
+
->Promise.thenResolve(_ => ()),
|
|
35
47
|
)
|
|
36
48
|
)
|
|
37
49
|
}),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
let publish = (topic, _id, _meta, json) =>
|
|
2
|
-
topic->Util_SNS_Runtime.publish(json->JSON.stringify)
|
|
1
|
+
let publish = (topic, _id, _meta, json) => topic->Util_SNS_Runtime.publish(json->JSON.stringify)
|
|
3
2
|
|
|
4
3
|
let publishFifo = (topic, id, _meta, json) =>
|
|
5
|
-
topic->Util_SNS_Runtime.publishFifo(
|
|
4
|
+
topic->Util_SNS_Runtime.publishFifo(
|
|
5
|
+
~messageGroupId=Util_SQS_Runtime.safeGroupId(id),
|
|
6
|
+
~message=json->JSON.stringify,
|
|
7
|
+
)
|
|
@@ -31,8 +31,7 @@ type serviceOutputs = {resources: array<Pulumi.Output.t<string>>}
|
|
|
31
31
|
// forwarded — geocoding is not scoped per caller (any authenticated user may
|
|
32
32
|
// resolve any address), unlike the upload service which namespaces objects by the
|
|
33
33
|
// verified `sub`.
|
|
34
|
-
let invokeCode: Pulumi.Input.t<string> =
|
|
35
|
-
`import { util } from '@aws-appsync/utils';
|
|
34
|
+
let invokeCode: Pulumi.Input.t<string> = `import { util } from '@aws-appsync/utils';
|
|
36
35
|
export function request(ctx) {
|
|
37
36
|
return { operation: 'Invoke', payload: { arguments: ctx.args } };
|
|
38
37
|
}
|
|
@@ -79,7 +78,11 @@ let make = (
|
|
|
79
78
|
{
|
|
80
79
|
sid: "AllowLambdaLogging",
|
|
81
80
|
effect: Allow,
|
|
82
|
-
actions: Actions([
|
|
81
|
+
actions: Actions([
|
|
82
|
+
"logs:CreateLogGroup",
|
|
83
|
+
"logs:CreateLogStream",
|
|
84
|
+
"logs:PutLogEvents",
|
|
85
|
+
]),
|
|
83
86
|
resources: Resource("arn:aws:logs:*:*:*"),
|
|
84
87
|
},
|
|
85
88
|
{
|
|
@@ -133,7 +133,7 @@ let generateAdminConfig = (
|
|
|
133
133
|
|
|
134
134
|
/** Extract entity ID from the last path segment (before any query string). */
|
|
135
135
|
let extractEntityId = (uri: string) => {
|
|
136
|
-
let pathPart =
|
|
136
|
+
let pathPart = uri->String.split("?")->Array.getUnsafe(0)
|
|
137
137
|
let segments = pathPart->String.split("/")
|
|
138
138
|
segments->Array.at(-1)->Option.getOr("")
|
|
139
139
|
}
|
|
@@ -145,26 +145,21 @@ let parsePaginationParams = (uri: string) => {
|
|
|
145
145
|
| None => (None, None)
|
|
146
146
|
| Some(qs) =>
|
|
147
147
|
let params = Dict.make()
|
|
148
|
-
qs
|
|
148
|
+
qs
|
|
149
|
+
->String.split("&")
|
|
150
|
+
->Array.forEach(param => {
|
|
149
151
|
let kv = param->String.split("=")
|
|
150
152
|
switch (kv->Array.get(0), kv->Array.get(1)) {
|
|
151
153
|
| (Some(k), Some(v)) => params->Dict.set(k, v)
|
|
152
154
|
| _ => ()
|
|
153
155
|
}
|
|
154
156
|
})
|
|
155
|
-
(
|
|
156
|
-
params->Dict.get("limit")->Option.flatMap(v => Int.fromString(v)),
|
|
157
|
-
params->Dict.get("after"),
|
|
158
|
-
)
|
|
157
|
+
(params->Dict.get("limit")->Option.flatMap(v => Int.fromString(v)), params->Dict.get("after"))
|
|
159
158
|
}
|
|
160
159
|
}
|
|
161
160
|
|
|
162
161
|
/** Build a paginated response JSON with events and pagination metadata. */
|
|
163
|
-
let paginatedResponse = (
|
|
164
|
-
~events: array<JSON.t>,
|
|
165
|
-
~hasMore: bool,
|
|
166
|
-
~nextAfter: option<string>,
|
|
167
|
-
) =>
|
|
162
|
+
let paginatedResponse = (~events: array<JSON.t>, ~hasMore: bool, ~nextAfter: option<string>) =>
|
|
168
163
|
Dict.fromArray([
|
|
169
164
|
("events", events->JSON.Encode.array),
|
|
170
165
|
(
|
|
@@ -196,25 +191,24 @@ let readEventLogHistory = async (
|
|
|
196
191
|
|
|
197
192
|
let expressionAttributeValues = [(":id", entityId->JSON.Encode.string)]->Dict.fromArray
|
|
198
193
|
|
|
199
|
-
let exclusiveStartKey =
|
|
200
|
-
|
|
201
|
-
(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
194
|
+
let exclusiveStartKey =
|
|
195
|
+
after->Option.map(afterPos =>
|
|
196
|
+
Dict.fromArray([
|
|
197
|
+
("id", entityId->JSON.Encode.string),
|
|
198
|
+
("position", afterPos->JSON.Encode.string),
|
|
199
|
+
])
|
|
200
|
+
)
|
|
205
201
|
|
|
206
|
-
let stream =
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
Stream.empty
|
|
217
|
-
})
|
|
202
|
+
let stream = Util_DynamoDb_Runtime.queryStream({
|
|
203
|
+
tableName: table.name,
|
|
204
|
+
consistentRead: true,
|
|
205
|
+
keyConditionExpression: "id=:id",
|
|
206
|
+
expressionAttributeValues,
|
|
207
|
+
?exclusiveStartKey,
|
|
208
|
+
})->Stream.catchAll(err => {
|
|
209
|
+
let _ = DynamoDb_Error.message(err)
|
|
210
|
+
Stream.empty
|
|
211
|
+
})
|
|
218
212
|
|
|
219
213
|
// Fetch limit+1 items to detect hasMore
|
|
220
214
|
let bounded = switch limit {
|
|
@@ -225,8 +219,7 @@ let readEventLogHistory = async (
|
|
|
225
219
|
let events = await bounded->Stream.runCollect->Effect.runPromise
|
|
226
220
|
|
|
227
221
|
let (limited, hasMore) = switch limit {
|
|
228
|
-
| Some(n)
|
|
229
|
-
(events->Array.slice(~start=0, ~end=n), true)
|
|
222
|
+
| Some(n) if events->Array.length > n => (events->Array.slice(~start=0, ~end=n), true)
|
|
230
223
|
| _ => (events, false)
|
|
231
224
|
}
|
|
232
225
|
|
|
@@ -258,10 +251,7 @@ let readDcbEventLogHistory = async (
|
|
|
258
251
|
hashKey: "id",
|
|
259
252
|
}
|
|
260
253
|
|
|
261
|
-
let result = await DcbEventLogStorage_DynamoDb_Runtime.read(table)(
|
|
262
|
-
~query=[],
|
|
263
|
-
~after?,
|
|
264
|
-
)
|
|
254
|
+
let result = await DcbEventLogStorage_DynamoDb_Runtime.read(table)(~query=[], ~after?)
|
|
265
255
|
|
|
266
256
|
// Filter by entity ID tag value (events matching this entity)
|
|
267
257
|
let filtered = if entityId->String.length > 0 {
|
|
@@ -272,8 +262,7 @@ let readDcbEventLogHistory = async (
|
|
|
272
262
|
|
|
273
263
|
// Apply limit
|
|
274
264
|
let (limited, hasMore) = switch limit {
|
|
275
|
-
| Some(n)
|
|
276
|
-
(filtered->Array.slice(~start=0, ~end=n), true)
|
|
265
|
+
| Some(n) if filtered->Array.length > n => (filtered->Array.slice(~start=0, ~end=n), true)
|
|
277
266
|
| _ => (filtered, false)
|
|
278
267
|
}
|
|
279
268
|
|
|
@@ -381,11 +370,7 @@ let extractIdentity = (authHeader: option<string>): Reventless.Identity.t =>
|
|
|
381
370
|
|
|
382
371
|
/** Dispatch an MCP tool call through makeGenerateCommand so the interceptor hook fires.
|
|
383
372
|
The commandTopicArn from mcpConfig tells us which SQS FIFO queue to target. */
|
|
384
|
-
let dispatchTool = async (
|
|
385
|
-
tool: mcpToolEntry,
|
|
386
|
-
args: JSON.t,
|
|
387
|
-
identity: Reventless.Identity.t,
|
|
388
|
-
) => {
|
|
373
|
+
let dispatchTool = async (tool: mcpToolEntry, args: JSON.t, identity: Reventless.Identity.t) => {
|
|
389
374
|
let queueRef = makeQueueRef(tool.commandTopicArn)
|
|
390
375
|
let publishJsons = sqsPublishJsons(queueRef, AWS.SQS_FIFO.service)
|
|
391
376
|
let generateCommand = makeGenerateCommand(
|
|
@@ -448,12 +433,12 @@ let dispatchTool = async (
|
|
|
448
433
|
|
|
449
434
|
/** Authentication mode for the Lambda Function URL. */
|
|
450
435
|
type authType =
|
|
451
|
-
|
|
436
|
+
/** AWS IAM auth — callers sign requests with SigV4. Suitable for
|
|
452
437
|
service-to-service or Cognito identity pool access. */
|
|
453
|
-
AwsIam
|
|
454
|
-
|
|
438
|
+
| AwsIam
|
|
439
|
+
/** No auth — the Function URL is publicly accessible. Suitable for
|
|
455
440
|
development or when auth is handled at a different layer (API Gateway). */
|
|
456
|
-
None
|
|
441
|
+
| None
|
|
457
442
|
|
|
458
443
|
/** Per-tool authorization scope. Tools can require specific Cognito groups
|
|
459
444
|
or OAuth scopes before execution. */
|
|
@@ -20,8 +20,7 @@ here — `Messaging.UnsupportedChannel` is what a caller gets, which is settled
|
|
|
20
20
|
rather than retried, so a preference for a channel this deployment does not run
|
|
21
21
|
costs one refusal and not a retry budget.
|
|
22
22
|
*/
|
|
23
|
-
let channels = (~sender: string): array<Reventless.Messaging.channel> =>
|
|
24
|
-
sender == "" ? [] : [Email]
|
|
23
|
+
let channels = (~sender: string): array<Reventless.Messaging.channel> => sender == "" ? [] : [Email]
|
|
25
24
|
|
|
26
25
|
/**
|
|
27
26
|
Send one message.
|
|
@@ -77,8 +76,13 @@ let send = async (
|
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
/** The port, closed over the deployment's sender. What a Lambda entry point puts
|
|
80
|
-
on `Capabilities.messaging`.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
on `Capabilities.messaging`.
|
|
80
|
+
|
|
81
|
+
No push service, so `makeProvider` publishes no `Push` channel. SES is an email
|
|
82
|
+
transport; a push one would be a separate provisioning with its own
|
|
83
|
+
credential. */
|
|
84
|
+
let provider = (~sender: string): Reventless.Messaging.provider =>
|
|
85
|
+
Reventless.Messaging.makeProvider(~emailAndSms=channels(~sender), ~pushServices=[], ~send=(
|
|
86
|
+
~recipient,
|
|
87
|
+
~message,
|
|
88
|
+
) => send(~sender, ~recipient, ~message))
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import * as SES$AwsSdk from "@reventlessdev/rescript-aws-sdk/src/SES.res.mjs";
|
|
4
4
|
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
5
5
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
|
+
import * as Messaging$Reventless from "@reventlessdev/reventless-spec/src/semantic/Messaging.res.mjs";
|
|
6
7
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
7
8
|
import * as ClientSesv2 from "@aws-sdk/client-sesv2";
|
|
8
9
|
|
|
@@ -103,10 +104,7 @@ async function send(sender, recipient, message) {
|
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
function provider(sender) {
|
|
106
|
-
return
|
|
107
|
-
channels: channels(sender),
|
|
108
|
-
send: (recipient, message) => send(sender, recipient, message)
|
|
109
|
-
};
|
|
107
|
+
return Messaging$Reventless.makeProvider(channels(sender), [], (recipient, message) => send(sender, recipient, message));
|
|
110
108
|
}
|
|
111
109
|
|
|
112
110
|
let Send;
|