@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,653 @@
1
+ /** AppSync resolver backed by a Pulumi dynamic provider that retries
2
+ CreateResolver / UpdateResolver on the schema-propagation race:
3
+
4
+ NotFoundException: No field named X found on type Query
5
+
6
+ The `aws-native` Cloud Control handler does NOT internally wait for this
7
+ propagation; neither does the classic provider. A custom dynamic provider
8
+ that calls the AppSync SDK directly and retries with exponential backoff
9
+ is the only reliable solution.
10
+
11
+ Exposes the same `makeUnitJsResolver` / `makePipelineJsResolver` API as
12
+ `AppSync_Resolver_Native` so `QueryDbResolvers_AppSync` only needs a
13
+ one-line module swap.
14
+
15
+ State migration: adds an alias pointing at the old
16
+ `aws-native:appsync/resolver:Resolver` type so existing resources are
17
+ adopted in-place on first deploy (no delete+recreate).
18
+
19
+ See docs/plans/appsync-resolver-aws-native-retry.md. */
20
+
21
+ // ── AWS SDK bindings ─────────────────────────────────────────────────────────
22
+ //
23
+ // Pulumi dynamic providers serialise the provider object (and its captured
24
+ // closure of imports) into stack state. A static `@module("@aws-sdk/client-appsync")`
25
+ // binding pulls the SDK's transitive deps into that closure, and Pulumi's
26
+ // serialiser fails to resolve them at runtime (CJS/ESM dual-export confusion
27
+ // produces invalid module paths like
28
+ // `@aws-sdk/client-appsync/node_modules/@aws-sdk/region-config-resolver/dist-cjs/index.js`).
29
+ //
30
+ // Workaround: lazy-import the SDK at handler-invocation time via `dynImport`,
31
+ // so the SDK module is NOT part of the captured closure. Each provider method
32
+ // resolves the SDK on first use and caches an initialised client.
33
+
34
+ let log = ReventlessCore.Logger.fromEnv()
35
+
36
+ type appSyncClient
37
+
38
+ type sdkRuntime = {name: string, runtimeVersion: string}
39
+
40
+ let appsyncJsRuntime: sdkRuntime = {name: "APPSYNC_JS", runtimeVersion: "1.0.0"}
41
+
42
+ type sdkPipelineConfig = {functions: array<string>}
43
+
44
+ type sdkResolverInput = {
45
+ apiId: string,
46
+ typeName: string,
47
+ fieldName: string,
48
+ dataSourceName?: string,
49
+ kind?: string,
50
+ code?: string,
51
+ runtime?: sdkRuntime,
52
+ pipelineConfig?: sdkPipelineConfig,
53
+ }
54
+
55
+ type sdkResolverOutput = {resolverArn?: string}
56
+ type sdkResolverResult = {resolver?: sdkResolverOutput}
57
+
58
+ type createResolverCmd
59
+ type updateResolverCmd
60
+ type deleteResolverCmd
61
+ type getResolverCmd
62
+
63
+ type sdkDeleteInput = {apiId: string, typeName: string, fieldName: string}
64
+
65
+ // Shape of the dynamically-imported `@aws-sdk/client-appsync` module.
66
+ // Constructors are typed as `('arg) => 'class` so we can call them with `new`
67
+ // via a small JS interop helper.
68
+ type sdkModule = {
69
+ @as("AppSyncClient") clientCtor: unit => appSyncClient,
70
+ @as("CreateResolverCommand") createCtor: sdkResolverInput => createResolverCmd,
71
+ @as("UpdateResolverCommand") updateCtor: sdkResolverInput => updateResolverCmd,
72
+ @as("DeleteResolverCommand") deleteCtor: sdkDeleteInput => deleteResolverCmd,
73
+ @as("GetResolverCommand") getCtor: sdkDeleteInput => getResolverCmd,
74
+ }
75
+
76
+ // Calls a constructor function with `new`. The SDK exports plain classes,
77
+ // so calling them as functions throws — we need `new`.
78
+ let newOf1: ('ctor, 'arg) => 'r = %raw(`(C, x) => new C(x)`)
79
+ let newOf0: 'ctor => 'r = %raw(`(C) => new C()`)
80
+
81
+ @send
82
+ external sendCreate: (appSyncClient, createResolverCmd) => promise<sdkResolverResult> = "send"
83
+ @send
84
+ external sendUpdate: (appSyncClient, updateResolverCmd) => promise<sdkResolverResult> = "send"
85
+ @send external sendDelete: (appSyncClient, deleteResolverCmd) => promise<unit> = "send"
86
+ @send external sendGet: (appSyncClient, getResolverCmd) => promise<sdkResolverResult> = "send"
87
+
88
+ // Dynamic ESM import — emitted by ReScript as a literal `import("...")`
89
+ // expression so the bundler does not statically capture the module.
90
+ @val external dynImport: string => promise<sdkModule> = "import"
91
+
92
+ // Lazy singletons — one SDK module + one client per deploy process.
93
+ let _sdk: ref<option<sdkModule>> = ref(None)
94
+ let _client: ref<option<appSyncClient>> = ref(None)
95
+
96
+ let getSdk = async (): sdkModule =>
97
+ switch _sdk.contents {
98
+ | Some(m) => m
99
+ | None =>
100
+ let m = await dynImport("@aws-sdk/client-appsync")
101
+ _sdk.contents = Some(m)
102
+ m
103
+ }
104
+
105
+ let getClient = async (): appSyncClient =>
106
+ switch _client.contents {
107
+ | Some(c) => c
108
+ | None =>
109
+ let sdk = await getSdk()
110
+ let c = newOf0(sdk.clientCtor)
111
+ _client.contents = Some(c)
112
+ c
113
+ }
114
+
115
+ // ── Error classification ──────────────────────────────────────────────────────
116
+
117
+ @get @return(nullable) external exnName: JsExn.t => option<string> = "name"
118
+
119
+ /** Returns `true` iff the error is the AppSync schema-propagation race:
120
+ `NotFoundException` with a message containing `"No field named"`.
121
+
122
+ Critical: must NOT match the delete-path `"No resolver found"` 404 —
123
+ those have the same exception name but a different message. */
124
+ let isFieldNotFoundError = (jsErr: JsExn.t): bool =>
125
+ switch (jsErr->exnName, JsExn.message(jsErr)) {
126
+ | (Some("NotFoundException"), Some(msg)) => msg->String.includes("No field named")
127
+ | _ => false
128
+ }
129
+
130
+ /** Returns `true` iff a delete should be treated as a no-op because the
131
+ target resource no longer exists in AWS. Covers three cases:
132
+
133
+ - `"API not found."` — the AppSync API itself was already deleted (e.g.
134
+ manually in the console or by a prior teardown); the resolver cannot
135
+ exist without its parent API.
136
+ - `"No resolver found"` — the API exists but the resolver was already
137
+ removed (diverged Pulumi state).
138
+ - `"Type not found"` — the parent GraphQL type was dropped from the schema
139
+ (e.g. a plugin's schema fragment was lost during a runtime re-stitch),
140
+ taking every field-attached resolver with it; resolver absent is the
141
+ desired end-state, so `refresh` should report drift and a subsequent
142
+ `up` will recreate against the restored schema.
143
+
144
+ In all cases the desired end-state (resolver absent) is already reached,
145
+ so the Pulumi delete should succeed. */
146
+ let isAlreadyDeletedError = (jsErr: JsExn.t): bool =>
147
+ switch (jsErr->exnName, JsExn.message(jsErr)) {
148
+ | (Some("NotFoundException"), Some(msg)) =>
149
+ msg->String.includes("API not found") ||
150
+ msg->String.includes("No resolver found") ||
151
+ msg->String.includes("Type not found")
152
+ | _ => false
153
+ }
154
+
155
+ /** Returns `true` iff AppSync rejected the create because a resolver for that
156
+ field already exists (Pulumi state / AppSync divergence). */
157
+ let isAlreadyExistsError = (jsErr: JsExn.t): bool =>
158
+ switch (jsErr->exnName, JsExn.message(jsErr)) {
159
+ | (Some("BadRequestException"), Some(msg)) => msg->String.includes("Only one resolver is allowed")
160
+ | _ => false
161
+ }
162
+
163
+ /** Returns `true` iff AppSync rejected the mutation because the API-level
164
+ schema-creation lock is held by an in-flight `StartSchemaCreation`:
165
+ `ConcurrentModificationException` with message
166
+ `"Schema is currently being altered"`.
167
+
168
+ AppSync holds a single per-API lock during schema creation and rejects any
169
+ concurrent `CreateResolver` / `UpdateResolver` (and `CreateDataSource`,
170
+ `CreateFunction`) until the schema reaches ACTIVE. Plugin_Builder gates
171
+ resolver creation on the plugin schema push, but admin-side resolvers in
172
+ `Platform_Admin.construct` are created synchronously and race the platform
173
+ schema push initiated from `Platform.res`. */
174
+ let isSchemaAlteringError = (jsErr: JsExn.t): bool =>
175
+ switch (jsErr->exnName, JsExn.message(jsErr)) {
176
+ | (Some("ConcurrentModificationException"), Some(msg)) =>
177
+ msg->String.includes("Schema is currently being altered")
178
+ | _ => false
179
+ }
180
+
181
+ // ── Retry helper ─────────────────────────────────────────────────────────────
182
+ //
183
+ // Pulumi serialises the dynamic provider object (and its entire closure of
184
+ // captured references) into stack state. Anything reachable from the provider
185
+ // methods must be JS-serialisable. `Effect` (from the `effect` package)
186
+ // captures runtime-level state that fails Pulumi's `serializeFunction`, so
187
+ // the retry loop here is hand-rolled rather than `Effect.retry` + `Schedule`.
188
+ // See https://www.pulumi.com/docs/concepts/resources/dynamic-providers/ —
189
+ // "the entire closure of values captured by the provider is serialised".
190
+
191
+ @val external setTimeout: (unit => unit, int) => int = "setTimeout"
192
+
193
+ /** Throws a JavaScript exception directly (bypasses the ReScript exn wrapper). */
194
+ let jsThrow: JsExn.t => 'a = %raw(`e => { throw e }`)
195
+
196
+ /** Hand-rolled retry on two transient AppSync races with capped exponential
197
+ backoff:
198
+
199
+ - `NotFoundException / No field named` — schema-propagation race after a
200
+ successful `StartSchemaCreation`. Backstop for the per-plugin dedup
201
+ flow (see `docs/plans/appsync-schema-push-dedup.md`).
202
+ - `ConcurrentModificationException / Schema is currently being altered` —
203
+ API-level lock contention with an in-flight `StartSchemaCreation` on
204
+ the same API (admin resolvers racing the platform schema push from
205
+ `Platform.res`).
206
+
207
+ Backoff: delay starts at 2 s, doubles each attempt, caps at 30 s. Up to
208
+ 8 attempts → ~150 s total budget — generous enough to outlast a typical
209
+ admin schema push (`waitForSchemaActive` polls 30 × 500 ms = 15 s and
210
+ real propagation usually finishes well inside that). The cap doubles as
211
+ a coarse fairness bound: if a schema push is genuinely taking > 2 min,
212
+ failing loud is better than retrying forever.
213
+
214
+ This is a **backstop**. The architectural fix for the
215
+ `ConcurrentModificationException` case is to gate
216
+ `Platform_Admin.construct`'s `createResolvers` on the admin schema push,
217
+ mirroring what Plugin_Builder does with `schemaPushed`. */
218
+ let rec runWithRaceRetry = async (
219
+ ~attempt: int=0,
220
+ ~maxAttempts: int=8,
221
+ ~delayMs: int=2000,
222
+ ~maxDelayMs: int=30000,
223
+ makeCall: unit => promise<'a>,
224
+ ): 'a => {
225
+ try {
226
+ await makeCall()
227
+ } catch {
228
+ | exn =>
229
+ let jsExn = exn->JsExn.fromException
230
+ let name = jsExn->Option.flatMap(exnName)->Option.getOr("(no name)")
231
+ let msg = jsExn->Option.flatMap(JsExn.message)->Option.getOr("(no message)")
232
+ let isRetryable =
233
+ attempt < maxAttempts &&
234
+ jsExn->Option.mapOr(false, e => isFieldNotFoundError(e) || isSchemaAlteringError(e))
235
+ if isRetryable {
236
+ log.info(
237
+ ~comp="AppSync_Resolver_Retrying",
238
+ `attempt ${(attempt + 1)->Int.toString}/${maxAttempts->Int.toString} failed, retrying in ${delayMs->Int.toString}ms: ${name}: ${msg}`,
239
+ )
240
+ let _ = await Promise.make((resolve, _) => setTimeout(resolve, delayMs)->ignore)
241
+ let nextDelay = delayMs * 2
242
+ let cappedDelay = nextDelay > maxDelayMs ? maxDelayMs : nextDelay
243
+ await runWithRaceRetry(
244
+ ~attempt=attempt + 1,
245
+ ~maxAttempts,
246
+ ~delayMs=cappedDelay,
247
+ ~maxDelayMs,
248
+ makeCall,
249
+ )
250
+ } else {
251
+ // Only log when we exhausted retries on a retryable error — not on the
252
+ // first non-retryable failure, which the caller may handle itself.
253
+ if attempt > 0 {
254
+ log.warn(
255
+ ~comp="AppSync_Resolver_Retrying",
256
+ `giving up after ${(attempt + 1)->Int.toString} attempts: ${name}: ${msg}`,
257
+ )
258
+ }
259
+ // Re-throw the original JavaScript error so Pulumi can display its message.
260
+ // throw(exn) would rethrow the ReScript exception wrapper (RE_EXN_ID), which
261
+ // has no `.message` property and causes Pulumi to display "error: undefined".
262
+ switch jsExn {
263
+ | Some(e) => jsThrow(e)
264
+ | None => throw(exn)
265
+ }
266
+ }
267
+ }
268
+ }
269
+
270
+ // ── Provider inputs (plain JS values delivered by Pulumi after resolution) ────
271
+
272
+ type providerInputs = {
273
+ apiId: string,
274
+ typeName: string,
275
+ fieldName: string,
276
+ dataSourceName?: string,
277
+ kind: string,
278
+ code: string,
279
+ functions?: array<string>,
280
+ }
281
+
282
+ // ── SDK input builder ─────────────────────────────────────────────────────────
283
+
284
+ let buildSdkInput = (inputs: providerInputs): sdkResolverInput => {
285
+ // Build the base required fields; then spread optional ones to keep
286
+ // the SDK payload free of explicit `undefined` keys.
287
+ let base: sdkResolverInput = {
288
+ apiId: inputs.apiId,
289
+ typeName: inputs.typeName,
290
+ fieldName: inputs.fieldName,
291
+ kind: inputs.kind,
292
+ code: inputs.code,
293
+ runtime: appsyncJsRuntime,
294
+ }
295
+ let withDs = switch inputs.dataSourceName {
296
+ | Some(ds) => {...base, dataSourceName: ds}
297
+ | None => base
298
+ }
299
+ switch inputs.functions {
300
+ | Some(fns) => {...withDs, pipelineConfig: {functions: fns}}
301
+ | None => withDs
302
+ }
303
+ }
304
+
305
+ let extractArn = (resp: sdkResolverResult): string =>
306
+ resp.resolver->Option.flatMap(r => r.resolverArn)->Option.getOr("unknown-arn")
307
+
308
+ // ── Dynamic provider method types ─────────────────────────────────────────────
309
+
310
+ // Pulumi passes OUTPUTS (not inputs) to diff/delete/update handlers, so all fields
311
+ // that diff_ compares must be stored in createOuts/updateResult.outs, otherwise
312
+ // olds.fieldX is undefined at diff time and `undefined != newValue` is always true
313
+ // in JavaScript — causing every deploy to trigger a delete+recreate.
314
+ type createOuts = {
315
+ resolverArn: string,
316
+ apiId: string,
317
+ typeName: string,
318
+ fieldName: string,
319
+ kind: string,
320
+ code: string,
321
+ dataSourceName?: string,
322
+ functions?: array<string>,
323
+ }
324
+ type createResult = {id: string, outs: createOuts}
325
+ type updateResult = {outs: createOuts}
326
+ type diffResult = {changes: bool, replaces: array<string>, deleteBeforeReplace: bool}
327
+ // Optional fields so `read_` can return `{}` when the resolver no longer exists
328
+ // in AppSync — Pulumi treats an empty `ReadResult` as "resource gone", removes
329
+ // it from state on `pulumi refresh`, and re-creates it on the next `pulumi up`.
330
+ type readResult = {id?: string, props?: providerInputs}
331
+
332
+ // ── Provider methods ──────────────────────────────────────────────────────────
333
+
334
+ let makeOuts = (resolverArn: string, inputs: providerInputs): createOuts => {
335
+ let base: createOuts = {
336
+ resolverArn,
337
+ apiId: inputs.apiId,
338
+ typeName: inputs.typeName,
339
+ fieldName: inputs.fieldName,
340
+ kind: inputs.kind,
341
+ code: inputs.code,
342
+ }
343
+ let withDs = switch inputs.dataSourceName {
344
+ | Some(ds) => {...base, dataSourceName: ds}
345
+ | None => base
346
+ }
347
+ switch inputs.functions {
348
+ | Some(fns) => {...withDs, functions: fns}
349
+ | None => withDs
350
+ }
351
+ }
352
+
353
+ let create = async (inputs: providerInputs): createResult => {
354
+ let sdk = await getSdk()
355
+ let client = await getClient()
356
+ let arn =
357
+ try {
358
+ await runWithRaceRetry(() =>
359
+ client
360
+ ->sendCreate(newOf1(sdk.createCtor, inputs->buildSdkInput))
361
+ ->Promise.thenResolve(extractArn)
362
+ )
363
+ } catch {
364
+ | exn =>
365
+ // If the resolver already exists (AppSync / Pulumi state divergence from a
366
+ // previous partial deploy), update it to match desired config and adopt its ARN.
367
+ // This makes create idempotent and lets stuck stacks recover without manual intervention.
368
+ let handled =
369
+ exn->JsExn.fromException->Option.mapOr(false, isAlreadyExistsError)
370
+ if handled {
371
+ let resp = await client->sendUpdate(newOf1(sdk.updateCtor, inputs->buildSdkInput))
372
+ extractArn(resp)
373
+ } else {
374
+ let jsExn = exn->JsExn.fromException
375
+ switch jsExn {
376
+ | Some(e) => jsThrow(e)
377
+ | None => throw(exn)
378
+ }
379
+ }
380
+ }
381
+ {id: arn, outs: makeOuts(arn, inputs)}
382
+ }
383
+
384
+ let update = async (id: string, _olds: providerInputs, news: providerInputs): updateResult => {
385
+ let sdk = await getSdk()
386
+ let client = await getClient()
387
+ let arn =
388
+ try {
389
+ let _ = await runWithRaceRetry(() =>
390
+ client->sendUpdate(newOf1(sdk.updateCtor, news->buildSdkInput))
391
+ )
392
+ // ARN is stable across updates — reuse the existing id
393
+ id
394
+ } catch {
395
+ | exn =>
396
+ // If the resolver was deleted from AppSync (e.g. by a schema replacement),
397
+ // fall back to CreateResolver so the resource is transparently recreated.
398
+ let handled =
399
+ exn->JsExn.fromException->Option.mapOr(false, isAlreadyDeletedError)
400
+ if handled {
401
+ let resp = await runWithRaceRetry(() =>
402
+ client
403
+ ->sendCreate(newOf1(sdk.createCtor, news->buildSdkInput))
404
+ ->Promise.thenResolve(extractArn)
405
+ )
406
+ resp
407
+ } else {
408
+ let jsExn = exn->JsExn.fromException
409
+ switch jsExn {
410
+ | Some(e) => jsThrow(e)
411
+ | None => throw(exn)
412
+ }
413
+ }
414
+ }
415
+ {outs: makeOuts(arn, news)}
416
+ }
417
+
418
+ /** Parse apiId, typeName, fieldName from the resolver ARN.
419
+ ARN format: arn:aws:appsync:{region}:{account}:apis/{apiId}/types/{typeName}/resolvers/{fieldName}
420
+ Pulumi dynamic providers pass OUTPUTS (not inputs) to delete, so props.apiId etc. may be
421
+ undefined. The ARN passed as `id` is always available and contains all needed identifiers. */
422
+ let parseArn = (arn: string): option<sdkDeleteInput> => {
423
+ let parts = arn->String.split("/")
424
+ switch (parts->Array.get(1), parts->Array.get(3), parts->Array.get(5)) {
425
+ | (Some(apiId), Some(typeName), Some(fieldName)) => Some({apiId, typeName, fieldName})
426
+ | _ => None
427
+ }
428
+ }
429
+
430
+ let delete_ = async (id: string, props: providerInputs): unit => {
431
+ let sdk = await getSdk()
432
+ let client = await getClient()
433
+ // Prefer parsing from the ARN since Pulumi passes outputs (not inputs) to delete handlers.
434
+ // Fall back to props fields for backward compat with older state that stores inputs in outs.
435
+ let deleteInput: sdkDeleteInput = switch parseArn(id) {
436
+ | Some(parsed) => parsed
437
+ | None => {apiId: props.apiId, typeName: props.typeName, fieldName: props.fieldName}
438
+ }
439
+ try {
440
+ await client->sendDelete(newOf1(sdk.deleteCtor, deleteInput))
441
+ } catch {
442
+ | exn if exn->JsExn.fromException->Option.mapOr(false, isAlreadyDeletedError) => ()
443
+ }
444
+ }
445
+
446
+ // Guard against undefined in olds for resources created with older code that did not
447
+ // store all fields in createOuts. In JavaScript `undefined !== value` evaluates to
448
+ // true, which would incorrectly flag every such field as requiring replacement.
449
+ let isDefined: string => bool = %raw(`x => x !== undefined && x !== null`)
450
+
451
+ /** Returns `true` for fields whose change requires delete+recreate.
452
+ AppSync does not allow renaming the API, type, field, or kind in-place. */
453
+ let diff_ = (_id: string, olds: providerInputs, news: providerInputs): diffResult => {
454
+ let replaces =
455
+ [
456
+ if isDefined(olds.apiId) && olds.apiId != news.apiId {Some("apiId")} else {None},
457
+ if isDefined(olds.typeName) && olds.typeName != news.typeName {Some("typeName")} else {None},
458
+ if isDefined(olds.fieldName) && olds.fieldName != news.fieldName {Some("fieldName")} else {None},
459
+ if isDefined(olds.kind) && olds.kind != news.kind {Some("kind")} else {None},
460
+ ]->Array.filterMap(x => x)
461
+ // For in-place update detection (non-replace changes): compare as-is.
462
+ // If olds is from old state (missing fields), this may trigger an unnecessary
463
+ // update, but that is safe — the update simply re-applies the resolver.
464
+ let changes =
465
+ replaces->Array.length > 0 ||
466
+ olds.code != news.code ||
467
+ olds.dataSourceName != news.dataSourceName ||
468
+ olds.functions != news.functions
469
+ {changes, replaces, deleteBeforeReplace: true}
470
+ }
471
+
472
+ /** Read live state for `pulumi refresh`.
473
+
474
+ Calls `GetResolver` against AppSync. If the resolver exists, returns the
475
+ stored inputs unchanged so Pulumi keeps the resource in state. If AppSync
476
+ reports the resolver as missing (`NotFoundException / No resolver found`
477
+ or `API not found.`), returns `{}` to signal drift — Pulumi removes the
478
+ resource from state on `pulumi refresh` and the next `pulumi up` recreates
479
+ it via `create`.
480
+
481
+ Healing flow: `pulumi refresh && pulumi up` after a schema replacement
482
+ that silently drops resolvers in AppSync. Without the live check the
483
+ `update` AlreadyDeleted→Create fallback only fires when an input field
484
+ changes; refresh alone could not detect the drift. */
485
+ let read_ = async (id: string, props: providerInputs): readResult => {
486
+ let sdk = await getSdk()
487
+ let client = await getClient()
488
+ // Prefer parsing the ARN since Pulumi passes outputs (not inputs) to read
489
+ // handlers; fall back to props fields for older state.
490
+ let getInput: sdkDeleteInput = switch parseArn(id) {
491
+ | Some(parsed) => parsed
492
+ | None => {apiId: props.apiId, typeName: props.typeName, fieldName: props.fieldName}
493
+ }
494
+ try {
495
+ let _ = await client->sendGet(newOf1(sdk.getCtor, getInput))
496
+ {id, props}
497
+ } catch {
498
+ | exn if exn->JsExn.fromException->Option.mapOr(false, isAlreadyDeletedError) =>
499
+ log.info(
500
+ ~comp="AppSync_Resolver_Retrying",
501
+ `resolver ${getInput.typeName}.${getInput.fieldName} missing in AppSync; reporting drift`,
502
+ )
503
+ ({}: readResult)
504
+ | exn =>
505
+ // Propagate non-404 errors (network/auth) so refresh fails loudly rather
506
+ // than silently dropping the resource from state.
507
+ let jsExn = exn->JsExn.fromException
508
+ switch jsExn {
509
+ | Some(e) => jsThrow(e)
510
+ | None => throw(exn)
511
+ }
512
+ }
513
+ }
514
+
515
+ // Provider as a plain JS object (no Pulumi Output captures — all state via inputs/olds/news)
516
+ let provider = {
517
+ "create": create,
518
+ "update": update,
519
+ "delete": delete_,
520
+ "diff": diff_,
521
+ "read": read_,
522
+ }
523
+
524
+ // ── Pulumi dynamic resource binding ──────────────────────────────────────────
525
+
526
+ /** Output shape is identical to AwsNative.AppSync.Resolver.t so
527
+ `Util.AppSync.toResourceNative` works without modification. */
528
+ type t = PulumiAws.AwsNative.AppSync.Resolver.t
529
+
530
+ type constructorProps = {
531
+ apiId: Pulumi.Input.t<string>,
532
+ typeName: Pulumi.Input.t<string>,
533
+ fieldName: Pulumi.Input.t<string>,
534
+ dataSourceName?: Pulumi.Input.t<string>,
535
+ kind: Pulumi.Input.t<string>,
536
+ code: Pulumi.Input.t<string>,
537
+ functions?: Pulumi.Input.t<array<string>>,
538
+ }
539
+
540
+ // pulumi.dynamic.Resource constructor: (provider, name, props, opts)
541
+ // Use the explicit /index.js path because @pulumi/pulumi/dynamic is a
542
+ // directory import not resolvable in ESM mode.
543
+ @module("@pulumi/pulumi/dynamic/index.js") @new
544
+ external _newResource: ('provider, string, 'props, Pulumi.CustomResourceOptions.t) => t =
545
+ "Resource"
546
+
547
+ let makeResolver = (
548
+ ~name: string,
549
+ ~props: constructorProps,
550
+ ~opts: option<Pulumi.CustomResourceOptions.t>,
551
+ ): t => {
552
+ // Always include an alias for the aws-native resource previously in state —
553
+ // prevents delete+recreate on first deploy (in-place adoption).
554
+ let migrationAlias = Pulumi.Alias.make(
555
+ ~type_="aws-native:appsync/resolver:Resolver",
556
+ ~name,
557
+ (),
558
+ )
559
+ let finalOpts: Pulumi.CustomResourceOptions.t = switch opts {
560
+ | Some(o) => {...o, aliases: [migrationAlias]}
561
+ | None => {aliases: [migrationAlias]}
562
+ }
563
+ _newResource(provider, name, props, finalOpts)
564
+ }
565
+
566
+ // ── Public API (identical signatures to AppSync_Resolver_Native) ──────────────
567
+
568
+ module Functions = PulumiAws.AppSync.Resolver.Functions
569
+
570
+ let makeSubscriptionResolverCode = (~filter: option<string>): string =>
571
+ switch filter {
572
+ | None => `export function request(ctx) {
573
+ return { payload: null };
574
+ }
575
+
576
+ export function response(ctx) {
577
+ return ctx.result;
578
+ }`
579
+ | Some(f) => `export function request(ctx) {
580
+ extensions.setSubscriptionFilter(${f});
581
+ return {};
582
+ }
583
+
584
+ export function response(ctx) {
585
+ return ctx.result;
586
+ }`
587
+ }
588
+
589
+ let makeSubscriptionResolver = (
590
+ ~name,
591
+ ~api: Pulumi.Output.t<PulumiAws.AppSync.GraphQLApi.t>,
592
+ ~field,
593
+ ~dataSourceName: option<Pulumi.Input.t<string>>=?,
594
+ ~subscriptionFilter: option<string>=?,
595
+ ~opts: option<Pulumi.CustomResourceOptions.t>=?,
596
+ ) => {
597
+ let baseProps: constructorProps = {
598
+ apiId: api->Pulumi.Output.flatMap(a => a.id)->Pulumi.Output.asInput,
599
+ typeName: "Subscription"->Pulumi.Input.make,
600
+ fieldName: field->Pulumi.Input.make,
601
+ kind: "UNIT"->Pulumi.Input.make,
602
+ code: makeSubscriptionResolverCode(~filter=subscriptionFilter)->Pulumi.Input.make,
603
+ }
604
+ let props = switch dataSourceName {
605
+ | Some(ds) => {...baseProps, dataSourceName: ds}
606
+ | None => baseProps
607
+ }
608
+ makeResolver(~name, ~props, ~opts)
609
+ }
610
+
611
+ let makeUnitJsResolver = (
612
+ ~name,
613
+ ~api: Pulumi.Output.t<PulumiAws.AppSync.GraphQLApi.t>,
614
+ ~dataSourceName,
615
+ ~type_,
616
+ ~field,
617
+ ~code,
618
+ ~opts: option<Pulumi.CustomResourceOptions.t>=?,
619
+ ) =>
620
+ makeResolver(
621
+ ~name,
622
+ ~props={
623
+ apiId: api->Pulumi.Output.flatMap(a => a.id)->Pulumi.Output.asInput,
624
+ typeName: type_,
625
+ fieldName: field,
626
+ dataSourceName: dataSourceName,
627
+ kind: "UNIT"->Pulumi.Input.make,
628
+ code,
629
+ },
630
+ ~opts,
631
+ )
632
+
633
+ let makePipelineJsResolver = (
634
+ ~name,
635
+ ~api: Pulumi.Output.t<PulumiAws.AppSync.GraphQLApi.t>,
636
+ ~type_,
637
+ ~field,
638
+ ~code,
639
+ ~functions: array<PulumiAws.AppSync.Function.t>,
640
+ ~opts: option<Pulumi.CustomResourceOptions.t>=?,
641
+ ) =>
642
+ makeResolver(
643
+ ~name,
644
+ ~props={
645
+ apiId: api->Pulumi.Output.flatMap(a => a.id)->Pulumi.Output.asInput,
646
+ typeName: type_,
647
+ fieldName: field,
648
+ kind: "PIPELINE"->Pulumi.Input.make,
649
+ code,
650
+ functions: functions->Array.map(f => f.functionId)->Pulumi.Output.all->Pulumi.Output.asInput,
651
+ },
652
+ ~opts,
653
+ )