@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,439 @@
|
|
|
1
|
+
let log = ReventlessCore.Logger.fromEnv()
|
|
2
|
+
|
|
3
|
+
// AWS managed cache policy — CachingOptimized (GET/HEAD, no query strings/cookies).
|
|
4
|
+
// Suited for hashed asset chunks whose URL changes on every build.
|
|
5
|
+
let cachingOptimizedPolicyId = "658327ea-f89d-4fab-a63d-7e88639e58f6"
|
|
6
|
+
|
|
7
|
+
// AWS managed cache policy — CachingDisabled (TTL 0). Used for unhashed entry
|
|
8
|
+
// points (`index.html`, `remoteEntry.js`, `config.json`) so a fresh `pulumi up`
|
|
9
|
+
// always surfaces the new manifest/config without a manual invalidation.
|
|
10
|
+
let cachingDisabledPolicyId = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
|
|
11
|
+
|
|
12
|
+
type bundleDistribution = {
|
|
13
|
+
distributionUrl: Pulumi.Output.t<string>,
|
|
14
|
+
bucketName: Pulumi.Output.t<string>,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Custom-domain config for a UI bundle's CloudFront distribution. When
|
|
18
|
+
// supplied, the bundle is served at `https://${fqdn}` instead of the default
|
|
19
|
+
// `*.cloudfront.net`. The framework provisions an ACM cert (us-east-1, as
|
|
20
|
+
// CloudFront requires), the DNS-01 validation records, and a Route53 A-alias
|
|
21
|
+
// pointing the FQDN at the distribution. The caller owns the Route53 zone.
|
|
22
|
+
type customDomain = {
|
|
23
|
+
fqdn: string,
|
|
24
|
+
hostedZoneId: string,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// CloudFront's global hosted zone ID for A/AAAA alias records — a fixed
|
|
28
|
+
// constant published by AWS. Used as the target zone when pointing a Route53
|
|
29
|
+
// record at any CloudFront distribution; not the distribution's own
|
|
30
|
+
// `hostedZoneId` output (which is meant for other Pulumi consumers).
|
|
31
|
+
let cloudFrontAliasZoneId = "Z2FDTNDATAQYW2"
|
|
32
|
+
|
|
33
|
+
// Lazy module-level us-east-1 Provider singleton. ACM certs consumed by
|
|
34
|
+
// CloudFront must live in us-east-1 regardless of the stack's primary
|
|
35
|
+
// region; sharing one provider across every UI bundle in the stack keeps the
|
|
36
|
+
// resource graph tidy. The singleton survives the whole Pulumi run because
|
|
37
|
+
// makeUiBundleDistribution may be invoked several times (host shell + future
|
|
38
|
+
// per-plugin SPAs) in a single deploy.
|
|
39
|
+
let _usEast1Provider: ref<option<PulumiAws.Aws.Provider.t>> = ref(None)
|
|
40
|
+
let _getUsEast1Provider = (): PulumiAws.Aws.Provider.t =>
|
|
41
|
+
switch _usEast1Provider.contents {
|
|
42
|
+
| Some(p) => p
|
|
43
|
+
| None =>
|
|
44
|
+
let p = PulumiAws.Aws.Provider.make(
|
|
45
|
+
~name="us-east-1",
|
|
46
|
+
~args={region: Pulumi.Input.make("us-east-1")},
|
|
47
|
+
)
|
|
48
|
+
_usEast1Provider := Some(p)
|
|
49
|
+
p
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ── Cache-Control ───────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
// Cache-Control for a bundle file. Vite emits content-hashed chunks under
|
|
55
|
+
// `assets/` whose URL changes whenever their content does, so they are safe to
|
|
56
|
+
// cache forever. Everything else is a STABLE-named entry point — `index.html`,
|
|
57
|
+
// the module-federation `mf-entry-bootstrap-*.js`, import maps, JSON — whose
|
|
58
|
+
// content changes IN PLACE across deploys, so it must always revalidate. Without
|
|
59
|
+
// `no-cache` here a redeploy uploads the new entry file to S3 while CloudFront
|
|
60
|
+
// (and browsers) keep serving the previous build: the "deployed but stale" trap.
|
|
61
|
+
let cacheControlFor = (relativePath: string): string =>
|
|
62
|
+
relativePath->String.startsWith("assets/")
|
|
63
|
+
? "public, max-age=31536000, immutable"
|
|
64
|
+
: "no-cache"
|
|
65
|
+
|
|
66
|
+
// ── Inline CloudFront SDK binding (deploy-time cache invalidation) ───────────
|
|
67
|
+
// Mirrors AppSync_Adapter's inline `@aws-sdk` binding pattern. Runs in the
|
|
68
|
+
// Pulumi deploy process (not a Lambda) with the deploy's ambient credentials.
|
|
69
|
+
|
|
70
|
+
type cloudFrontClient
|
|
71
|
+
type cfPaths = {
|
|
72
|
+
@as("Quantity") quantity: int,
|
|
73
|
+
@as("Items") items: array<string>,
|
|
74
|
+
}
|
|
75
|
+
type cfInvalidationBatch = {
|
|
76
|
+
@as("CallerReference") callerReference: string,
|
|
77
|
+
@as("Paths") paths: cfPaths,
|
|
78
|
+
}
|
|
79
|
+
type createInvalidationInput = {
|
|
80
|
+
@as("DistributionId") distributionId: string,
|
|
81
|
+
@as("InvalidationBatch") invalidationBatch: cfInvalidationBatch,
|
|
82
|
+
}
|
|
83
|
+
type createInvalidationCommand
|
|
84
|
+
|
|
85
|
+
@module("@aws-sdk/client-cloudfront") @new
|
|
86
|
+
external makeCloudFrontClient: unit => cloudFrontClient = "CloudFrontClient"
|
|
87
|
+
@module("@aws-sdk/client-cloudfront") @new
|
|
88
|
+
external makeCreateInvalidationCommand: createInvalidationInput => createInvalidationCommand =
|
|
89
|
+
"CreateInvalidationCommand"
|
|
90
|
+
@send external cfSend: (cloudFrontClient, createInvalidationCommand) => promise<unknown> = "send"
|
|
91
|
+
|
|
92
|
+
// Best-effort CloudFront invalidation. Submits the batch (resolves once AWS
|
|
93
|
+
// accepts it — we do not wait for it to reach Completed) and never throws: a
|
|
94
|
+
// failed invalidation must not fail the deploy.
|
|
95
|
+
let invalidateDistribution = async (~distributionId: string, ~paths: array<string>): unit => {
|
|
96
|
+
try {
|
|
97
|
+
let client = makeCloudFrontClient()
|
|
98
|
+
let input = {
|
|
99
|
+
distributionId,
|
|
100
|
+
invalidationBatch: {
|
|
101
|
+
callerReference: "reventless-" ++ Date.now()->Float.toString,
|
|
102
|
+
paths: {quantity: paths->Array.length, items: paths},
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
let _ = await client->cfSend(input->makeCreateInvalidationCommand)
|
|
106
|
+
log.info(~comp="makeUiBundleDistribution", `CloudFront invalidation submitted for ${distributionId}`)
|
|
107
|
+
} catch {
|
|
108
|
+
| exn =>
|
|
109
|
+
let msg = exn->JsExn.fromException->Option.flatMap(JsExn.message)->Option.getOr("unknown")
|
|
110
|
+
log.info(~comp="makeUiBundleDistribution", `CloudFront invalidation skipped (${msg})`)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Provision an S3 bucket + CloudFront distribution for a UI bundle. When
|
|
116
|
+
* `~assetsDir` is supplied, every file under it is uploaded as a `BucketObject`
|
|
117
|
+
* with the correct MIME type and an etag derived from the file's SHA-256 so
|
|
118
|
+
* Pulumi only re-uploads files that actually changed. When `~spaFallback=true`,
|
|
119
|
+
* CloudFront 403/404 responses fall back to the index document so client-side
|
|
120
|
+
* routes resolve correctly on first paint.
|
|
121
|
+
*
|
|
122
|
+
* Recommended call site for a SPA bundle:
|
|
123
|
+
* ```rescript
|
|
124
|
+
* let { distributionUrl } = Plugin_Stack.makeUiBundleDistribution(
|
|
125
|
+
* ~pluginId="my-console-bundle",
|
|
126
|
+
* ~bundleVersion="1.0.0",
|
|
127
|
+
* ~assetsDir=projectRoot ++ "/../../bundles/my-console/dist",
|
|
128
|
+
* ~spaFallback=true,
|
|
129
|
+
* )
|
|
130
|
+
* ```
|
|
131
|
+
*
|
|
132
|
+
* The caller must build the bundle (`vite build` or equivalent) before
|
|
133
|
+
* `pulumi up`. Supplying `~assetsDir` for a missing or empty directory
|
|
134
|
+
* fails fast with a clear error message.
|
|
135
|
+
*/
|
|
136
|
+
let makeUiBundleDistribution = (
|
|
137
|
+
~pluginId: string,
|
|
138
|
+
~bundleVersion: string,
|
|
139
|
+
~assetsDir: option<string>=?,
|
|
140
|
+
~spaFallback: bool=false,
|
|
141
|
+
~indexDocument: string="index.html",
|
|
142
|
+
~stableName: bool=false,
|
|
143
|
+
~excludeFiles: array<string>=[],
|
|
144
|
+
~customDomain: option<customDomain>=?,
|
|
145
|
+
): bundleDistribution => {
|
|
146
|
+
// When stableName=true, Pulumi resource names omit bundleVersion so every
|
|
147
|
+
// deploy updates the same bucket + CloudFront distribution in place. The
|
|
148
|
+
// public CloudFront domain stays the same across releases. Per-file etags
|
|
149
|
+
// still drive BucketObject diffs, and obsolete objects are removed when
|
|
150
|
+
// their Pulumi resource disappears from state.
|
|
151
|
+
//
|
|
152
|
+
// When false (the default), bundleVersion is baked into every resource name,
|
|
153
|
+
// so each release provisions a fresh bucket + distribution — useful for
|
|
154
|
+
// plugin UI bundles whose URLs are resolved at runtime through the host
|
|
155
|
+
// shell, where blue/green between versions is wanted.
|
|
156
|
+
let name = stableName ? pluginId : pluginId ++ "-" ++ bundleVersion
|
|
157
|
+
|
|
158
|
+
let bucket = PulumiAws.S3.Bucket.make(~name=name ++ "-bundle")
|
|
159
|
+
|
|
160
|
+
let _ = PulumiAws.S3.BucketPublicAccessBlock.make(
|
|
161
|
+
~name=name ++ "-bundle-pab",
|
|
162
|
+
~args={
|
|
163
|
+
bucket: bucket.id->Pulumi.Output.asInput,
|
|
164
|
+
blockPublicAcls: Pulumi.Input.make(true),
|
|
165
|
+
blockPublicPolicy: Pulumi.Input.make(true),
|
|
166
|
+
ignorePublicAcls: Pulumi.Input.make(true),
|
|
167
|
+
restrictPublicBuckets: Pulumi.Input.make(true),
|
|
168
|
+
},
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
let oac = PulumiAws.CloudFront.OriginAccessControl.make(
|
|
172
|
+
~name=name ++ "-oac",
|
|
173
|
+
~args={
|
|
174
|
+
originAccessControlOriginType: Pulumi.Input.make("s3"),
|
|
175
|
+
signingBehavior: Pulumi.Input.make("always"),
|
|
176
|
+
signingProtocol: Pulumi.Input.make("sigv4"),
|
|
177
|
+
},
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
let originId = pluginId ++ "-s3"
|
|
181
|
+
|
|
182
|
+
let customErrorResponses = spaFallback
|
|
183
|
+
? [
|
|
184
|
+
{
|
|
185
|
+
PulumiAws.CloudFront.Distribution.errorCode: Pulumi.Input.make(403),
|
|
186
|
+
responseCode: Pulumi.Input.make(200),
|
|
187
|
+
responsePagePath: Pulumi.Input.make("/" ++ indexDocument),
|
|
188
|
+
errorCachingMinTtl: Pulumi.Input.make(0),
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
errorCode: Pulumi.Input.make(404),
|
|
192
|
+
responseCode: Pulumi.Input.make(200),
|
|
193
|
+
responsePagePath: Pulumi.Input.make("/" ++ indexDocument),
|
|
194
|
+
errorCachingMinTtl: Pulumi.Input.make(0),
|
|
195
|
+
},
|
|
196
|
+
]
|
|
197
|
+
: []
|
|
198
|
+
|
|
199
|
+
// Pin paths that must never be cached at the CDN edge to the CachingDisabled
|
|
200
|
+
// policy. Always cover `remoteEntry.js` (federation manifest) and, for SPA
|
|
201
|
+
// shells, `index.html` + `config.json`. Hashed assets fall through to the
|
|
202
|
+
// CachingOptimized default behavior since their URL changes on every build.
|
|
203
|
+
let noCacheBehavior = (pattern: string): PulumiAws.CloudFront.Distribution.orderedCacheBehavior => {
|
|
204
|
+
pathPattern: Pulumi.Input.make(pattern),
|
|
205
|
+
targetOriginId: Pulumi.Input.make(originId),
|
|
206
|
+
viewerProtocolPolicy: Pulumi.Input.make("redirect-to-https"),
|
|
207
|
+
allowedMethods: Pulumi.Input.make(["GET", "HEAD"]),
|
|
208
|
+
cachedMethods: Pulumi.Input.make(["GET", "HEAD"]),
|
|
209
|
+
cachePolicyId: Pulumi.Input.make(cachingDisabledPolicyId),
|
|
210
|
+
}
|
|
211
|
+
let orderedCacheBehaviors = Array.concat(
|
|
212
|
+
[noCacheBehavior("/remoteEntry.js")],
|
|
213
|
+
spaFallback ? [noCacheBehavior("/" ++ indexDocument), noCacheBehavior("/config.json")] : [],
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
// Custom-domain provisioning. When `customDomain` is supplied the bundle is
|
|
217
|
+
// served at `https://${fqdn}`: the framework creates an ACM cert in us-east-1
|
|
218
|
+
// (CloudFront only consumes us-east-1 certs), the DNS-01 validation record in
|
|
219
|
+
// the caller's hosted zone, a CertificateValidation that blocks until ACM
|
|
220
|
+
// issues the cert, and a Route53 A-alias from the FQDN to the distribution.
|
|
221
|
+
// When `None`, the cloudfront.net default URL is retained — no extra resources.
|
|
222
|
+
//
|
|
223
|
+
// Resource names below intentionally omit `bundleVersion`: the cert + alias
|
|
224
|
+
// outlive a single deploy, so they must be stable across releases (unlike the
|
|
225
|
+
// bucket / objects which already carry `bundleVersion` for cache-busting).
|
|
226
|
+
let viewerCertificate: PulumiAws.CloudFront.Distribution.viewerCertificate = switch customDomain {
|
|
227
|
+
| None => {
|
|
228
|
+
cloudfrontDefaultCertificate: Pulumi.Input.make(true),
|
|
229
|
+
}
|
|
230
|
+
| Some({fqdn, hostedZoneId}) =>
|
|
231
|
+
let usEast1 = _getUsEast1Provider()
|
|
232
|
+
let cert = PulumiAws.Acm.Certificate.make(
|
|
233
|
+
~name=pluginId ++ "-domain-cert",
|
|
234
|
+
~args={
|
|
235
|
+
domainName: Pulumi.Input.make(fqdn),
|
|
236
|
+
validationMethod: Pulumi.Input.make("DNS"),
|
|
237
|
+
},
|
|
238
|
+
~opts={provider: usEast1},
|
|
239
|
+
)
|
|
240
|
+
let firstValidationOption =
|
|
241
|
+
cert.domainValidationOptions->Pulumi.Output.apply(opts => opts->Array.getUnsafe(0))
|
|
242
|
+
let validationRecord = PulumiAws.Route53.Record.make(
|
|
243
|
+
~name=pluginId ++ "-domain-validation-record",
|
|
244
|
+
~args={
|
|
245
|
+
zoneId: Pulumi.Input.make(hostedZoneId),
|
|
246
|
+
name: firstValidationOption
|
|
247
|
+
->Pulumi.Output.apply(o => o.resourceRecordName)
|
|
248
|
+
->Pulumi.Output.asInput,
|
|
249
|
+
type_: firstValidationOption
|
|
250
|
+
->Pulumi.Output.apply(o => o.resourceRecordType)
|
|
251
|
+
->Pulumi.Output.asInput,
|
|
252
|
+
ttl: Pulumi.Input.make(60),
|
|
253
|
+
records: firstValidationOption
|
|
254
|
+
->Pulumi.Output.apply(o => [o.resourceRecordValue])
|
|
255
|
+
->Pulumi.Output.asInput,
|
|
256
|
+
// ACM renewals reuse the same validation token, so the record is
|
|
257
|
+
// stable. allowOverwrite avoids spurious "record already exists"
|
|
258
|
+
// errors on redeploys where the in-state record was wiped manually.
|
|
259
|
+
allowOverwrite: Pulumi.Input.make(true),
|
|
260
|
+
},
|
|
261
|
+
)
|
|
262
|
+
let validated = PulumiAws.Acm.CertificateValidation.make(
|
|
263
|
+
~name=pluginId ++ "-domain-cert-validation",
|
|
264
|
+
~args={
|
|
265
|
+
certificateArn: cert.arn->Pulumi.Output.asInput,
|
|
266
|
+
validationRecordFqdns: [validationRecord.fqdn]
|
|
267
|
+
->Pulumi.Output.all
|
|
268
|
+
->Pulumi.Output.asInput,
|
|
269
|
+
},
|
|
270
|
+
~opts={provider: usEast1},
|
|
271
|
+
)
|
|
272
|
+
{
|
|
273
|
+
acmCertificateArn: validated.certificateArn->Pulumi.Output.asInput,
|
|
274
|
+
sslSupportMethod: Pulumi.Input.make("sni-only"),
|
|
275
|
+
minimumProtocolVersion: Pulumi.Input.make("TLSv1.2_2021"),
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
let distribution = PulumiAws.CloudFront.Distribution.make(
|
|
280
|
+
~name=name ++ "-cdn",
|
|
281
|
+
~args={
|
|
282
|
+
enabled: Pulumi.Input.make(true),
|
|
283
|
+
aliases: ?switch customDomain {
|
|
284
|
+
| None => None
|
|
285
|
+
| Some({fqdn}) => Some(Pulumi.Input.make([fqdn]))
|
|
286
|
+
},
|
|
287
|
+
origins: (bucket.bucketRegionalDomainName, oac.id)
|
|
288
|
+
->Pulumi.Output.all2
|
|
289
|
+
->Pulumi.Output.apply(((domainName, oacId)) =>
|
|
290
|
+
[
|
|
291
|
+
{
|
|
292
|
+
PulumiAws.CloudFront.Distribution.domainName: Pulumi.Input.make(domainName),
|
|
293
|
+
originId: Pulumi.Input.make(originId),
|
|
294
|
+
originAccessControlId: Pulumi.Input.make(oacId),
|
|
295
|
+
},
|
|
296
|
+
]
|
|
297
|
+
)
|
|
298
|
+
->Pulumi.Output.asInput,
|
|
299
|
+
defaultCacheBehavior: Pulumi.Input.make(
|
|
300
|
+
(
|
|
301
|
+
{
|
|
302
|
+
targetOriginId: Pulumi.Input.make(originId),
|
|
303
|
+
viewerProtocolPolicy: Pulumi.Input.make("redirect-to-https"),
|
|
304
|
+
allowedMethods: Pulumi.Input.make(["GET", "HEAD"]),
|
|
305
|
+
cachedMethods: Pulumi.Input.make(["GET", "HEAD"]),
|
|
306
|
+
cachePolicyId: Pulumi.Input.make(cachingOptimizedPolicyId),
|
|
307
|
+
}: PulumiAws.CloudFront.Distribution.defaultCacheBehavior
|
|
308
|
+
),
|
|
309
|
+
),
|
|
310
|
+
orderedCacheBehaviors: Pulumi.Input.make(orderedCacheBehaviors),
|
|
311
|
+
restrictions: Pulumi.Input.make({
|
|
312
|
+
PulumiAws.CloudFront.Distribution.geoRestriction: Pulumi.Input.make({
|
|
313
|
+
PulumiAws.CloudFront.Distribution.restrictionType: Pulumi.Input.make("none"),
|
|
314
|
+
}),
|
|
315
|
+
}),
|
|
316
|
+
viewerCertificate: Pulumi.Input.make(viewerCertificate),
|
|
317
|
+
comment: Pulumi.Input.make(pluginId ++ " UI bundle CDN"),
|
|
318
|
+
defaultRootObject: Pulumi.Input.make(indexDocument),
|
|
319
|
+
customErrorResponses: Pulumi.Input.make(customErrorResponses),
|
|
320
|
+
},
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
// Route53 A-alias from the FQDN to the freshly-created distribution. Lives
|
|
324
|
+
// in the caller's hosted zone (NOT the us-east-1 cert provider's zone — the
|
|
325
|
+
// zone is wherever the caller put it). CloudFront's global alias zone ID is
|
|
326
|
+
// a fixed constant; see `cloudFrontAliasZoneId`.
|
|
327
|
+
switch customDomain {
|
|
328
|
+
| None => ()
|
|
329
|
+
| Some({fqdn, hostedZoneId}) =>
|
|
330
|
+
let _ = PulumiAws.Route53.Record.make(
|
|
331
|
+
~name=pluginId ++ "-domain-alias",
|
|
332
|
+
~args={
|
|
333
|
+
zoneId: Pulumi.Input.make(hostedZoneId),
|
|
334
|
+
name: Pulumi.Input.make(fqdn),
|
|
335
|
+
type_: Pulumi.Input.make("A"),
|
|
336
|
+
aliases: [
|
|
337
|
+
(
|
|
338
|
+
{
|
|
339
|
+
name: distribution.domainName->Pulumi.Output.asInput,
|
|
340
|
+
zoneId: Pulumi.Input.make(cloudFrontAliasZoneId),
|
|
341
|
+
evaluateTargetHealth: Pulumi.Input.make(false),
|
|
342
|
+
}: PulumiAws.Route53.Record.alias
|
|
343
|
+
),
|
|
344
|
+
]->Pulumi.Input.make,
|
|
345
|
+
},
|
|
346
|
+
)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
let _ = PulumiAws.S3.BucketPolicy.make(
|
|
350
|
+
~name=name ++ "-bundle-policy",
|
|
351
|
+
~args={
|
|
352
|
+
bucket: bucket.id->Pulumi.Output.asInput,
|
|
353
|
+
policy: (bucket.arn, distribution.arn)
|
|
354
|
+
->Pulumi.Output.all2
|
|
355
|
+
->Pulumi.Output.apply(((bucketArn, distributionArn)) =>
|
|
356
|
+
{
|
|
357
|
+
"Version": "2012-10-17",
|
|
358
|
+
"Statement": [
|
|
359
|
+
{
|
|
360
|
+
"Sid": "AllowCloudFrontServicePrincipal",
|
|
361
|
+
"Effect": "Allow",
|
|
362
|
+
"Principal": {"Service": "cloudfront.amazonaws.com"},
|
|
363
|
+
"Action": "s3:GetObject",
|
|
364
|
+
"Resource": bucketArn ++ "/*",
|
|
365
|
+
"Condition": {
|
|
366
|
+
"StringEquals": {"AWS:SourceArn": distributionArn},
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
],
|
|
370
|
+
}
|
|
371
|
+
->JSON.stringifyAny
|
|
372
|
+
->Option.getUnsafe
|
|
373
|
+
)
|
|
374
|
+
->Pulumi.Output.asInput,
|
|
375
|
+
},
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
switch assetsDir {
|
|
379
|
+
| None => ()
|
|
380
|
+
| Some(dir) =>
|
|
381
|
+
let allEntries = Util.StaticBundle.walk(dir)
|
|
382
|
+
if allEntries->Array.length == 0 {
|
|
383
|
+
JsError.throwWithMessage(
|
|
384
|
+
`Plugin_Stack.makeUiBundleDistribution: assetsDir is empty: ${dir}`,
|
|
385
|
+
)
|
|
386
|
+
}
|
|
387
|
+
// Drop excluded relative paths before BucketObject creation. Used so the
|
|
388
|
+
// host-shell deploy can skip the dev-mode `public/config.json` it ships
|
|
389
|
+
// with — the explicit Platform.res BucketObject writes the production
|
|
390
|
+
// config to the same S3 key and would otherwise race with the bundle
|
|
391
|
+
// upload (whichever Pulumi applies last wins).
|
|
392
|
+
let entries =
|
|
393
|
+
allEntries->Array.filter(entry => !(excludeFiles->Array.includes(entry.relativePath)))
|
|
394
|
+
let objectEtags =
|
|
395
|
+
entries->Array.map(entry => {
|
|
396
|
+
let obj = PulumiAws.S3.BucketObject.make(
|
|
397
|
+
~name=name ++ "-asset-" ++ Util.StaticBundle.sanitizeName(entry.relativePath),
|
|
398
|
+
~args={
|
|
399
|
+
bucket: bucket.id->Pulumi.Output.asInput,
|
|
400
|
+
key: Pulumi.Input.make(entry.relativePath),
|
|
401
|
+
source: Pulumi.Input.make(entry.fileAsset),
|
|
402
|
+
contentType: Pulumi.Input.make(Util.StaticBundle.contentTypeFor(entry.relativePath)),
|
|
403
|
+
cacheControl: Pulumi.Input.make(cacheControlFor(entry.relativePath)),
|
|
404
|
+
etag: Pulumi.Input.make(entry.contentHash),
|
|
405
|
+
},
|
|
406
|
+
)
|
|
407
|
+
obj.etag
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
// Auto-invalidate CloudFront once every object is (re)uploaded. Stable-named
|
|
411
|
+
// entry files (index.html, the module-federation mf-entry-bootstrap-*.js)
|
|
412
|
+
// are served by the long-TTL default cache behaviour, so without this a
|
|
413
|
+
// `pulumi up` lands the new bundle in S3 while CloudFront keeps serving the
|
|
414
|
+
// prior build until its TTL expires. Chained on the upload etags so it runs
|
|
415
|
+
// AFTER the new content is in S3; `/*` is a single invalidation path (well
|
|
416
|
+
// within CloudFront's free-tier monthly allowance even on frequent deploys).
|
|
417
|
+
let _ =
|
|
418
|
+
(distribution.id, Pulumi.Output.all(objectEtags))
|
|
419
|
+
->Pulumi.Output.all2
|
|
420
|
+
->Pulumi.Output.flatMap(((distId, _etags)) =>
|
|
421
|
+
invalidateDistribution(~distributionId=distId, ~paths=["/*"])->Pulumi.Output.fromPromise
|
|
422
|
+
)
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// When a custom domain is provisioned, return the pretty FQDN URL — the
|
|
426
|
+
// *.cloudfront.net hostname stops accepting requests once `aliases` is set,
|
|
427
|
+
// so the only viable public URL is the FQDN. Downstream consumers
|
|
428
|
+
// (`hostShellUrl` export, host-shell `config.json`) see the pretty URL
|
|
429
|
+
// transparently; no per-call-site change required.
|
|
430
|
+
let distributionUrl = switch customDomain {
|
|
431
|
+
| Some({fqdn}) => Pulumi.Output.make("https://" ++ fqdn)
|
|
432
|
+
| None => distribution.domainName->Pulumi.Output.apply(d => "https://" ++ d)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
{
|
|
436
|
+
distributionUrl,
|
|
437
|
+
bucketName: bucket.bucket,
|
|
438
|
+
}
|
|
439
|
+
}
|