@reventlessdev/reventless-aws 3.0.0-alpha.167
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 +1564 -0
- package/README.md +62 -0
- package/__mocks__/emptyModule.js +1 -0
- package/all-licenses.csv +565 -0
- package/docker-compose.dynamodb-local.yml +12 -0
- package/jest.setup.cjs +5 -0
- package/licenses-analysis.ods +0 -0
- package/package.json +73 -0
- package/rescript.json +39 -0
- package/reventless-licenses-analysis.xls +0 -0
- package/scripts/run-integration-tests.sh +43 -0
- package/src/Platform.res +1940 -0
- package/src/Platform.res.mjs +2281 -0
- package/src/Platform_Casts.res +106 -0
- package/src/Platform_Casts.res.mjs +13 -0
- package/src/Platform_Stack.res +153 -0
- package/src/Platform_Stack.res.mjs +121 -0
- package/src/Types.res +39 -0
- package/src/Types.res.mjs +21 -0
- package/src/adapter/AWS.res +96 -0
- package/src/adapter/AWS.res.mjs +186 -0
- package/src/adapter/AWS_Tags.res +16 -0
- package/src/adapter/AWS_Tags.res.mjs +48 -0
- package/src/adapter/Adapter_Helpers.res +19 -0
- package/src/adapter/Adapter_Helpers.res.mjs +37 -0
- package/src/adapter/Api/AppSync_EventsApi.res +172 -0
- package/src/adapter/Api/AppSync_EventsApi.res.mjs +96 -0
- package/src/adapter/Api/AppSync_Resolver_Native.res +93 -0
- package/src/adapter/Api/AppSync_Resolver_Native.res.mjs +67 -0
- package/src/adapter/Api/AppSync_Resolver_Retrying.res +653 -0
- package/src/adapter/Api/AppSync_Resolver_Retrying.res.mjs +462 -0
- package/src/adapter/Api/CommandSubscriptionResolvers_AppSync.res +29 -0
- package/src/adapter/Api/CommandSubscriptionResolvers_AppSync.res.mjs +15 -0
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +238 -0
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res.mjs +179 -0
- package/src/adapter/Api/Platform_UIFragments_Lambda.res +229 -0
- package/src/adapter/Api/Platform_UIFragments_Lambda.res.mjs +245 -0
- package/src/adapter/Auth/Auth_Cognito.res +209 -0
- package/src/adapter/Auth/Auth_Cognito.res.mjs +135 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers.res +2 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers.res.mjs +12 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +251 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res.mjs +126 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res +20 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res.mjs +23 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_Runtime.res +1 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_Runtime.res.mjs +11 -0
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res +95 -0
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res.mjs +50 -0
- package/src/adapter/CommandTopic/CommandTopicChannel.res +6 -0
- package/src/adapter/CommandTopic/CommandTopicChannel.res.mjs +21 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_Helpers.res +196 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_Helpers.res.mjs +145 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +91 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res.mjs +74 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +69 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs +62 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +60 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res.mjs +56 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res +73 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs +65 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +88 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs +76 -0
- package/src/adapter/CommandTopic/CommandTopicRemoteChannel.res +1 -0
- package/src/adapter/CommandTopic/CommandTopicRemoteChannel.res.mjs +9 -0
- package/src/adapter/CommandTopic/CommandTopicRemoteChannel_SQS.res +7 -0
- package/src/adapter/CommandTopic/CommandTopicRemoteChannel_SQS.res.mjs +17 -0
- package/src/adapter/Counter/CounterHandler_DynamoDbStream.res +103 -0
- package/src/adapter/Counter/CounterHandler_DynamoDbStream.res.mjs +68 -0
- package/src/adapter/Counter/CounterHandler_DynamoDbStream_Runtime.res +107 -0
- package/src/adapter/Counter/CounterHandler_DynamoDbStream_Runtime.res.mjs +145 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage.res +1 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage.res.mjs +9 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res +84 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res.mjs +52 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +1436 -0
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res.mjs +1143 -0
- package/src/adapter/EventCollector/EventCollectorChannel.res +6 -0
- package/src/adapter/EventCollector/EventCollectorChannel.res.mjs +21 -0
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +63 -0
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs +56 -0
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res +20 -0
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res.mjs +32 -0
- package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res +266 -0
- package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res.mjs +166 -0
- package/src/adapter/EventCollector/EventCollectorChannel_SQS.res +81 -0
- package/src/adapter/EventCollector/EventCollectorChannel_SQS.res.mjs +54 -0
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res +59 -0
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res.mjs +45 -0
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res +91 -0
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res.mjs +89 -0
- package/src/adapter/EventLog/EventLogStorage.res +3 -0
- package/src/adapter/EventLog/EventLogStorage.res.mjs +15 -0
- package/src/adapter/EventLog/EventLogStorage_DynamoDb.res +25 -0
- package/src/adapter/EventLog/EventLogStorage_DynamoDb.res.mjs +34 -0
- package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res +26 -0
- package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res.mjs +35 -0
- package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res +121 -0
- package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res.mjs +137 -0
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +265 -0
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res.mjs +185 -0
- package/src/adapter/EventTopic/EventTopicPublisher.res +6 -0
- package/src/adapter/EventTopic/EventTopicPublisher.res.mjs +21 -0
- package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res +25 -0
- package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res.mjs +28 -0
- package/src/adapter/EventTopic/EventTopicPublisher_SNS.res +40 -0
- package/src/adapter/EventTopic/EventTopicPublisher_SNS.res.mjs +39 -0
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res +39 -0
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res.mjs +38 -0
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res +5 -0
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res.mjs +18 -0
- package/src/adapter/Mcp/MCP_Lambda.res +502 -0
- package/src/adapter/Mcp/MCP_Lambda.res.mjs +289 -0
- package/src/adapter/QueryDb/NodeResolver_AppSync.res +71 -0
- package/src/adapter/QueryDb/NodeResolver_AppSync.res.mjs +44 -0
- package/src/adapter/QueryDb/QueryDbResolvers.res +2 -0
- package/src/adapter/QueryDb/QueryDbResolvers.res.mjs +12 -0
- package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res +434 -0
- package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res.mjs +243 -0
- package/src/adapter/QueryDb/QueryDbResolvers_AppSync_NoOp.res +21 -0
- package/src/adapter/QueryDb/QueryDbResolvers_AppSync_NoOp.res.mjs +14 -0
- package/src/adapter/QueryDb/QueryDbResolvers_NoOp.res +21 -0
- package/src/adapter/QueryDb/QueryDbResolvers_NoOp.res.mjs +14 -0
- package/src/adapter/QueryDb/QueryDbStorage.res +5 -0
- package/src/adapter/QueryDb/QueryDbStorage.res.mjs +18 -0
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res +115 -0
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res.mjs +100 -0
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res +52 -0
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res.mjs +38 -0
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res +271 -0
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res.mjs +306 -0
- package/src/adapter/QueryDb/QueryInterceptor_Lambda.res +20 -0
- package/src/adapter/QueryDb/QueryInterceptor_Lambda.res.mjs +22 -0
- package/src/adapter/QueryEngine/QueryEngine.res +3 -0
- package/src/adapter/QueryEngine/QueryEngine.res.mjs +12 -0
- package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res +184 -0
- package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res.mjs +221 -0
- package/src/adapter/Runtime/AdminEventCollectorEntryPoint.mjs +879 -0
- package/src/adapter/Runtime/AggregateEntryPoint.mjs +313 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +327 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +239 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +331 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +240 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +247 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +185 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +244 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +185 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +347 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +244 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +285 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +212 -0
- package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +124 -0
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +187 -0
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +147 -0
- package/src/adapter/Runtime/CounterEntryPoint.mjs +91 -0
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +265 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +122 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res.mjs +89 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +193 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +137 -0
- package/src/adapter/Runtime/EventMapperEntryPoint.mjs +97 -0
- package/src/adapter/Runtime/ExtensionPointEntryPoint.mjs +101 -0
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +83 -0
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res.mjs +59 -0
- package/src/adapter/Runtime/HandlerFactoryHelpers.mjs +142 -0
- package/src/adapter/Runtime/HeartbeatEntryPoint.mjs +38 -0
- package/src/adapter/Runtime/PluginExtensionPointEntryPoint.mjs +137 -0
- package/src/adapter/Runtime/ReadModelEntryPoint.mjs +143 -0
- package/src/adapter/Runtime/RuntimeEnvironment.res +1 -0
- package/src/adapter/Runtime/RuntimeEnvironment.res.mjs +9 -0
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +254 -0
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs +169 -0
- package/src/adapter/Runtime/SideEffectEntryPoint.mjs +81 -0
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +178 -0
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res.mjs +129 -0
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +166 -0
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +87 -0
- package/src/adapter/Runtime/StateViewSliceEntryPoint.mjs +136 -0
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +344 -0
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res.mjs +242 -0
- package/src/adapter/Runtime/TaskBucketEntryPoint.mjs +150 -0
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +123 -0
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res.mjs +74 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher.res +2 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher.res.mjs +12 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +54 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res.mjs +41 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res +97 -0
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res.mjs +85 -0
- package/src/adapter/StateTopic/StateTopic_AppSync.res +418 -0
- package/src/adapter/StateTopic/StateTopic_AppSync.res.mjs +295 -0
- package/src/adapter/Task/TaskBucket.res +1 -0
- package/src/adapter/Task/TaskBucket.res.mjs +9 -0
- package/src/adapter/Task/TaskBucket_S3.res +157 -0
- package/src/adapter/Task/TaskBucket_S3.res.mjs +108 -0
- package/src/adapter/Task/TaskBucket_S3_Runtime.res +11 -0
- package/src/adapter/Task/TaskBucket_S3_Runtime.res.mjs +15 -0
- package/src/components/Aggregate_Builder.res +1 -0
- package/src/components/Aggregate_Builder.res.mjs +25 -0
- package/src/components/Aggregate_Builder_Micro.res +63 -0
- package/src/components/Aggregate_Builder_Micro.res.mjs +80 -0
- package/src/components/Aggregate_Builder_NoResolver.res +61 -0
- package/src/components/Aggregate_Builder_NoResolver.res.mjs +80 -0
- package/src/components/Aggregate_Builder_PerAggregate.res +57 -0
- package/src/components/Aggregate_Builder_PerAggregate.res.mjs +80 -0
- package/src/components/Aggregate_Builder_Single.res +59 -0
- package/src/components/Aggregate_Builder_Single.res.mjs +80 -0
- package/src/components/Aggregate_Builder_Single_Async.res +59 -0
- package/src/components/Aggregate_Builder_Single_Async.res.mjs +80 -0
- package/src/components/Api/AppSync_Adapter.res +500 -0
- package/src/components/Api/AppSync_Adapter.res.mjs +396 -0
- package/src/components/AutomationSlice_Builder.res +52 -0
- package/src/components/AutomationSlice_Builder.res.mjs +72 -0
- package/src/components/AutomationSlice_Builder_Bundled.res.mjs +70 -0
- package/src/components/Counter_Builder.res +10 -0
- package/src/components/Counter_Builder.res.mjs +16 -0
- package/src/components/DataCleaner.res +170 -0
- package/src/components/DataCleaner.res.mjs +2 -0
- package/src/components/DcbEventLog_Builder.res +8 -0
- package/src/components/DcbEventLog_Builder.res.mjs +14 -0
- package/src/components/ExtensionPoint_Builder.res +16 -0
- package/src/components/ExtensionPoint_Builder.res.mjs +37 -0
- package/src/components/ForeignReadModel_Builder.res +19 -0
- package/src/components/ForeignReadModel_Builder.res.mjs +48 -0
- package/src/components/InboundTranslationSlice_Builder.res +25 -0
- package/src/components/InboundTranslationSlice_Builder.res.mjs +31 -0
- package/src/components/OutboundTranslationSlice_Builder.res +60 -0
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +76 -0
- package/src/components/OutboundTranslationSlice_Builder_Bundled.res.mjs +75 -0
- package/src/components/Plugin.res +29 -0
- package/src/components/Plugin.res.mjs +63 -0
- package/src/components/ReadModel_Builder.res +1 -0
- package/src/components/ReadModel_Builder.res.mjs +19 -0
- package/src/components/ReadModel_Builder_NoResolver.res +55 -0
- package/src/components/ReadModel_Builder_NoResolver.res.mjs +64 -0
- package/src/components/ReadModel_Builder_NoResolver_Stream.res +60 -0
- package/src/components/ReadModel_Builder_NoResolver_Stream.res.mjs +64 -0
- package/src/components/ReadModel_Builder_PerReadModel.res +53 -0
- package/src/components/ReadModel_Builder_PerReadModel.res.mjs +66 -0
- package/src/components/ReadModel_Builder_Single.res +52 -0
- package/src/components/ReadModel_Builder_Single.res.mjs +66 -0
- package/src/components/ReadModel_Builder_Single_Stream.res +60 -0
- package/src/components/ReadModel_Builder_Single_Stream.res.mjs +66 -0
- package/src/components/Scheduler.res +1 -0
- package/src/components/Scheduler.res.mjs +13 -0
- package/src/components/SideEffectHandler.res +1 -0
- package/src/components/SideEffectHandler.res.mjs +19 -0
- package/src/components/SideEffectHandler_PerSideEffectHandler.res +13 -0
- package/src/components/SideEffectHandler_PerSideEffectHandler.res.mjs +52 -0
- package/src/components/SideEffectHandler_Single.res +54 -0
- package/src/components/SideEffectHandler_Single.res.mjs +60 -0
- package/src/components/StateChangeSlice_Builder.res +17 -0
- package/src/components/StateChangeSlice_Builder.res.mjs +23 -0
- package/src/components/StateViewSlice_Builder.res +46 -0
- package/src/components/StateViewSlice_Builder.res.mjs +68 -0
- package/src/components/StateViewSlice_Builder_Bundled.res.mjs +69 -0
- package/src/components/StateViewSlice_Builder_Stream.res +50 -0
- package/src/components/StateViewSlice_Builder_Stream.res.mjs +68 -0
- package/src/components/Task_Builder.res +1 -0
- package/src/components/Task_Builder.res.mjs +28 -0
- package/src/components/Task_Builder_PerBucket.res +22 -0
- package/src/components/Task_Builder_PerBucket.res.mjs +63 -0
- package/src/components/Vpc.res +214 -0
- package/src/components/Vpc.res.mjs +117 -0
- package/src/components/Vpc.resi +22 -0
- package/src/errors/AppSync_Error.res +36 -0
- package/src/errors/AppSync_Error.res.mjs +38 -0
- package/src/errors/Cognito_Error.res +36 -0
- package/src/errors/Cognito_Error.res.mjs +38 -0
- package/src/errors/DynamoDb_Error.res +75 -0
- package/src/errors/DynamoDb_Error.res.mjs +86 -0
- package/src/errors/Kinesis_Error.res +36 -0
- package/src/errors/Kinesis_Error.res.mjs +38 -0
- package/src/errors/SNS_Error.res +34 -0
- package/src/errors/SNS_Error.res.mjs +38 -0
- package/src/errors/SQS_Error.res +40 -0
- package/src/errors/SQS_Error.res.mjs +41 -0
- package/src/plugin/cloner/ClonerRunner.res +1 -0
- package/src/plugin/cloner/ClonerRunner.res.mjs +9 -0
- package/src/plugin/cloner/ClonerRunner_Fargate.res +362 -0
- package/src/plugin/cloner/ClonerRunner_Fargate.res.mjs +246 -0
- package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res +42 -0
- package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res.mjs +45 -0
- package/src/plugin/heartbeat/HeartbeatRunner.res +1 -0
- package/src/plugin/heartbeat/HeartbeatRunner.res.mjs +9 -0
- package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res +96 -0
- package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res.mjs +69 -0
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +115 -0
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs +88 -0
- package/src/plugin/runtime/PluginRuntimeOperations.res +5 -0
- package/src/plugin/runtime/PluginRuntimeOperations.res.mjs +14 -0
- package/src/plugin/runtime/PluginRuntime_Builder.res +769 -0
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +464 -0
- package/src/plugin/runtime/Util_PluginMessage_Runtime.res +13 -0
- package/src/plugin/runtime/Util_PluginMessage_Runtime.res.mjs +19 -0
- package/src/plugin/stack/Plugin_ExtensionPoint_Builder.res +28 -0
- package/src/plugin/stack/Plugin_ExtensionPoint_Builder.res.mjs +67 -0
- package/src/plugin/stack/Plugin_Stack.res +439 -0
- package/src/plugin/stack/Plugin_Stack.res.mjs +263 -0
- package/src/util/Util.res +29 -0
- package/src/util/Util.res.mjs +93 -0
- package/src/util/Util_AppSync.res +36 -0
- package/src/util/Util_AppSync.res.mjs +35 -0
- package/src/util/Util_AppSync_Caller.res +213 -0
- package/src/util/Util_AppSync_Caller.res.mjs +170 -0
- package/src/util/Util_Bundle.res +255 -0
- package/src/util/Util_Bundle.res.mjs +179 -0
- package/src/util/Util_Cloudwatch.res +14 -0
- package/src/util/Util_Cloudwatch.res.mjs +19 -0
- package/src/util/Util_CognitoGroupUser.res +39 -0
- package/src/util/Util_CognitoGroupUser.res.mjs +32 -0
- package/src/util/Util_CognitoGroupUser_Runtime.res +65 -0
- package/src/util/Util_CognitoGroupUser_Runtime.res.mjs +50 -0
- package/src/util/Util_Cognito_Runtime.res +52 -0
- package/src/util/Util_Cognito_Runtime.res.mjs +35 -0
- package/src/util/Util_DeadLetterQueue.res +154 -0
- package/src/util/Util_DeadLetterQueue.res.mjs +158 -0
- package/src/util/Util_DynamoDb.res +210 -0
- package/src/util/Util_DynamoDb.res.mjs +218 -0
- package/src/util/Util_DynamoDbStream.res +138 -0
- package/src/util/Util_DynamoDbStream.res.mjs +134 -0
- package/src/util/Util_DynamoDbStream_Runtime.res +94 -0
- package/src/util/Util_DynamoDbStream_Runtime.res.mjs +131 -0
- package/src/util/Util_DynamoDb_Runtime.res +216 -0
- package/src/util/Util_DynamoDb_Runtime.res.mjs +257 -0
- package/src/util/Util_DynamoDb_TableManager.res +23 -0
- package/src/util/Util_DynamoDb_TableManager.res.mjs +35 -0
- package/src/util/Util_DynamoDb_TableManager.resi +3 -0
- package/src/util/Util_Env.res +5 -0
- package/src/util/Util_Env.res.mjs +2 -0
- package/src/util/Util_EventSourceMapping.res +49 -0
- package/src/util/Util_EventSourceMapping.res.mjs +32 -0
- package/src/util/Util_HostUiDomain.res +28 -0
- package/src/util/Util_HostUiDomain.res.mjs +26 -0
- package/src/util/Util_IAM_Role.res +14 -0
- package/src/util/Util_IAM_Role.res.mjs +28 -0
- package/src/util/Util_Kinesis_Runtime.res +20 -0
- package/src/util/Util_Kinesis_Runtime.res.mjs +24 -0
- package/src/util/Util_Lambda.res +39 -0
- package/src/util/Util_Lambda.res.mjs +45 -0
- package/src/util/Util_LocalConfig.res +119 -0
- package/src/util/Util_LocalConfig.res.mjs +112 -0
- package/src/util/Util_ResourceNaming.res +15 -0
- package/src/util/Util_ResourceNaming.res.mjs +26 -0
- package/src/util/Util_S3.res +17 -0
- package/src/util/Util_S3.res.mjs +30 -0
- package/src/util/Util_S3_Runtime.res +11 -0
- package/src/util/Util_S3_Runtime.res.mjs +15 -0
- package/src/util/Util_SNS.res +33 -0
- package/src/util/Util_SNS.res.mjs +50 -0
- package/src/util/Util_SNS_FIFO.res +21 -0
- package/src/util/Util_SNS_FIFO.res.mjs +27 -0
- package/src/util/Util_SNS_Runtime.res +33 -0
- package/src/util/Util_SNS_Runtime.res.mjs +27 -0
- package/src/util/Util_SQS.res +70 -0
- package/src/util/Util_SQS.res.mjs +83 -0
- package/src/util/Util_SQS_FIFO.res +16 -0
- package/src/util/Util_SQS_FIFO.res.mjs +28 -0
- package/src/util/Util_SQS_Runtime.res +169 -0
- package/src/util/Util_SQS_Runtime.res.mjs +150 -0
- package/src/util/Util_SesPolicy_Runtime.res +54 -0
- package/src/util/Util_SesPolicy_Runtime.res.mjs +55 -0
- package/src/util/Util_StaticBundle.res +124 -0
- package/src/util/Util_StaticBundle.res.mjs +132 -0
- package/src/util/Util_Vpc.res +22 -0
- package/src/util/Util_Vpc.res.mjs +27 -0
- package/tests/AppSync_AdapterTest.res +396 -0
- package/tests/AppSync_AdapterTest.res.mjs +326 -0
- package/tests/AppSync_Resolver_RetryingTest.res +59 -0
- package/tests/AppSync_Resolver_RetryingTest.res.mjs +66 -0
- package/tests/Auth_CognitoTest.res +203 -0
- package/tests/Auth_CognitoTest.res.mjs +248 -0
- package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res +602 -0
- package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res.mjs +742 -0
- package/tests/EventLogStorage_DynamoDb_RuntimeTest.res +57 -0
- package/tests/EventLogStorage_DynamoDb_RuntimeTest.res.mjs +68 -0
- package/tests/MCP_LambdaTest.res +101 -0
- package/tests/MCP_LambdaTest.res.mjs +56 -0
- package/tests/Util_HostUiDomainTest.res +90 -0
- package/tests/Util_HostUiDomainTest.res.mjs +50 -0
- package/tests/Util_SQS_RuntimeTest.res +46 -0
- package/tests/Util_SQS_RuntimeTest.res.mjs +45 -0
- package/tests/Util_StaticBundleTest.res +136 -0
- package/tests/Util_StaticBundleTest.res.mjs +149 -0
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +101 -0
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res.mjs +91 -0
- package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +315 -0
- package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res.mjs +435 -0
- package/tests/integration/DcbIntegrationHarness.res +102 -0
- package/tests/integration/DcbIntegrationHarness.res.mjs +163 -0
- package/tests/integration/EpTestSlice.res +28 -0
- package/tests/integration/EpTestSlice.res.mjs +43 -0
- package/tests/integration/EpTestSliceBehavior.res +18 -0
- package/tests/integration/EpTestSliceBehavior.res.mjs +35 -0
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
// AWS MCP adapter — Lambda Function URL with Streamable HTTP transport.
|
|
2
|
+
//
|
|
3
|
+
// Deploy-time: creates a Lambda function bundled with @modelcontextprotocol/sdk
|
|
4
|
+
// and a Function URL for Streamable HTTP access.
|
|
5
|
+
//
|
|
6
|
+
// Runtime: the Lambda handler parses MCP protocol requests, routes tool calls
|
|
7
|
+
// to SQS CommandTopics and resource reads to DynamoDB QueryDbs — the same
|
|
8
|
+
// backend as AppSync resolvers. Event history resources read directly from
|
|
9
|
+
// EventLog and DcbEventLog DynamoDB tables.
|
|
10
|
+
//
|
|
11
|
+
// NOTE: Lambda Function URL bindings for rescript-pulumi-aws are not yet
|
|
12
|
+
// available. This module provides the runtime MCP server handler that will
|
|
13
|
+
// be deployed once the Pulumi bindings are added. The deploy-time infrastructure
|
|
14
|
+
// (Lambda + Function URL + IAM role) is documented but not yet wired to Pulumi.
|
|
15
|
+
|
|
16
|
+
// ─── Runtime handler ───────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
type mcpToolEntry = {
|
|
19
|
+
name: string,
|
|
20
|
+
description: string,
|
|
21
|
+
inputSchema: JSON.t,
|
|
22
|
+
commandTopicArn: string,
|
|
23
|
+
componentKind: string, // "Aggregate" | "StateChangeSlice"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type mcpResourceEntry = {
|
|
27
|
+
name: string,
|
|
28
|
+
description: string,
|
|
29
|
+
uriTemplate: string,
|
|
30
|
+
queryDbTableName: string,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type mcpEventHistoryEntry = {
|
|
34
|
+
name: string,
|
|
35
|
+
displayName: string,
|
|
36
|
+
tableName: string,
|
|
37
|
+
busKey: string,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type mcpConfig = {
|
|
41
|
+
serverName: string,
|
|
42
|
+
serverVersion: string,
|
|
43
|
+
tools: array<mcpToolEntry>,
|
|
44
|
+
resources: array<mcpResourceEntry>,
|
|
45
|
+
eventHistoryResources: array<mcpEventHistoryEntry>,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Generate the MCP config from plugin schema entries.
|
|
49
|
+
Called at deploy time to produce the config JSON that the Lambda reads
|
|
50
|
+
from its environment variable. */
|
|
51
|
+
let generateConfig = (
|
|
52
|
+
~serverName: string,
|
|
53
|
+
~serverVersion: string,
|
|
54
|
+
~pluginName: string,
|
|
55
|
+
~mutationEntries: array<ReventlessInfra.Api.mutationSchemaEntry>,
|
|
56
|
+
~queryEntries: array<ReventlessInfra.Api.querySchemaEntry>,
|
|
57
|
+
~eventLogEntries: array<ReventlessInfra.Api.eventLogSchemaEntry>=[],
|
|
58
|
+
~commandTopicArns: dict<string>,
|
|
59
|
+
~queryDbTableNames: dict<string>,
|
|
60
|
+
~eventLogTableNames: dict<string>=Dict.make(),
|
|
61
|
+
): mcpConfig => {
|
|
62
|
+
let toolDefs = ReventlessCore.MCP_SchemaGenerator.generateTools(~pluginName, ~mutationEntries)
|
|
63
|
+
// Build a lookup from field name to component kind.
|
|
64
|
+
// Union({anyOf}) schemas are aggregate commands; others are DCB StateChangeSlice commands.
|
|
65
|
+
let kindByField = Dict.make()
|
|
66
|
+
mutationEntries->Array.forEach(entry => {
|
|
67
|
+
let kind = switch entry.commandSchema {
|
|
68
|
+
| Union(_) => "Aggregate"
|
|
69
|
+
| _ => "StateChangeSlice"
|
|
70
|
+
}
|
|
71
|
+
entry.fieldNames->Array.forEach(fieldName => kindByField->Dict.set(fieldName, kind))
|
|
72
|
+
})
|
|
73
|
+
let tools = toolDefs->Array.map(def => {
|
|
74
|
+
name: def.name,
|
|
75
|
+
description: def.description,
|
|
76
|
+
inputSchema: def.inputSchema,
|
|
77
|
+
commandTopicArn: commandTopicArns->Dict.get(def.name)->Option.getOr(""),
|
|
78
|
+
componentKind: kindByField->Dict.get(def.name)->Option.getOr("Aggregate"),
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
let resourceDefs = ReventlessCore.MCP_SchemaGenerator.generateResources(
|
|
82
|
+
~pluginName,
|
|
83
|
+
~queryEntries,
|
|
84
|
+
)
|
|
85
|
+
let resources = resourceDefs->Array.map(def => {
|
|
86
|
+
name: def.name,
|
|
87
|
+
description: def.description,
|
|
88
|
+
uriTemplate: def.uriTemplate,
|
|
89
|
+
queryDbTableName: queryDbTableNames->Dict.get(def.name)->Option.getOr(""),
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
let eventHistoryResources = eventLogEntries->Array.map(entry => {
|
|
93
|
+
let nameLower = entry.displayName->String.toLowerCase
|
|
94
|
+
{
|
|
95
|
+
name: `${nameLower}_events`,
|
|
96
|
+
displayName: entry.displayName,
|
|
97
|
+
tableName: eventLogTableNames->Dict.get(entry.busKey)->Option.getOr(""),
|
|
98
|
+
busKey: entry.busKey,
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
{serverName, serverVersion, tools, resources, eventHistoryResources}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Generate the core-only MCP config for split mode.
|
|
106
|
+
Contains only core administrative tools (Plugin_Activate, Plugin_Deactivate, Clone)
|
|
107
|
+
and core resources (Plugin, Plugins). No plugin-contributed entries.
|
|
108
|
+
|
|
109
|
+
The commandTopicArns and queryDbTableNames must map core field names to their
|
|
110
|
+
corresponding AWS resource ARNs/names. When Lambda Function URL deployment is
|
|
111
|
+
available (Step 13), these will be wired from Pulumi stack outputs. */
|
|
112
|
+
let generateAdminConfig = (
|
|
113
|
+
~serverName: string,
|
|
114
|
+
~serverVersion: string,
|
|
115
|
+
~cloner: bool=false,
|
|
116
|
+
~commandTopicArns: dict<string>=Dict.make(),
|
|
117
|
+
~queryDbTableNames: dict<string>=Dict.make(),
|
|
118
|
+
): mcpConfig =>
|
|
119
|
+
generateConfig(
|
|
120
|
+
~serverName=`${serverName}-admin`,
|
|
121
|
+
~serverVersion,
|
|
122
|
+
~pluginName="Admin",
|
|
123
|
+
~mutationEntries=ReventlessCore.AdminApi.mutationEntries(~cloner),
|
|
124
|
+
~queryEntries=ReventlessCore.PluginBaseFragment.queryEntries,
|
|
125
|
+
~commandTopicArns,
|
|
126
|
+
~queryDbTableNames,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
// ─── URI parsing helpers ─────────────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
/** Extract entity ID from the last path segment (before any query string). */
|
|
132
|
+
let extractEntityId = (uri: string) => {
|
|
133
|
+
let pathPart = (uri->String.split("?"))->Array.getUnsafe(0)
|
|
134
|
+
let segments = pathPart->String.split("/")
|
|
135
|
+
segments->Array.at(-1)->Option.getOr("")
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Parse limit and after pagination params from a URI query string. */
|
|
139
|
+
let parsePaginationParams = (uri: string) => {
|
|
140
|
+
let parts = uri->String.split("?")
|
|
141
|
+
switch parts->Array.get(1) {
|
|
142
|
+
| None => (None, None)
|
|
143
|
+
| Some(qs) =>
|
|
144
|
+
let params = Dict.make()
|
|
145
|
+
qs->String.split("&")->Array.forEach(param => {
|
|
146
|
+
let kv = param->String.split("=")
|
|
147
|
+
switch (kv->Array.get(0), kv->Array.get(1)) {
|
|
148
|
+
| (Some(k), Some(v)) => params->Dict.set(k, v)
|
|
149
|
+
| _ => ()
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
(
|
|
153
|
+
params->Dict.get("limit")->Option.flatMap(v => Int.fromString(v)),
|
|
154
|
+
params->Dict.get("after"),
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Build a paginated response JSON with events and pagination metadata. */
|
|
160
|
+
let paginatedResponse = (
|
|
161
|
+
~events: array<JSON.t>,
|
|
162
|
+
~hasMore: bool,
|
|
163
|
+
~nextAfter: option<string>,
|
|
164
|
+
) =>
|
|
165
|
+
Dict.fromArray([
|
|
166
|
+
("events", events->JSON.Encode.array),
|
|
167
|
+
(
|
|
168
|
+
"pagination",
|
|
169
|
+
Dict.fromArray([
|
|
170
|
+
("hasMore", hasMore->JSON.Encode.bool),
|
|
171
|
+
("nextAfter", nextAfter->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
|
|
172
|
+
])->JSON.Encode.object,
|
|
173
|
+
),
|
|
174
|
+
])->JSON.Encode.object
|
|
175
|
+
|
|
176
|
+
// ─── Runtime event history handlers ──────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
/** Read event history from an EventLog DynamoDB table (aggregate events).
|
|
179
|
+
Uses the existing queryStream infrastructure for lazy DynamoDB pagination
|
|
180
|
+
with Stream.take for efficient limiting. */
|
|
181
|
+
let readEventLogHistory = async (
|
|
182
|
+
~tableName: string,
|
|
183
|
+
~entityId: string,
|
|
184
|
+
~limit: option<int>=?,
|
|
185
|
+
~after: option<string>=?,
|
|
186
|
+
) => {
|
|
187
|
+
let table: Util_DynamoDb_Runtime.resolvedTable = {
|
|
188
|
+
id: "",
|
|
189
|
+
name: tableName,
|
|
190
|
+
arn: "",
|
|
191
|
+
hashKey: "id",
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let expressionAttributeValues = [(":id", entityId->JSON.Encode.string)]->Dict.fromArray
|
|
195
|
+
|
|
196
|
+
let exclusiveStartKey = after->Option.map(afterPos =>
|
|
197
|
+
Dict.fromArray([
|
|
198
|
+
("id", entityId->JSON.Encode.string),
|
|
199
|
+
("position", afterPos->JSON.Encode.string),
|
|
200
|
+
])
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
let stream =
|
|
204
|
+
Util_DynamoDb_Runtime.queryStream({
|
|
205
|
+
tableName: table.name,
|
|
206
|
+
consistentRead: true,
|
|
207
|
+
keyConditionExpression: "id=:id",
|
|
208
|
+
expressionAttributeValues,
|
|
209
|
+
?exclusiveStartKey,
|
|
210
|
+
})
|
|
211
|
+
->Stream.catchAll(err => {
|
|
212
|
+
let _ = DynamoDb_Error.message(err)
|
|
213
|
+
Stream.empty
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
// Fetch limit+1 items to detect hasMore
|
|
217
|
+
let bounded = switch limit {
|
|
218
|
+
| Some(n) => stream->Stream.take(n + 1)
|
|
219
|
+
| None => stream
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
let events = await bounded->Stream.runCollect->Effect.runPromise
|
|
223
|
+
|
|
224
|
+
let (limited, hasMore) = switch limit {
|
|
225
|
+
| Some(n) when events->Array.length > n =>
|
|
226
|
+
(events->Array.slice(~start=0, ~end=n), true)
|
|
227
|
+
| _ => (events, false)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
let nextAfter = if hasMore {
|
|
231
|
+
limited
|
|
232
|
+
->Array.at(-1)
|
|
233
|
+
->Option.flatMap(JSON.Decode.object)
|
|
234
|
+
->Option.flatMap(obj => obj->Dict.get("position"))
|
|
235
|
+
->Option.flatMap(JSON.Decode.string)
|
|
236
|
+
} else {
|
|
237
|
+
None
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
paginatedResponse(~events=limited, ~hasMore, ~nextAfter)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Read event history from a DcbEventLog DynamoDB table.
|
|
244
|
+
Uses the existing DcbEventLog runtime read with tag-based filtering. */
|
|
245
|
+
let readDcbEventLogHistory = async (
|
|
246
|
+
~tableName: string,
|
|
247
|
+
~entityId: string,
|
|
248
|
+
~limit: option<int>=?,
|
|
249
|
+
~after: option<string>=?,
|
|
250
|
+
) => {
|
|
251
|
+
let table: Util_DynamoDb_Runtime.resolvedTable = {
|
|
252
|
+
id: "",
|
|
253
|
+
name: tableName,
|
|
254
|
+
arn: "",
|
|
255
|
+
hashKey: "id",
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
let result = await DcbEventLogStorage_DynamoDb_Runtime.read(table)(
|
|
259
|
+
~query=[],
|
|
260
|
+
~after?,
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
// Filter by entity ID tag value (events matching this entity)
|
|
264
|
+
let filtered = if entityId->String.length > 0 {
|
|
265
|
+
result.events->Array.filter(e => e.tags->Array.some(tag => tag.value == entityId))
|
|
266
|
+
} else {
|
|
267
|
+
result.events
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Apply limit
|
|
271
|
+
let (limited, hasMore) = switch limit {
|
|
272
|
+
| Some(n) when filtered->Array.length > n =>
|
|
273
|
+
(filtered->Array.slice(~start=0, ~end=n), true)
|
|
274
|
+
| _ => (filtered, false)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Serialize events to JSON
|
|
278
|
+
let eventsJson = limited->Array.map(e =>
|
|
279
|
+
Dict.fromArray([
|
|
280
|
+
("position", JSON.Encode.string(e.position)),
|
|
281
|
+
("event", JSON.Encode.string(e.eventType)),
|
|
282
|
+
("data", e.data),
|
|
283
|
+
(
|
|
284
|
+
"tags",
|
|
285
|
+
e.tags
|
|
286
|
+
->Array.map(t =>
|
|
287
|
+
Dict.fromArray([
|
|
288
|
+
("key", JSON.Encode.string(t.key)),
|
|
289
|
+
("value", JSON.Encode.string(t.value)),
|
|
290
|
+
])->JSON.Encode.object
|
|
291
|
+
)
|
|
292
|
+
->JSON.Encode.array,
|
|
293
|
+
),
|
|
294
|
+
])->JSON.Encode.object
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
let nextAfter = if hasMore {
|
|
298
|
+
limited->Array.at(-1)->Option.map(e => e.position)
|
|
299
|
+
} else {
|
|
300
|
+
None
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
paginatedResponse(~events=eventsJson, ~hasMore, ~nextAfter)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// ─── Runtime dispatch ─────────────────────────────────────────────────────
|
|
307
|
+
|
|
308
|
+
@module(
|
|
309
|
+
"@reventlessdev/reventless-core/src/components/CommandGenerator/CommandGenerator_Callback.res.mjs"
|
|
310
|
+
)
|
|
311
|
+
external makeGenerateCommand: (
|
|
312
|
+
ReventlessCore.CommandGenerator.publishJsons,
|
|
313
|
+
string,
|
|
314
|
+
'schema,
|
|
315
|
+
string,
|
|
316
|
+
option<bool>,
|
|
317
|
+
) => ReventlessCore.CommandGenerator.commandGenerator = "makeGenerateCommand"
|
|
318
|
+
|
|
319
|
+
@module(
|
|
320
|
+
"@reventlessdev/reventless-aws/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs"
|
|
321
|
+
)
|
|
322
|
+
external sqsPublishJsons: ('queue, string) => ReventlessCore.CommandGenerator.publishJsons =
|
|
323
|
+
"publishJsons"
|
|
324
|
+
|
|
325
|
+
@module("@reventlessdev/reventless-core/src/RequestContext.res.mjs")
|
|
326
|
+
external requestContextTag: 'a = "tag"
|
|
327
|
+
|
|
328
|
+
@module("effect/Effect")
|
|
329
|
+
external effectProvideService: ('a, 'b) => 'c = "provideService"
|
|
330
|
+
|
|
331
|
+
@send external pipe: ('a, 'b) => 'c = "pipe"
|
|
332
|
+
|
|
333
|
+
let makeQueueRef: string => 'a = %raw(`(url) => ({ id: url, name: url, arn: "" })`)
|
|
334
|
+
|
|
335
|
+
// Decode the payload section of a JWT (base64url → JSON) without signature verification.
|
|
336
|
+
// The Lambda authorizer / API Gateway Cognito authorizer is responsible for verification;
|
|
337
|
+
// the Lambda only needs to read the already-validated claims.
|
|
338
|
+
let decodeJwtClaims: string => option<'a> = %raw(`
|
|
339
|
+
function(token) {
|
|
340
|
+
try {
|
|
341
|
+
var parts = token.split(".");
|
|
342
|
+
if (parts.length < 2) return undefined;
|
|
343
|
+
var base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
344
|
+
var json = Buffer.from(base64, "base64").toString("utf8");
|
|
345
|
+
return JSON.parse(json);
|
|
346
|
+
} catch(_) { return undefined; }
|
|
347
|
+
}
|
|
348
|
+
`)
|
|
349
|
+
|
|
350
|
+
/** Extract a Cognito Identity from a Bearer token in the Authorization header.
|
|
351
|
+
Falls back to Identity.anonymous when the header is absent or the token is malformed. */
|
|
352
|
+
let extractIdentity = (authHeader: option<string>): Reventless.Identity.t =>
|
|
353
|
+
switch authHeader {
|
|
354
|
+
| None => Reventless.Identity.anonymous
|
|
355
|
+
| Some(header) =>
|
|
356
|
+
let token = if header->String.startsWith("Bearer ") {
|
|
357
|
+
header->String.slice(~start=7)
|
|
358
|
+
} else {
|
|
359
|
+
header
|
|
360
|
+
}
|
|
361
|
+
switch decodeJwtClaims(token) {
|
|
362
|
+
| None => Reventless.Identity.anonymous
|
|
363
|
+
| Some(claims) =>
|
|
364
|
+
let claimsDict: dict<JSON.t> = claims->Obj.magic
|
|
365
|
+
let userId =
|
|
366
|
+
claimsDict->Dict.get("sub")->Option.flatMap(JSON.Decode.string)->Option.getOr("anonymous")
|
|
367
|
+
let username =
|
|
368
|
+
claimsDict
|
|
369
|
+
->Dict.get("cognito:username")
|
|
370
|
+
->Option.orElse(claimsDict->Dict.get("username"))
|
|
371
|
+
->Option.flatMap(JSON.Decode.string)
|
|
372
|
+
->Option.getOr(userId)
|
|
373
|
+
let groups: array<string> =
|
|
374
|
+
claimsDict
|
|
375
|
+
->Dict.get("cognito:groups")
|
|
376
|
+
->Option.map(g => g->Obj.magic)
|
|
377
|
+
->Option.getOr([])
|
|
378
|
+
{
|
|
379
|
+
Reventless.Identity.userId,
|
|
380
|
+
username,
|
|
381
|
+
groups,
|
|
382
|
+
provider: Cognito,
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
let runEffect = (correlationId: option<string>, effect) =>
|
|
388
|
+
effect
|
|
389
|
+
->pipe(
|
|
390
|
+
effectProvideService(
|
|
391
|
+
requestContextTag,
|
|
392
|
+
{"correlationId": correlationId->Option.getOr("unknown")},
|
|
393
|
+
),
|
|
394
|
+
)
|
|
395
|
+
->pipe(Effect.runPromise)
|
|
396
|
+
|
|
397
|
+
/** Dispatch an MCP tool call through makeGenerateCommand so the interceptor hook fires.
|
|
398
|
+
The commandTopicArn from mcpConfig tells us which SQS FIFO queue to target. */
|
|
399
|
+
let dispatchTool = async (
|
|
400
|
+
tool: mcpToolEntry,
|
|
401
|
+
args: JSON.t,
|
|
402
|
+
identity: Reventless.Identity.t,
|
|
403
|
+
) => {
|
|
404
|
+
let queueRef = makeQueueRef(tool.commandTopicArn)
|
|
405
|
+
let publishJsons = sqsPublishJsons(queueRef, AWS.SQS_FIFO.service)
|
|
406
|
+
let generateCommand = makeGenerateCommand(
|
|
407
|
+
publishJsons,
|
|
408
|
+
tool.name,
|
|
409
|
+
S.json->S.castToUnknown,
|
|
410
|
+
tool.componentKind,
|
|
411
|
+
Some(false), // stripIdFromParams=false — id is embedded in args
|
|
412
|
+
)
|
|
413
|
+
let payload: ReventlessCore.CommandGenerator.payload = {
|
|
414
|
+
command: tool.name,
|
|
415
|
+
arguments: args->Obj.magic,
|
|
416
|
+
meta: {ip: [], user: identity.userId, info: `mcp/tools/${tool.name}`},
|
|
417
|
+
identity,
|
|
418
|
+
}
|
|
419
|
+
await runEffect(None, generateCommand(payload))
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// ─── Deploy-time infrastructure (placeholder) ─────────────────────────────
|
|
423
|
+
//
|
|
424
|
+
// When rescript-pulumi-aws gains Lambda Function URL bindings, this section
|
|
425
|
+
// will create:
|
|
426
|
+
//
|
|
427
|
+
// 1. Lambda function (Node.js 20.x runtime)
|
|
428
|
+
// - Handler: mcp-handler.handler
|
|
429
|
+
// - Environment: MCP_CONFIG = JSON.stringify(config)
|
|
430
|
+
// - Bundled dependencies: @modelcontextprotocol/sdk, zod
|
|
431
|
+
//
|
|
432
|
+
// 2. Lambda Function URL
|
|
433
|
+
// - Auth type: AWS_IAM (for Cognito/IAM auth) or NONE (for public access)
|
|
434
|
+
// - CORS: configurable origin whitelist
|
|
435
|
+
// - Invoke mode: RESPONSE_STREAM (for SSE support)
|
|
436
|
+
//
|
|
437
|
+
// 3. IAM Role
|
|
438
|
+
// - sqs:SendMessage on all registered CommandTopic queues
|
|
439
|
+
// - dynamodb:GetItem, dynamodb:Query on all registered QueryDb tables
|
|
440
|
+
// - dynamodb:Query on all registered EventLog tables (event history)
|
|
441
|
+
// - dynamodb:Query on all registered DcbEventLog tables + GSIs (event history)
|
|
442
|
+
//
|
|
443
|
+
// The Lambda handler code would:
|
|
444
|
+
// - Read MCP_CONFIG from environment
|
|
445
|
+
// - Create an MCP Server instance with registered tools and resources
|
|
446
|
+
// - Tool handlers: SQS.sendMessage to the command topic ARN
|
|
447
|
+
// - Resource handlers: DynamoDB.getItem/query on the table
|
|
448
|
+
// - Event history handlers: readEventLogHistory / readDcbEventLogHistory
|
|
449
|
+
// - Use StreamableHTTPServerTransport with the Lambda response stream
|
|
450
|
+
|
|
451
|
+
// ─── Auth and rate limiting configuration ────────────────────────────────
|
|
452
|
+
//
|
|
453
|
+
// MCP 1.0 standardizes on OAuth 2.0. The Lambda Function URL validates JWT
|
|
454
|
+
// tokens from the Authorization header using the same Cognito User Pool as
|
|
455
|
+
// AppSync.
|
|
456
|
+
|
|
457
|
+
/** Authentication mode for the Lambda Function URL. */
|
|
458
|
+
type authType =
|
|
459
|
+
| /** AWS IAM auth — callers sign requests with SigV4. Suitable for
|
|
460
|
+
service-to-service or Cognito identity pool access. */
|
|
461
|
+
AwsIam
|
|
462
|
+
| /** No auth — the Function URL is publicly accessible. Suitable for
|
|
463
|
+
development or when auth is handled at a different layer (API Gateway). */
|
|
464
|
+
None
|
|
465
|
+
|
|
466
|
+
/** Per-tool authorization scope. Tools can require specific Cognito groups
|
|
467
|
+
or OAuth scopes before execution. */
|
|
468
|
+
type toolScope = {
|
|
469
|
+
/** Tool name (must match a registered tool). */
|
|
470
|
+
toolName: string,
|
|
471
|
+
/** Required Cognito groups — the caller must belong to at least one. */
|
|
472
|
+
requiredGroups?: array<string>,
|
|
473
|
+
/** Required OAuth scopes — the caller's token must include at least one. */
|
|
474
|
+
requiredScopes?: array<string>,
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/** Rate limiting configuration (coarse, via Lambda reserved concurrency). */
|
|
478
|
+
type rateLimitConfig = {
|
|
479
|
+
/** Maximum concurrent Lambda executions for the MCP endpoint. */
|
|
480
|
+
reservedConcurrency?: int,
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/** Full MCP deployment configuration for AWS. */
|
|
484
|
+
type deployConfig = {
|
|
485
|
+
/** Authentication mode for the Function URL. */
|
|
486
|
+
authType: authType,
|
|
487
|
+
/** CORS allowed origins (e.g., ["https://app.example.com"]). */
|
|
488
|
+
corsOrigins?: array<string>,
|
|
489
|
+
/** Per-tool authorization scopes. */
|
|
490
|
+
toolScopes?: array<toolScope>,
|
|
491
|
+
/** Rate limiting configuration. */
|
|
492
|
+
rateLimit?: rateLimitConfig,
|
|
493
|
+
/** When true, only Resources are registered — no Tools. Useful for
|
|
494
|
+
conservative initial rollout. */
|
|
495
|
+
readOnly?: bool,
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Placeholder type for the deploy-time component output.
|
|
499
|
+
type outputs = {
|
|
500
|
+
functionUrl: Pulumi.Output.t<string>,
|
|
501
|
+
lambdaArn: Pulumi.Output.t<string>,
|
|
502
|
+
}
|