@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,80 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Util_Bundle$ReventlessAws from "../util/Util_Bundle.res.mjs";
4
+ import * as Plugin_Helpers$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/component/Plugin_Helpers.res.mjs";
5
+ import * as Aggregate_Builder$ReventlessCore from "@reventlessdev/reventless-core/src/components/Aggregate/Aggregate_Builder.res.mjs";
6
+ import * as RuntimeEnvironment_Lambda$ReventlessAws from "../adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs";
7
+ import * as CommandTopicChannel_SQS_Async$ReventlessAws from "../adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs";
8
+ import * as EventLogStorage_DynamoDbStream$ReventlessAws from "../adapter/EventLog/EventLogStorage_DynamoDbStream.res.mjs";
9
+ import * as CommandGeneratorResolvers_AppSync$ReventlessAws from "../adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res.mjs";
10
+ import * as EventTopicPublisher_DynamoDbStream$ReventlessAws from "../adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res.mjs";
11
+ import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
12
+ import * as AggregateRuntime_Builder_Single_Async$ReventlessAws from "../adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs";
13
+
14
+ function Make(Spec) {
15
+ return Behavior => (EventMappings => {
16
+ let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(Behavior)({
17
+ mappings: EventMappings.mappings,
18
+ counter: EventMappings.counter
19
+ })({
20
+ make: RuntimeEnvironment_Lambda$ReventlessAws.make,
21
+ groupBySource: RuntimeEnvironment_Lambda$ReventlessAws.groupBySource,
22
+ extractCorrelationId: RuntimeEnvironment_Lambda$ReventlessAws.extractCorrelationId,
23
+ asEventHandler: prim => prim,
24
+ asEffectHandler: prim => prim
25
+ })(CommandGeneratorResolvers_AppSync$ReventlessAws)({
26
+ make: CommandTopicChannel_SQS_Async$ReventlessAws.make
27
+ })(EventLogStorage_DynamoDbStream$ReventlessAws)(EventTopicPublisher_DynamoDbStream$ReventlessAws)({
28
+ make: EventCollectorChannel_DynamoDbStream$ReventlessAws.make,
29
+ connect: EventCollectorChannel_DynamoDbStream$ReventlessAws.connect
30
+ })({
31
+ CommandTopicChannel: {
32
+ make: CommandTopicChannel_SQS_Async$ReventlessAws.make
33
+ },
34
+ EventCollectorChannel: {
35
+ make: EventCollectorChannel_DynamoDbStream$ReventlessAws.make,
36
+ connect: EventCollectorChannel_DynamoDbStream$ReventlessAws.connect
37
+ },
38
+ forCommandGenerator: AggregateRuntime_Builder_Single_Async$ReventlessAws.forCommandGenerator,
39
+ forCommandTopic: AggregateRuntime_Builder_Single_Async$ReventlessAws.forCommandTopic,
40
+ forEventCollector: AggregateRuntime_Builder_Single_Async$ReventlessAws.forEventCollector,
41
+ finish: AggregateRuntime_Builder_Single_Async$ReventlessAws.finish
42
+ })(Plugin_Helpers$ReventlessCore.NoopHooksConfig);
43
+ let make = (api, opts) => {
44
+ let aggregate = Inner.make(api, opts);
45
+ let eventLogOutputs = Inner.outputs(aggregate).eventLog;
46
+ let tableResource = eventLogOutputs.resources[0];
47
+ let eventLogTableName = tableResource.name;
48
+ AggregateRuntime_Builder_Single_Async$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Behavior.moduleUrl), eventLogTableName);
49
+ return aggregate;
50
+ };
51
+ let finish = () => AggregateRuntime_Builder_Single_Async$ReventlessAws.finish();
52
+ return {
53
+ Spec: Spec,
54
+ make: make,
55
+ outputs: Inner.outputs,
56
+ operations: Inner.operations,
57
+ finish: finish
58
+ };
59
+ });
60
+ }
61
+
62
+ let CommandGeneratorResolvers;
63
+
64
+ let CommandTopicChannel;
65
+
66
+ let EventCollectorChannel;
67
+
68
+ let RuntimeEnvironment;
69
+
70
+ let AggregateRuntimeBuilder;
71
+
72
+ export {
73
+ CommandGeneratorResolvers,
74
+ CommandTopicChannel,
75
+ EventCollectorChannel,
76
+ RuntimeEnvironment,
77
+ AggregateRuntimeBuilder,
78
+ Make,
79
+ }
80
+ /* Util_Bundle-ReventlessAws Not a pure module */
@@ -0,0 +1,500 @@
1
+ // AppSync_Adapter — implements ReventlessInfra.Api_Adapter.Provider for AWS AppSync.
2
+ //
3
+ // Creates a new AppSync GraphQL API and IAM execution role.
4
+ // updateSchema uses the AWS AppSync SDK to push a stitched SDL whenever plugins connect.
5
+
6
+ open PulumiAws
7
+
8
+ let log = ReventlessCore.Logger.fromEnv()
9
+
10
+ // ── SHA-256 helper ─────────────────────────────────────────────────────────
11
+
12
+ type hashObject
13
+ @module("node:crypto") external createHash: string => hashObject = "createHash"
14
+ @send external hashUpdate: (hashObject, string) => hashObject = "update"
15
+ @send external hashDigest: (hashObject, string) => string = "digest"
16
+
17
+ let sha256Hex = (input: string): string =>
18
+ createHash("sha256")->hashUpdate(input)->hashDigest("hex")
19
+
20
+ // ── Inline AppSync SDK binding ─────────────────────────────────────────────
21
+
22
+ type appSyncClient
23
+
24
+ // AWS SDK v3 command pattern: client.send(new StartSchemaCreationCommand({...}))
25
+ type startSchemaCreationInput = {
26
+ apiId: string,
27
+ definition: string,
28
+ }
29
+
30
+ type startSchemaCreationCommand
31
+
32
+ @module("@aws-sdk/client-appsync") @new
33
+ external makeAppSyncClient: unit => appSyncClient = "AppSyncClient"
34
+
35
+ @module("@aws-sdk/client-appsync") @new
36
+ external makeStartSchemaCreationCommand: startSchemaCreationInput => startSchemaCreationCommand =
37
+ "StartSchemaCreationCommand"
38
+
39
+ @send
40
+ external send: (appSyncClient, startSchemaCreationCommand) => promise<unknown> = "send"
41
+
42
+ let startSchemaCreation = (client: appSyncClient, input: startSchemaCreationInput) =>
43
+ client->send(input->makeStartSchemaCreationCommand)
44
+
45
+ // Retrying wrapper: AppSync holds an API-level lock during schema creation and
46
+ // rejects concurrent StartSchemaCreation calls with HTTP 409
47
+ // ConcurrentModificationException ("Schema is currently being altered, please
48
+ // wait until that is complete."). When multiple processes deploy plugin stacks
49
+ // in parallel against the same AppSync API, they race on this lock. Retry with
50
+ // jittered exponential backoff so a losing call can wait for the in-progress
51
+ // schema to finish and try again. Permanent errors (e.g. invalid SDL) are not
52
+ // retried — see AppSync_Error.classify.
53
+ let startSchemaCreationRetrying = (
54
+ client: appSyncClient,
55
+ input: startSchemaCreationInput,
56
+ ): promise<unit> => {
57
+ Effect.tryPromise(
58
+ ~catch=AppSync_Error.classify,
59
+ () => startSchemaCreation(client, input)->Promise.then(_ => Promise.resolve()),
60
+ )
61
+ ->Effect.retry(AppSync_Error.retrySchedule)
62
+ ->Effect.runPromise
63
+ }
64
+
65
+ // GetSchemaCreationStatus — poll until schema is ACTIVE
66
+ type getSchemaCreationStatusInput = {apiId: string}
67
+ type getSchemaCreationStatusCommand
68
+ type getSchemaCreationStatusResult = {status: string, details: option<string>}
69
+
70
+ @module("@aws-sdk/client-appsync") @new
71
+ external makeGetSchemaCreationStatusCommand: getSchemaCreationStatusInput => getSchemaCreationStatusCommand =
72
+ "GetSchemaCreationStatusCommand"
73
+
74
+ @send
75
+ external sendGetStatus: (appSyncClient, getSchemaCreationStatusCommand) => promise<getSchemaCreationStatusResult> =
76
+ "send"
77
+
78
+ let rec waitForSchemaActive = async (client, apiId, ~maxAttempts=30, ~attempt=0) => {
79
+ let result = await client->sendGetStatus(
80
+ {apiId: apiId}->makeGetSchemaCreationStatusCommand,
81
+ )
82
+ switch result.status {
83
+ | "ACTIVE" | "SUCCESS" => ()
84
+ | "FAILED" =>
85
+ let details = result.details->Option.getOr("(no details)")
86
+ JsError.throwWithMessage(`Schema creation failed for API ${apiId}: ${details}`)
87
+ | status if attempt >= maxAttempts =>
88
+ JsError.throwWithMessage(
89
+ `Schema creation timed out after ${maxAttempts->Int.toString} attempts (status: ${status})`,
90
+ )
91
+ | _ =>
92
+ await Promise.make((resolve, _) => setTimeout(resolve, 500)->ignore)
93
+ await waitForSchemaActive(client, apiId, ~maxAttempts, ~attempt=attempt + 1)
94
+ }
95
+ }
96
+
97
+ // GetIntrospectionSchema — fetch the live schema as an SDL string. Used by the
98
+ // deploy-time drift check in preResolversSchemaHook to detect a live schema that
99
+ // was clobbered out-of-band by a runtime re-stitch (the stored deploy hash does
100
+ // not reflect such clobbers). Returns "" when the API has no schema or when
101
+ // introspection fails — the caller decides how to treat an empty result.
102
+ type getIntrospectionSchemaInput = {apiId: string, format: string}
103
+ type getIntrospectionSchemaCommand
104
+ type schemaBlob
105
+ type getIntrospectionSchemaResult = {schema: option<schemaBlob>}
106
+
107
+ @module("@aws-sdk/client-appsync") @new
108
+ external makeGetIntrospectionSchemaCommand: getIntrospectionSchemaInput => getIntrospectionSchemaCommand =
109
+ "GetIntrospectionSchemaCommand"
110
+
111
+ @send
112
+ external sendGetIntrospection: (
113
+ appSyncClient,
114
+ getIntrospectionSchemaCommand,
115
+ ) => promise<getIntrospectionSchemaResult> = "send"
116
+
117
+ // resp.schema is a Uint8Array of the SDL text; decode it to UTF-8.
118
+ type nodeBuffer
119
+ @val @scope("Buffer") external bufferFrom: schemaBlob => nodeBuffer = "from"
120
+ @send external bufferToString: (nodeBuffer, string) => string = "toString"
121
+
122
+ let getIntrospectionSdl = async (client: appSyncClient, apiId: string): string => {
123
+ try {
124
+ let resp = await client->sendGetIntrospection(
125
+ {apiId, format: "SDL"}->makeGetIntrospectionSchemaCommand,
126
+ )
127
+ switch resp.schema {
128
+ | Some(blob) => bufferFrom(blob)->bufferToString("utf-8")
129
+ | None => ""
130
+ }
131
+ } catch {
132
+ | exn =>
133
+ let msg = exn->JsExn.fromException->Option.flatMap(JsExn.message)->Option.getOr("unknown")
134
+ log.warn(~comp="AppSync_Adapter", `getIntrospectionSdl failed for ${apiId}: ${msg}`)
135
+ ""
136
+ }
137
+ }
138
+
139
+ let deploySchemaWithRetry = (
140
+ client: appSyncClient,
141
+ apiId: string,
142
+ definition: string,
143
+ ): Effect.t<unit, AppSync_Error.t, unit> =>
144
+ Effect.tryPromise(
145
+ ~catch=AppSync_Error.classify,
146
+ () => startSchemaCreation(client, {apiId, definition})->Promise.then(_ => Promise.resolve()),
147
+ )->Effect.retry(AppSync_Error.retrySchedule)
148
+
149
+ // ── Schema-push serialization lock ──────────────────────────────────────────
150
+ //
151
+ // Plugin/service stacks share one AppSync API, and StartSchemaCreation REPLACES
152
+ // the whole schema. When two stacks scan the deploy-schema table, stitch, and
153
+ // push concurrently, a push built from a stale scan (missing a peer's not-yet-
154
+ // written fragment) clobbers the peer's fields — orphaning their resolvers
155
+ // (NotFoundException: No field named X). The shrink guard only catches
156
+ // catastrophic (>threshold) drops, not a single dropped field.
157
+ //
158
+ // This lease serialises scan→stitch→push across stacks via a conditional-write
159
+ // lock row in the shared PluginSchemaPersistence table. A push that holds the
160
+ // lease always scans a table already containing every prior push's fragment, so
161
+ // the last push is complete and nothing is clobbered. The lease carries a TTL so
162
+ // a crashed holder cannot deadlock the table; if the lock cannot be acquired
163
+ // within maxWaitMs we proceed best-effort rather than fail the deploy.
164
+
165
+ @val external schemaLockSetTimeout: (unit => unit, int) => unit = "setTimeout"
166
+ let schemaLockSleep = (ms: int): promise<unit> =>
167
+ Promise.make((resolve, _) => schemaLockSetTimeout(() => resolve(), ms))
168
+ let _schemaLockCounter = ref(0)
169
+
170
+ let withSchemaPushLock = async (
171
+ ~tableName: string,
172
+ ~apiId: string,
173
+ ~leaseMs: int=120000,
174
+ ~maxWaitMs: int=180000,
175
+ fn: unit => promise<'a>,
176
+ ): 'a => {
177
+ open AwsSdk.DynamoDb.DocumentClient
178
+ let lockId = `schema-push-lock:${apiId}`
179
+ _schemaLockCounter := _schemaLockCounter.contents + 1
180
+ let holder = `${apiId}#${Date.now()->Float.toString}#${_schemaLockCounter.contents->Int.toString}`
181
+
182
+ let acquire = async () => {
183
+ let deadline = Date.now() +. maxWaitMs->Int.toFloat
184
+ let acquired = ref(false)
185
+ while !acquired.contents {
186
+ let now = Date.now()
187
+ let ok =
188
+ await PutCommand.make({
189
+ PutCommand.tableName,
190
+ item: Dict.fromArray([
191
+ ("id", lockId->JSON.Encode.string),
192
+ ("holder", holder->JSON.Encode.string),
193
+ ("expiresAt", (now +. leaseMs->Int.toFloat)->JSON.Encode.float),
194
+ ])->JSON.Encode.object,
195
+ conditionExpression: "attribute_not_exists(id) OR expiresAt < :now",
196
+ expressionAttributeValues: Dict.fromArray([(":now", now->JSON.Encode.float)]),
197
+ })
198
+ ->PutCommand.send
199
+ ->Promise.thenResolve(_ => true)
200
+ ->Promise.catch(_ => Promise.resolve(false))
201
+ if ok {
202
+ acquired := true
203
+ } else if Date.now() > deadline {
204
+ log.warn(
205
+ ~comp="AppSync_Adapter",
206
+ `schema-push lock for ${apiId} not acquired within ${maxWaitMs->Int.toString}ms — proceeding best-effort`,
207
+ )
208
+ acquired := true
209
+ } else {
210
+ await schemaLockSleep(1000)
211
+ }
212
+ }
213
+ }
214
+
215
+ let release = async () => {
216
+ let _ =
217
+ await DeleteCommand.make({
218
+ DeleteCommand.tableName,
219
+ key: Dict.fromArray([("id", lockId->JSON.Encode.string)]),
220
+ conditionExpression: "holder = :holder",
221
+ expressionAttributeValues: Dict.fromArray([(":holder", holder->JSON.Encode.string)]),
222
+ })
223
+ ->DeleteCommand.send
224
+ ->Promise.thenResolve(_ => ())
225
+ ->Promise.catch(_ => Promise.resolve()) // expired lease stolen by a peer — leave theirs intact
226
+ }
227
+
228
+ await acquire()
229
+ try {
230
+ let r = await fn()
231
+ let _ = await release()
232
+ r
233
+ } catch {
234
+ | exn =>
235
+ let _ = await release()
236
+ throw(exn)
237
+ }
238
+ }
239
+
240
+ // Lazy singleton AppSync client (runtime only)
241
+ let _client: ref<option<appSyncClient>> = ref(None)
242
+ let getClient = () =>
243
+ switch _client.contents {
244
+ | Some(c) => c
245
+ | None =>
246
+ let c = makeAppSyncClient()
247
+ _client.contents = Some(c)
248
+ c
249
+ }
250
+
251
+ // ── @aws_auth directive injection ─────────────────────────────────────────
252
+ // Injects @aws_auth(cognito_groups: [...]) directives into SDL field strings
253
+ // based on authorization metadata from schema entries.
254
+ //
255
+ // Two sources are merged:
256
+ // 1. The legacy `authorization?: {tableName, group}` field — single group
257
+ // per entry, kept for the indexed-access auth path.
258
+ // 2. The Stage E2 spec-level `Authorization.permission` fields
259
+ // (`fieldPermissions` on mutations, `permission` on queries) — derived
260
+ // from `@@reventless.authorize` / `@authorize` PPX annotations.
261
+ //
262
+ // When both are present on the same field, the spec-level permission wins
263
+ // (it is more specific). `AllowGroups([g1, g2, ...])` emits
264
+ // `@aws_auth(cognito_groups: ["g1", "g2", ...])`. `AllowAuthenticated` /
265
+ // `AllowAnonymous` emit no directive (with Cognito as primary auth, any
266
+ // reaching request is already authenticated). `AllowGroups([])` and
267
+ // `DenyAll` emit a sentinel `__deny_all__` group that no Cognito user can
268
+ // belong to — effectively blocking the field at the API layer.
269
+
270
+ let _permissionToCognitoGroups = (
271
+ permission: Reventless.Authorization.permission,
272
+ ): option<array<string>> =>
273
+ switch permission {
274
+ | AllowGroups([]) => Some(["__deny_all__"])
275
+ | AllowGroups(groups) => Some(groups)
276
+ | DenyAll => Some(["__deny_all__"])
277
+ | AllowAuthenticated | AllowAnonymous => None
278
+ }
279
+
280
+ let _formatGroupsDirective = (groups: array<string>): string => {
281
+ let quoted = groups->Array.map(g => `"${g}"`)->Array.join(", ")
282
+ `@aws_auth(cognito_groups: [${quoted}])`
283
+ }
284
+
285
+ let injectAwsAuth = (
286
+ fragment: Reventless.Plugin.apiSchemaFragment,
287
+ ~mutationEntries: array<ReventlessInfra.Api.mutationSchemaEntry>,
288
+ ~queryEntries: array<ReventlessInfra.Api.querySchemaEntry>,
289
+ ): Reventless.Plugin.apiSchemaFragment => {
290
+ let parts = ReventlessCore.GraphQL_Stitcher.decode(fragment)
291
+
292
+ // Build authorization lookup from mutation entries: fieldName -> groups.
293
+ // Spec-level `fieldPermissions` takes precedence over the legacy
294
+ // `authorization.group` per-entry single-group form.
295
+ let mutationAuthMap: Dict.t<array<string>> = Dict.make()
296
+ mutationEntries->Array.forEach(entry => {
297
+ switch entry.authorization {
298
+ | Some({group}) =>
299
+ entry.fieldNames->Array.forEach(fieldName =>
300
+ mutationAuthMap->Dict.set(fieldName, [group])
301
+ )
302
+ | None => ()
303
+ }
304
+ switch entry.fieldPermissions {
305
+ | Some(fp) =>
306
+ fp
307
+ ->Dict.toArray
308
+ ->Array.forEach(((fieldName, permission)) => {
309
+ switch _permissionToCognitoGroups(permission) {
310
+ | Some(groups) => mutationAuthMap->Dict.set(fieldName, groups)
311
+ | None => mutationAuthMap->Dict.delete(fieldName)
312
+ }
313
+ })
314
+ | None => ()
315
+ }
316
+ })
317
+
318
+ // Build authorization lookup from query entries: fieldName -> groups.
319
+ // Spec-level `permission` takes precedence over the legacy authorization.
320
+ let queryAuthMap: Dict.t<array<string>> = Dict.make()
321
+ queryEntries->Array.forEach(entry => {
322
+ switch entry.authorization {
323
+ | Some({group}) =>
324
+ queryAuthMap->Dict.set(entry.singleFieldName, [group])
325
+ queryAuthMap->Dict.set(entry.listFieldName, [group])
326
+ | None => ()
327
+ }
328
+ switch entry.permission {
329
+ | Some(permission) =>
330
+ switch _permissionToCognitoGroups(permission) {
331
+ | Some(groups) =>
332
+ queryAuthMap->Dict.set(entry.singleFieldName, groups)
333
+ queryAuthMap->Dict.set(entry.listFieldName, groups)
334
+ | None =>
335
+ queryAuthMap->Dict.delete(entry.singleFieldName)
336
+ queryAuthMap->Dict.delete(entry.listFieldName)
337
+ }
338
+ | None => ()
339
+ }
340
+ })
341
+
342
+ let augmentedMutations = parts.mutations->Array.map(field => {
343
+ let fieldName = ReventlessCore.GraphQL_Stitcher.extractLeadingName(field)
344
+ switch mutationAuthMap->Dict.get(fieldName) {
345
+ | Some(groups) => `${field}\n ${_formatGroupsDirective(groups)}`
346
+ | None => field
347
+ }
348
+ })
349
+
350
+ let augmentedQueries = parts.queries->Array.map(field => {
351
+ let fieldName = ReventlessCore.GraphQL_Stitcher.extractLeadingName(field)
352
+ switch queryAuthMap->Dict.get(fieldName) {
353
+ | Some(groups) => `${field} ${_formatGroupsDirective(groups)}`
354
+ | None => field
355
+ }
356
+ })
357
+
358
+ let encoded =
359
+ JSON.Encode.object(
360
+ Dict.fromArray([
361
+ ("types", JSON.Encode.array(parts.types->Array.map(JSON.Encode.string))),
362
+ ("mutations", JSON.Encode.array(augmentedMutations->Array.map(JSON.Encode.string))),
363
+ ("queries", JSON.Encode.array(augmentedQueries->Array.map(JSON.Encode.string))),
364
+ (
365
+ "subscriptions",
366
+ JSON.Encode.array(parts.subscriptions->Array.map(JSON.Encode.string)),
367
+ ),
368
+ ]),
369
+ )->JSON.stringify
370
+
371
+ {Reventless.Plugin.encoded, protocol: "graphql"}
372
+ }
373
+
374
+ // Injects @aws_auth with the given group on ALL mutation, query, and subscription
375
+ // fields in a fragment. Used for the base fragment where all fields share the
376
+ // same authorization group.
377
+ let injectAwsAuthAll = (
378
+ fragment: Reventless.Plugin.apiSchemaFragment,
379
+ ~group: string,
380
+ ): Reventless.Plugin.apiSchemaFragment => {
381
+ let parts = ReventlessCore.GraphQL_Stitcher.decode(fragment)
382
+
383
+ let augmentedMutations = parts.mutations->Array.map(field =>
384
+ `${field}\n @aws_auth(cognito_groups: ["${group}"])`
385
+ )
386
+ let augmentedQueries = parts.queries->Array.map(field =>
387
+ `${field} @aws_auth(cognito_groups: ["${group}"])`
388
+ )
389
+ let augmentedSubscriptions = parts.subscriptions->Array.map(field =>
390
+ `${field}\n @aws_auth(cognito_groups: ["${group}"])`
391
+ )
392
+
393
+ let encoded =
394
+ JSON.Encode.object(
395
+ Dict.fromArray([
396
+ ("types", JSON.Encode.array(parts.types->Array.map(JSON.Encode.string))),
397
+ ("mutations", JSON.Encode.array(augmentedMutations->Array.map(JSON.Encode.string))),
398
+ ("queries", JSON.Encode.array(augmentedQueries->Array.map(JSON.Encode.string))),
399
+ (
400
+ "subscriptions",
401
+ JSON.Encode.array(augmentedSubscriptions->Array.map(JSON.Encode.string)),
402
+ ),
403
+ ]),
404
+ )->JSON.stringify
405
+
406
+ {Reventless.Plugin.encoded, protocol: "graphql"}
407
+ }
408
+
409
+ // ── Provider implementation ────────────────────────────────────────────────
410
+
411
+ type api = AppSync.GraphQLApi.t
412
+ type role = IAM.Role.t
413
+
414
+ let makeApiResource = (
415
+ ~name: string,
416
+ ~opts: Pulumi.ComponentResource.options,
417
+ ): (Pulumi.Output.t<api>, Pulumi.Output.t<role>) => {
418
+ let customOpts: Pulumi.CustomResourceOptions.t = {
419
+ parent: ?opts.parent,
420
+ }
421
+
422
+ // Create IAM role for AppSync
423
+ let iamRole = IAM.Role.make(
424
+ ~name=`${name}-appsync-role`,
425
+ ~args={
426
+ assumeRolePolicy: `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"appsync.amazonaws.com"},"Action":"sts:AssumeRole"}]}`
427
+ ->Pulumi.Input.make,
428
+ },
429
+ ~opts=Some(customOpts),
430
+ )
431
+
432
+ // Resolve the Cognito UserPool — cached inside Platform_Stack, so calling
433
+ // from each API call site (DomainApi, PlatformApi) is safe. Returned as a
434
+ // single Output that yields the {userPoolId, awsRegion, defaultAction}
435
+ // record AppSync expects.
436
+ let authConfigOut = Auth_Cognito.make(~name=`${name}-auth`)
437
+ let userPoolConfigOut =
438
+ authConfigOut->Pulumi.Output.apply((c: Auth_Cognito.authConfig) =>
439
+ (
440
+ {
441
+ userPoolId: c.userPoolId,
442
+ awsRegion: c.region,
443
+ defaultAction: AppSync.GraphQLApi.ALLOW,
444
+ }: AppSync.GraphQLApi.userPoolConfig
445
+ )
446
+ )
447
+
448
+ // Cognito as primary auth, AWS_IAM as additional provider for
449
+ // server-to-server lambdas (heartbeat, Plugin_Connected emission) signed via
450
+ // the existing IAM role.
451
+ let apiArgs: AppSync.GraphQLApi.args = {
452
+ authenticationType: AppSync.GraphQLApi
453
+ .AMAZON_COGNITO_USER_POOLS->Pulumi.Input.make,
454
+ userPoolConfig: userPoolConfigOut->Pulumi.Output.asInput,
455
+ additionalAuthenticationProviders: [
456
+ (
457
+ {
458
+ authenticationType: AppSync.GraphQLApi.AWS_IAM->Pulumi.Input.make,
459
+ }: AppSync.GraphQLApi.additionalAuthenticationProvider
460
+ )->Pulumi.Input.make,
461
+ ]->Pulumi.Input.make,
462
+ }
463
+ let graphQLApi = AppSync.GraphQLApi.make(~name, ~args=apiArgs, ~opts=Some(customOpts))
464
+
465
+ (graphQLApi->Pulumi.Output.make, iamRole->Pulumi.Output.make)
466
+ }
467
+
468
+ let generateFragment = (
469
+ ~mutationEntries: array<ReventlessInfra.Api.mutationSchemaEntry>,
470
+ ~queryEntries: array<ReventlessInfra.Api.querySchemaEntry>,
471
+ ): Reventless.Plugin.apiSchemaFragment => {
472
+ let fragment = ReventlessCore.GraphQL_FragmentGenerator.generate(~mutationEntries, ~queryEntries)
473
+ injectAwsAuth(fragment, ~mutationEntries, ~queryEntries)
474
+ }
475
+
476
+ let updateSchema = (
477
+ ~api: Pulumi.Output.t<api>,
478
+ ~baseFragment: Reventless.Plugin.apiSchemaFragment,
479
+ ~pluginFragments: array<Reventless.Plugin.apiSchemaFragment>,
480
+ ): promise<unit> => {
481
+ // Inject @aws_auth(cognito_groups: ["Admin"]) into all base fragment fields.
482
+ // The base fragment contains core Plugin aggregate queries/mutations — all Admin-only.
483
+ // Plugin fragments already have @aws_auth injected via generateFragment.
484
+ let augmentedBaseFragment = injectAwsAuthAll(baseFragment, ~group="Admin")
485
+ let sdl = ReventlessCore.GraphQL_Stitcher.stitch(~baseFragment=augmentedBaseFragment, ~pluginFragments)
486
+ // Resolve the API ID from the Output chain. In mock mode (tests) and in Lambda runtime
487
+ // (where the Output is backed by already-known values), this completes synchronously.
488
+ // The resulting promise wraps the AppSync SDK call.
489
+ let resultPromise: ref<promise<unit>> = ref(Promise.resolve())
490
+ let _ =
491
+ api
492
+ ->Pulumi.Output.apply(graphQLApi =>
493
+ graphQLApi.id->Pulumi.Output.apply(apiId => {
494
+ let effect = deploySchemaWithRetry(getClient(), apiId, sdl)
495
+ let p = effect->Effect.runPromise
496
+ resultPromise.contents = p
497
+ })
498
+ )
499
+ resultPromise.contents
500
+ }