@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.
Files changed (394) hide show
  1. package/CHANGELOG.md +1564 -0
  2. package/README.md +62 -0
  3. package/__mocks__/emptyModule.js +1 -0
  4. package/all-licenses.csv +565 -0
  5. package/docker-compose.dynamodb-local.yml +12 -0
  6. package/jest.setup.cjs +5 -0
  7. package/licenses-analysis.ods +0 -0
  8. package/package.json +73 -0
  9. package/rescript.json +39 -0
  10. package/reventless-licenses-analysis.xls +0 -0
  11. package/scripts/run-integration-tests.sh +43 -0
  12. package/src/Platform.res +1940 -0
  13. package/src/Platform.res.mjs +2281 -0
  14. package/src/Platform_Casts.res +106 -0
  15. package/src/Platform_Casts.res.mjs +13 -0
  16. package/src/Platform_Stack.res +153 -0
  17. package/src/Platform_Stack.res.mjs +121 -0
  18. package/src/Types.res +39 -0
  19. package/src/Types.res.mjs +21 -0
  20. package/src/adapter/AWS.res +96 -0
  21. package/src/adapter/AWS.res.mjs +186 -0
  22. package/src/adapter/AWS_Tags.res +16 -0
  23. package/src/adapter/AWS_Tags.res.mjs +48 -0
  24. package/src/adapter/Adapter_Helpers.res +19 -0
  25. package/src/adapter/Adapter_Helpers.res.mjs +37 -0
  26. package/src/adapter/Api/AppSync_EventsApi.res +172 -0
  27. package/src/adapter/Api/AppSync_EventsApi.res.mjs +96 -0
  28. package/src/adapter/Api/AppSync_Resolver_Native.res +93 -0
  29. package/src/adapter/Api/AppSync_Resolver_Native.res.mjs +67 -0
  30. package/src/adapter/Api/AppSync_Resolver_Retrying.res +653 -0
  31. package/src/adapter/Api/AppSync_Resolver_Retrying.res.mjs +462 -0
  32. package/src/adapter/Api/CommandSubscriptionResolvers_AppSync.res +29 -0
  33. package/src/adapter/Api/CommandSubscriptionResolvers_AppSync.res.mjs +15 -0
  34. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +238 -0
  35. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res.mjs +179 -0
  36. package/src/adapter/Api/Platform_UIFragments_Lambda.res +229 -0
  37. package/src/adapter/Api/Platform_UIFragments_Lambda.res.mjs +245 -0
  38. package/src/adapter/Auth/Auth_Cognito.res +209 -0
  39. package/src/adapter/Auth/Auth_Cognito.res.mjs +135 -0
  40. package/src/adapter/CommandGenerator/CommandGeneratorResolvers.res +2 -0
  41. package/src/adapter/CommandGenerator/CommandGeneratorResolvers.res.mjs +12 -0
  42. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +251 -0
  43. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res.mjs +126 -0
  44. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res +20 -0
  45. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res.mjs +23 -0
  46. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_Runtime.res +1 -0
  47. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_Runtime.res.mjs +11 -0
  48. package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res +95 -0
  49. package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res.mjs +50 -0
  50. package/src/adapter/CommandTopic/CommandTopicChannel.res +6 -0
  51. package/src/adapter/CommandTopic/CommandTopicChannel.res.mjs +21 -0
  52. package/src/adapter/CommandTopic/CommandTopicChannel_Helpers.res +196 -0
  53. package/src/adapter/CommandTopic/CommandTopicChannel_Helpers.res.mjs +145 -0
  54. package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +91 -0
  55. package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res.mjs +74 -0
  56. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +69 -0
  57. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs +62 -0
  58. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +60 -0
  59. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res.mjs +56 -0
  60. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res +73 -0
  61. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs +65 -0
  62. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +88 -0
  63. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs +76 -0
  64. package/src/adapter/CommandTopic/CommandTopicRemoteChannel.res +1 -0
  65. package/src/adapter/CommandTopic/CommandTopicRemoteChannel.res.mjs +9 -0
  66. package/src/adapter/CommandTopic/CommandTopicRemoteChannel_SQS.res +7 -0
  67. package/src/adapter/CommandTopic/CommandTopicRemoteChannel_SQS.res.mjs +17 -0
  68. package/src/adapter/Counter/CounterHandler_DynamoDbStream.res +103 -0
  69. package/src/adapter/Counter/CounterHandler_DynamoDbStream.res.mjs +68 -0
  70. package/src/adapter/Counter/CounterHandler_DynamoDbStream_Runtime.res +107 -0
  71. package/src/adapter/Counter/CounterHandler_DynamoDbStream_Runtime.res.mjs +145 -0
  72. package/src/adapter/DcbEventLog/DcbEventLogStorage.res +1 -0
  73. package/src/adapter/DcbEventLog/DcbEventLogStorage.res.mjs +9 -0
  74. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res +84 -0
  75. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res.mjs +52 -0
  76. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +1436 -0
  77. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res.mjs +1143 -0
  78. package/src/adapter/EventCollector/EventCollectorChannel.res +6 -0
  79. package/src/adapter/EventCollector/EventCollectorChannel.res.mjs +21 -0
  80. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +63 -0
  81. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs +56 -0
  82. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res +20 -0
  83. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res.mjs +32 -0
  84. package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res +266 -0
  85. package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res.mjs +166 -0
  86. package/src/adapter/EventCollector/EventCollectorChannel_SQS.res +81 -0
  87. package/src/adapter/EventCollector/EventCollectorChannel_SQS.res.mjs +54 -0
  88. package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res +59 -0
  89. package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res.mjs +45 -0
  90. package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res +91 -0
  91. package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res.mjs +89 -0
  92. package/src/adapter/EventLog/EventLogStorage.res +3 -0
  93. package/src/adapter/EventLog/EventLogStorage.res.mjs +15 -0
  94. package/src/adapter/EventLog/EventLogStorage_DynamoDb.res +25 -0
  95. package/src/adapter/EventLog/EventLogStorage_DynamoDb.res.mjs +34 -0
  96. package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res +26 -0
  97. package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res.mjs +35 -0
  98. package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res +121 -0
  99. package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res.mjs +137 -0
  100. package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +265 -0
  101. package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res.mjs +185 -0
  102. package/src/adapter/EventTopic/EventTopicPublisher.res +6 -0
  103. package/src/adapter/EventTopic/EventTopicPublisher.res.mjs +21 -0
  104. package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res +25 -0
  105. package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res.mjs +28 -0
  106. package/src/adapter/EventTopic/EventTopicPublisher_SNS.res +40 -0
  107. package/src/adapter/EventTopic/EventTopicPublisher_SNS.res.mjs +39 -0
  108. package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res +39 -0
  109. package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res.mjs +38 -0
  110. package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res +5 -0
  111. package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res.mjs +18 -0
  112. package/src/adapter/Mcp/MCP_Lambda.res +502 -0
  113. package/src/adapter/Mcp/MCP_Lambda.res.mjs +289 -0
  114. package/src/adapter/QueryDb/NodeResolver_AppSync.res +71 -0
  115. package/src/adapter/QueryDb/NodeResolver_AppSync.res.mjs +44 -0
  116. package/src/adapter/QueryDb/QueryDbResolvers.res +2 -0
  117. package/src/adapter/QueryDb/QueryDbResolvers.res.mjs +12 -0
  118. package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res +434 -0
  119. package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res.mjs +243 -0
  120. package/src/adapter/QueryDb/QueryDbResolvers_AppSync_NoOp.res +21 -0
  121. package/src/adapter/QueryDb/QueryDbResolvers_AppSync_NoOp.res.mjs +14 -0
  122. package/src/adapter/QueryDb/QueryDbResolvers_NoOp.res +21 -0
  123. package/src/adapter/QueryDb/QueryDbResolvers_NoOp.res.mjs +14 -0
  124. package/src/adapter/QueryDb/QueryDbStorage.res +5 -0
  125. package/src/adapter/QueryDb/QueryDbStorage.res.mjs +18 -0
  126. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res +115 -0
  127. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res.mjs +100 -0
  128. package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res +52 -0
  129. package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res.mjs +38 -0
  130. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res +271 -0
  131. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res.mjs +306 -0
  132. package/src/adapter/QueryDb/QueryInterceptor_Lambda.res +20 -0
  133. package/src/adapter/QueryDb/QueryInterceptor_Lambda.res.mjs +22 -0
  134. package/src/adapter/QueryEngine/QueryEngine.res +3 -0
  135. package/src/adapter/QueryEngine/QueryEngine.res.mjs +12 -0
  136. package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res +184 -0
  137. package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res.mjs +221 -0
  138. package/src/adapter/Runtime/AdminEventCollectorEntryPoint.mjs +879 -0
  139. package/src/adapter/Runtime/AggregateEntryPoint.mjs +313 -0
  140. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +327 -0
  141. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +239 -0
  142. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +331 -0
  143. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +240 -0
  144. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +247 -0
  145. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +185 -0
  146. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +244 -0
  147. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +185 -0
  148. package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +347 -0
  149. package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +244 -0
  150. package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +285 -0
  151. package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +212 -0
  152. package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +124 -0
  153. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +187 -0
  154. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +147 -0
  155. package/src/adapter/Runtime/CounterEntryPoint.mjs +91 -0
  156. package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +265 -0
  157. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +122 -0
  158. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res.mjs +89 -0
  159. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +193 -0
  160. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +137 -0
  161. package/src/adapter/Runtime/EventMapperEntryPoint.mjs +97 -0
  162. package/src/adapter/Runtime/ExtensionPointEntryPoint.mjs +101 -0
  163. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +83 -0
  164. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res.mjs +59 -0
  165. package/src/adapter/Runtime/HandlerFactoryHelpers.mjs +142 -0
  166. package/src/adapter/Runtime/HeartbeatEntryPoint.mjs +38 -0
  167. package/src/adapter/Runtime/PluginExtensionPointEntryPoint.mjs +137 -0
  168. package/src/adapter/Runtime/ReadModelEntryPoint.mjs +143 -0
  169. package/src/adapter/Runtime/RuntimeEnvironment.res +1 -0
  170. package/src/adapter/Runtime/RuntimeEnvironment.res.mjs +9 -0
  171. package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +254 -0
  172. package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs +169 -0
  173. package/src/adapter/Runtime/SideEffectEntryPoint.mjs +81 -0
  174. package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +178 -0
  175. package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res.mjs +129 -0
  176. package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +166 -0
  177. package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +87 -0
  178. package/src/adapter/Runtime/StateViewSliceEntryPoint.mjs +136 -0
  179. package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +344 -0
  180. package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res.mjs +242 -0
  181. package/src/adapter/Runtime/TaskBucketEntryPoint.mjs +150 -0
  182. package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +123 -0
  183. package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res.mjs +74 -0
  184. package/src/adapter/ScheduledPublisher/ScheduledPublisher.res +2 -0
  185. package/src/adapter/ScheduledPublisher/ScheduledPublisher.res.mjs +12 -0
  186. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +54 -0
  187. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res.mjs +41 -0
  188. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res +97 -0
  189. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res.mjs +85 -0
  190. package/src/adapter/StateTopic/StateTopic_AppSync.res +418 -0
  191. package/src/adapter/StateTopic/StateTopic_AppSync.res.mjs +295 -0
  192. package/src/adapter/Task/TaskBucket.res +1 -0
  193. package/src/adapter/Task/TaskBucket.res.mjs +9 -0
  194. package/src/adapter/Task/TaskBucket_S3.res +157 -0
  195. package/src/adapter/Task/TaskBucket_S3.res.mjs +108 -0
  196. package/src/adapter/Task/TaskBucket_S3_Runtime.res +11 -0
  197. package/src/adapter/Task/TaskBucket_S3_Runtime.res.mjs +15 -0
  198. package/src/components/Aggregate_Builder.res +1 -0
  199. package/src/components/Aggregate_Builder.res.mjs +25 -0
  200. package/src/components/Aggregate_Builder_Micro.res +63 -0
  201. package/src/components/Aggregate_Builder_Micro.res.mjs +80 -0
  202. package/src/components/Aggregate_Builder_NoResolver.res +61 -0
  203. package/src/components/Aggregate_Builder_NoResolver.res.mjs +80 -0
  204. package/src/components/Aggregate_Builder_PerAggregate.res +57 -0
  205. package/src/components/Aggregate_Builder_PerAggregate.res.mjs +80 -0
  206. package/src/components/Aggregate_Builder_Single.res +59 -0
  207. package/src/components/Aggregate_Builder_Single.res.mjs +80 -0
  208. package/src/components/Aggregate_Builder_Single_Async.res +59 -0
  209. package/src/components/Aggregate_Builder_Single_Async.res.mjs +80 -0
  210. package/src/components/Api/AppSync_Adapter.res +500 -0
  211. package/src/components/Api/AppSync_Adapter.res.mjs +396 -0
  212. package/src/components/AutomationSlice_Builder.res +52 -0
  213. package/src/components/AutomationSlice_Builder.res.mjs +72 -0
  214. package/src/components/AutomationSlice_Builder_Bundled.res.mjs +70 -0
  215. package/src/components/Counter_Builder.res +10 -0
  216. package/src/components/Counter_Builder.res.mjs +16 -0
  217. package/src/components/DataCleaner.res +170 -0
  218. package/src/components/DataCleaner.res.mjs +2 -0
  219. package/src/components/DcbEventLog_Builder.res +8 -0
  220. package/src/components/DcbEventLog_Builder.res.mjs +14 -0
  221. package/src/components/ExtensionPoint_Builder.res +16 -0
  222. package/src/components/ExtensionPoint_Builder.res.mjs +37 -0
  223. package/src/components/ForeignReadModel_Builder.res +19 -0
  224. package/src/components/ForeignReadModel_Builder.res.mjs +48 -0
  225. package/src/components/InboundTranslationSlice_Builder.res +25 -0
  226. package/src/components/InboundTranslationSlice_Builder.res.mjs +31 -0
  227. package/src/components/OutboundTranslationSlice_Builder.res +60 -0
  228. package/src/components/OutboundTranslationSlice_Builder.res.mjs +76 -0
  229. package/src/components/OutboundTranslationSlice_Builder_Bundled.res.mjs +75 -0
  230. package/src/components/Plugin.res +29 -0
  231. package/src/components/Plugin.res.mjs +63 -0
  232. package/src/components/ReadModel_Builder.res +1 -0
  233. package/src/components/ReadModel_Builder.res.mjs +19 -0
  234. package/src/components/ReadModel_Builder_NoResolver.res +55 -0
  235. package/src/components/ReadModel_Builder_NoResolver.res.mjs +64 -0
  236. package/src/components/ReadModel_Builder_NoResolver_Stream.res +60 -0
  237. package/src/components/ReadModel_Builder_NoResolver_Stream.res.mjs +64 -0
  238. package/src/components/ReadModel_Builder_PerReadModel.res +53 -0
  239. package/src/components/ReadModel_Builder_PerReadModel.res.mjs +66 -0
  240. package/src/components/ReadModel_Builder_Single.res +52 -0
  241. package/src/components/ReadModel_Builder_Single.res.mjs +66 -0
  242. package/src/components/ReadModel_Builder_Single_Stream.res +60 -0
  243. package/src/components/ReadModel_Builder_Single_Stream.res.mjs +66 -0
  244. package/src/components/Scheduler.res +1 -0
  245. package/src/components/Scheduler.res.mjs +13 -0
  246. package/src/components/SideEffectHandler.res +1 -0
  247. package/src/components/SideEffectHandler.res.mjs +19 -0
  248. package/src/components/SideEffectHandler_PerSideEffectHandler.res +13 -0
  249. package/src/components/SideEffectHandler_PerSideEffectHandler.res.mjs +52 -0
  250. package/src/components/SideEffectHandler_Single.res +54 -0
  251. package/src/components/SideEffectHandler_Single.res.mjs +60 -0
  252. package/src/components/StateChangeSlice_Builder.res +17 -0
  253. package/src/components/StateChangeSlice_Builder.res.mjs +23 -0
  254. package/src/components/StateViewSlice_Builder.res +46 -0
  255. package/src/components/StateViewSlice_Builder.res.mjs +68 -0
  256. package/src/components/StateViewSlice_Builder_Bundled.res.mjs +69 -0
  257. package/src/components/StateViewSlice_Builder_Stream.res +50 -0
  258. package/src/components/StateViewSlice_Builder_Stream.res.mjs +68 -0
  259. package/src/components/Task_Builder.res +1 -0
  260. package/src/components/Task_Builder.res.mjs +28 -0
  261. package/src/components/Task_Builder_PerBucket.res +22 -0
  262. package/src/components/Task_Builder_PerBucket.res.mjs +63 -0
  263. package/src/components/Vpc.res +214 -0
  264. package/src/components/Vpc.res.mjs +117 -0
  265. package/src/components/Vpc.resi +22 -0
  266. package/src/errors/AppSync_Error.res +36 -0
  267. package/src/errors/AppSync_Error.res.mjs +38 -0
  268. package/src/errors/Cognito_Error.res +36 -0
  269. package/src/errors/Cognito_Error.res.mjs +38 -0
  270. package/src/errors/DynamoDb_Error.res +75 -0
  271. package/src/errors/DynamoDb_Error.res.mjs +86 -0
  272. package/src/errors/Kinesis_Error.res +36 -0
  273. package/src/errors/Kinesis_Error.res.mjs +38 -0
  274. package/src/errors/SNS_Error.res +34 -0
  275. package/src/errors/SNS_Error.res.mjs +38 -0
  276. package/src/errors/SQS_Error.res +40 -0
  277. package/src/errors/SQS_Error.res.mjs +41 -0
  278. package/src/plugin/cloner/ClonerRunner.res +1 -0
  279. package/src/plugin/cloner/ClonerRunner.res.mjs +9 -0
  280. package/src/plugin/cloner/ClonerRunner_Fargate.res +362 -0
  281. package/src/plugin/cloner/ClonerRunner_Fargate.res.mjs +246 -0
  282. package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res +42 -0
  283. package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res.mjs +45 -0
  284. package/src/plugin/heartbeat/HeartbeatRunner.res +1 -0
  285. package/src/plugin/heartbeat/HeartbeatRunner.res.mjs +9 -0
  286. package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res +96 -0
  287. package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res.mjs +69 -0
  288. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +115 -0
  289. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs +88 -0
  290. package/src/plugin/runtime/PluginRuntimeOperations.res +5 -0
  291. package/src/plugin/runtime/PluginRuntimeOperations.res.mjs +14 -0
  292. package/src/plugin/runtime/PluginRuntime_Builder.res +769 -0
  293. package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +464 -0
  294. package/src/plugin/runtime/Util_PluginMessage_Runtime.res +13 -0
  295. package/src/plugin/runtime/Util_PluginMessage_Runtime.res.mjs +19 -0
  296. package/src/plugin/stack/Plugin_ExtensionPoint_Builder.res +28 -0
  297. package/src/plugin/stack/Plugin_ExtensionPoint_Builder.res.mjs +67 -0
  298. package/src/plugin/stack/Plugin_Stack.res +439 -0
  299. package/src/plugin/stack/Plugin_Stack.res.mjs +263 -0
  300. package/src/util/Util.res +29 -0
  301. package/src/util/Util.res.mjs +93 -0
  302. package/src/util/Util_AppSync.res +36 -0
  303. package/src/util/Util_AppSync.res.mjs +35 -0
  304. package/src/util/Util_AppSync_Caller.res +213 -0
  305. package/src/util/Util_AppSync_Caller.res.mjs +170 -0
  306. package/src/util/Util_Bundle.res +255 -0
  307. package/src/util/Util_Bundle.res.mjs +179 -0
  308. package/src/util/Util_Cloudwatch.res +14 -0
  309. package/src/util/Util_Cloudwatch.res.mjs +19 -0
  310. package/src/util/Util_CognitoGroupUser.res +39 -0
  311. package/src/util/Util_CognitoGroupUser.res.mjs +32 -0
  312. package/src/util/Util_CognitoGroupUser_Runtime.res +65 -0
  313. package/src/util/Util_CognitoGroupUser_Runtime.res.mjs +50 -0
  314. package/src/util/Util_Cognito_Runtime.res +52 -0
  315. package/src/util/Util_Cognito_Runtime.res.mjs +35 -0
  316. package/src/util/Util_DeadLetterQueue.res +154 -0
  317. package/src/util/Util_DeadLetterQueue.res.mjs +158 -0
  318. package/src/util/Util_DynamoDb.res +210 -0
  319. package/src/util/Util_DynamoDb.res.mjs +218 -0
  320. package/src/util/Util_DynamoDbStream.res +138 -0
  321. package/src/util/Util_DynamoDbStream.res.mjs +134 -0
  322. package/src/util/Util_DynamoDbStream_Runtime.res +94 -0
  323. package/src/util/Util_DynamoDbStream_Runtime.res.mjs +131 -0
  324. package/src/util/Util_DynamoDb_Runtime.res +216 -0
  325. package/src/util/Util_DynamoDb_Runtime.res.mjs +257 -0
  326. package/src/util/Util_DynamoDb_TableManager.res +23 -0
  327. package/src/util/Util_DynamoDb_TableManager.res.mjs +35 -0
  328. package/src/util/Util_DynamoDb_TableManager.resi +3 -0
  329. package/src/util/Util_Env.res +5 -0
  330. package/src/util/Util_Env.res.mjs +2 -0
  331. package/src/util/Util_EventSourceMapping.res +49 -0
  332. package/src/util/Util_EventSourceMapping.res.mjs +32 -0
  333. package/src/util/Util_HostUiDomain.res +28 -0
  334. package/src/util/Util_HostUiDomain.res.mjs +26 -0
  335. package/src/util/Util_IAM_Role.res +14 -0
  336. package/src/util/Util_IAM_Role.res.mjs +28 -0
  337. package/src/util/Util_Kinesis_Runtime.res +20 -0
  338. package/src/util/Util_Kinesis_Runtime.res.mjs +24 -0
  339. package/src/util/Util_Lambda.res +39 -0
  340. package/src/util/Util_Lambda.res.mjs +45 -0
  341. package/src/util/Util_LocalConfig.res +119 -0
  342. package/src/util/Util_LocalConfig.res.mjs +112 -0
  343. package/src/util/Util_ResourceNaming.res +15 -0
  344. package/src/util/Util_ResourceNaming.res.mjs +26 -0
  345. package/src/util/Util_S3.res +17 -0
  346. package/src/util/Util_S3.res.mjs +30 -0
  347. package/src/util/Util_S3_Runtime.res +11 -0
  348. package/src/util/Util_S3_Runtime.res.mjs +15 -0
  349. package/src/util/Util_SNS.res +33 -0
  350. package/src/util/Util_SNS.res.mjs +50 -0
  351. package/src/util/Util_SNS_FIFO.res +21 -0
  352. package/src/util/Util_SNS_FIFO.res.mjs +27 -0
  353. package/src/util/Util_SNS_Runtime.res +33 -0
  354. package/src/util/Util_SNS_Runtime.res.mjs +27 -0
  355. package/src/util/Util_SQS.res +70 -0
  356. package/src/util/Util_SQS.res.mjs +83 -0
  357. package/src/util/Util_SQS_FIFO.res +16 -0
  358. package/src/util/Util_SQS_FIFO.res.mjs +28 -0
  359. package/src/util/Util_SQS_Runtime.res +169 -0
  360. package/src/util/Util_SQS_Runtime.res.mjs +150 -0
  361. package/src/util/Util_SesPolicy_Runtime.res +54 -0
  362. package/src/util/Util_SesPolicy_Runtime.res.mjs +55 -0
  363. package/src/util/Util_StaticBundle.res +124 -0
  364. package/src/util/Util_StaticBundle.res.mjs +132 -0
  365. package/src/util/Util_Vpc.res +22 -0
  366. package/src/util/Util_Vpc.res.mjs +27 -0
  367. package/tests/AppSync_AdapterTest.res +396 -0
  368. package/tests/AppSync_AdapterTest.res.mjs +326 -0
  369. package/tests/AppSync_Resolver_RetryingTest.res +59 -0
  370. package/tests/AppSync_Resolver_RetryingTest.res.mjs +66 -0
  371. package/tests/Auth_CognitoTest.res +203 -0
  372. package/tests/Auth_CognitoTest.res.mjs +248 -0
  373. package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res +602 -0
  374. package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res.mjs +742 -0
  375. package/tests/EventLogStorage_DynamoDb_RuntimeTest.res +57 -0
  376. package/tests/EventLogStorage_DynamoDb_RuntimeTest.res.mjs +68 -0
  377. package/tests/MCP_LambdaTest.res +101 -0
  378. package/tests/MCP_LambdaTest.res.mjs +56 -0
  379. package/tests/Util_HostUiDomainTest.res +90 -0
  380. package/tests/Util_HostUiDomainTest.res.mjs +50 -0
  381. package/tests/Util_SQS_RuntimeTest.res +46 -0
  382. package/tests/Util_SQS_RuntimeTest.res.mjs +45 -0
  383. package/tests/Util_StaticBundleTest.res +136 -0
  384. package/tests/Util_StaticBundleTest.res.mjs +149 -0
  385. package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +101 -0
  386. package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res.mjs +91 -0
  387. package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +315 -0
  388. package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res.mjs +435 -0
  389. package/tests/integration/DcbIntegrationHarness.res +102 -0
  390. package/tests/integration/DcbIntegrationHarness.res.mjs +163 -0
  391. package/tests/integration/EpTestSlice.res +28 -0
  392. package/tests/integration/EpTestSlice.res.mjs +43 -0
  393. package/tests/integration/EpTestSliceBehavior.res +18 -0
  394. 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
+ }