@reventlessdev/reventless-aws 3.0.0-alpha.344 → 3.0.0-alpha.346

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 (263) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/package.json +15 -12
  3. package/run-provision-accounts.mjs +3 -0
  4. package/run-provision-admin.mjs +3 -0
  5. package/scripts/ProvisionAccounts.res +325 -0
  6. package/scripts/ProvisionAccounts.res.mjs +337 -0
  7. package/scripts/ProvisionAdmin.res +275 -0
  8. package/scripts/ProvisionAdmin.res.mjs +289 -0
  9. package/scripts/ProvisionCognito.res +149 -0
  10. package/scripts/ProvisionCognito.res.mjs +98 -0
  11. package/scripts/ProvisionIdentity.res +84 -14
  12. package/scripts/ProvisionIdentity.res.mjs +72 -7
  13. package/scripts/ProvisionProvider.res +104 -0
  14. package/scripts/ProvisionProvider.res.mjs +123 -0
  15. package/src/Platform.res +358 -329
  16. package/src/Platform.res.mjs +24 -12
  17. package/src/Platform_Casts.res +13 -4
  18. package/src/Platform_Stack.res +119 -9
  19. package/src/Platform_Stack.res.mjs +42 -4
  20. package/src/adapter/Api/AppSyncEventsSigner_Ops.res +8 -4
  21. package/src/adapter/Api/AppSync_EventsApi.res +12 -14
  22. package/src/adapter/Api/AppSync_Resolver_Native.res +3 -4
  23. package/src/adapter/Api/AppSync_Resolver_Retrying.res +78 -70
  24. package/src/adapter/Api/AppSync_SourceApiAssociation_Retrying.res +11 -8
  25. package/src/adapter/Api/Platform_AdminScan_Ops.res +15 -14
  26. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +10 -2
  27. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +40 -50
  28. package/src/adapter/Api/Platform_UIFragments_Lambda.res +39 -32
  29. package/src/adapter/Api/Platform_UIFragments_Lambda_Ops.res +5 -2
  30. package/src/adapter/Auth/Auth_ActiveRolePoolAttachment.res +0 -1
  31. package/src/adapter/Auth/Auth_ActiveRoleStore.res +1 -2
  32. package/src/adapter/Auth/Auth_ActiveRoleStore_Schema.res +1 -4
  33. package/src/adapter/Auth/Auth_ActiveRoleTrigger_Ops.res +5 -2
  34. package/src/adapter/Auth/Auth_Cognito.res +3 -9
  35. package/src/adapter/Auth/Auth_LoginIdentifier.res +66 -0
  36. package/src/adapter/Auth/Auth_LoginIdentifier.res.mjs +70 -0
  37. package/src/adapter/Auth/Auth_SignUpMode.res +78 -0
  38. package/src/adapter/Auth/Auth_SignUpMode.res.mjs +56 -0
  39. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +1 -4
  40. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res +3 -1
  41. package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res +1 -4
  42. package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +7 -4
  43. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +6 -1
  44. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +7 -4
  45. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res +24 -18
  46. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +9 -4
  47. package/src/adapter/CommandTopic/CommandTopicRegistry.res +1 -4
  48. package/src/adapter/Counter/CounterHandler_DynamoDbStream.res +15 -15
  49. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res +9 -5
  50. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +179 -213
  51. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +5 -5
  52. package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res +6 -2
  53. package/src/adapter/EventCollector/EventCollectorChannel_SQS.res +14 -7
  54. package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res +14 -7
  55. package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res +6 -3
  56. package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res +6 -1
  57. package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res +13 -17
  58. package/src/adapter/EventLog/EventLogStorage_Postgres.res +7 -4
  59. package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +12 -7
  60. package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync_Ops.res +4 -2
  61. package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res +3 -2
  62. package/src/adapter/EventTopic/EventTopicPublisher_SNS.res +20 -12
  63. package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res +21 -9
  64. package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res +5 -3
  65. package/src/adapter/Geocoder/Geocoder_AwsLocation_Resolver.res +6 -3
  66. package/src/adapter/Mcp/MCP_Lambda.res +31 -46
  67. package/src/adapter/Messaging/Messaging_Ses_Backend.res +11 -7
  68. package/src/adapter/Messaging/Messaging_Ses_Backend.res.mjs +2 -4
  69. package/src/adapter/Monitoring/Monitoring_CloudWatch.res +16 -16
  70. package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res +5 -10
  71. package/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res +4 -2
  72. package/src/adapter/Postgres/PgConnection.res +6 -5
  73. package/src/adapter/Postgres/PgMigration_Builder.res +4 -8
  74. package/src/adapter/Postgres/PgRuntime.res +4 -7
  75. package/src/adapter/QueryDb/PgQueryResolver_Builder.res +9 -11
  76. package/src/adapter/QueryDb/PgQueryResolver_Lambda.res +22 -21
  77. package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res +114 -111
  78. package/src/adapter/QueryDb/QueryDbResolvers_Lambda.res +1 -7
  79. package/src/adapter/QueryDb/QueryDbStorage.res +4 -2
  80. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res +23 -24
  81. package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res +8 -2
  82. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res +71 -73
  83. package/src/adapter/QueryDb/QueryDbStorage_Postgres.res +5 -2
  84. package/src/adapter/QueryDb/QueryInterceptor_Provisioning.res +1 -4
  85. package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res +8 -2
  86. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +73 -81
  87. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +72 -78
  88. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +44 -67
  89. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +44 -67
  90. package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +53 -82
  91. package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +47 -77
  92. package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +23 -11
  93. package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res.mjs +5 -1
  94. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +80 -97
  95. package/src/adapter/Runtime/CounterEntryPoint_Ops.res +2 -7
  96. package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +16 -10
  97. package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +24 -15
  98. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +17 -37
  99. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +31 -57
  100. package/src/adapter/Runtime/EventMapperEntryPoint_Ops.res +18 -24
  101. package/src/adapter/Runtime/ExtensionPointEntryPoint_Ops.res +1 -5
  102. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +4 -3
  103. package/src/adapter/Runtime/HeartbeatEntryPoint.res +0 -1
  104. package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.res +4 -2
  105. package/src/adapter/Runtime/PgMigrationEntryPoint.res +0 -1
  106. package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res +3 -2
  107. package/src/adapter/Runtime/PluginExtensionPointEntryPoint.res +1 -2
  108. package/src/adapter/Runtime/ProjectionEntryPoint_Ops.res +4 -5
  109. package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +22 -10
  110. package/src/adapter/Runtime/RuntimeExtensionEntryPoint_Ops.res +8 -2
  111. package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +14 -31
  112. package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +16 -17
  113. package/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res +10 -9
  114. package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +46 -52
  115. package/src/adapter/Runtime/StreamRoutedEntryPoint_Ops.res +36 -41
  116. package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +31 -37
  117. package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +6 -7
  118. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +4 -6
  119. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res +2 -6
  120. package/src/adapter/StateTopic/StateTopic_AppSync.res +21 -16
  121. package/src/adapter/StateTopic/StateTopic_AppSync_Ops.res +36 -32
  122. package/src/adapter/Task/TaskBucket_S3.res +6 -1
  123. package/src/adapter/Upload/Upload_Claim_S3.res +17 -20
  124. package/src/adapter/Upload/Upload_Claim_S3_Ops.res +5 -2
  125. package/src/adapter/Upload/Upload_Presign_S3.res +51 -49
  126. package/src/capability/Capability_Geocoding_AwsLocation.res +4 -1
  127. package/src/capability/Capability_Messaging.res +4 -5
  128. package/src/capability/Capability_Messaging_Ses.res +3 -1
  129. package/src/capability/Capability_ObjectStore_S3.res +1 -7
  130. package/src/components/Api/AppSync_Adapter.res +80 -109
  131. package/src/components/Api/AppSync_Adapter.res.mjs +26 -60
  132. package/src/components/Api/AppSync_SdlDecorate.res +118 -31
  133. package/src/components/Api/AppSync_SdlDecorate.res.mjs +45 -0
  134. package/src/components/AutomationSlice_Builder.res +6 -4
  135. package/src/components/ExtensionPoint_Builder.res +9 -10
  136. package/src/components/InboundTranslationSlice_Builder.res +7 -8
  137. package/src/components/OutboundTranslationSlice_Builder.res +14 -8
  138. package/src/components/OutboundTranslationSlice_Builder.res.mjs +1 -1
  139. package/src/components/SideEffectHandler_Single.res +4 -4
  140. package/src/components/StateViewSlice_Builder.res +6 -4
  141. package/src/components/StateViewSlice_Builder_Stream.res +6 -4
  142. package/src/components/Task_Builder_PerBucket.res +10 -11
  143. package/src/plugin/cloner/ClonerRunner_Fargate.res +3 -10
  144. package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res +1 -4
  145. package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res +5 -5
  146. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +19 -21
  147. package/src/plugin/runtime/PluginRuntime_Builder.res +167 -188
  148. package/src/plugin/runtime/Util_PluginMessage_Runtime.res +6 -5
  149. package/src/plugin/stack/Plugin_Stack.res +104 -103
  150. package/src/util/Util_AlarmSpec.res +2 -1
  151. package/src/util/Util_AppSync.res +8 -2
  152. package/src/util/Util_AppSync_Caller.res +15 -14
  153. package/src/util/Util_Bundle.res +46 -42
  154. package/src/util/Util_CognitoGroupUser_Runtime.res +32 -34
  155. package/src/util/Util_Cognito_Runtime.res +11 -7
  156. package/src/util/Util_DeadLetterQueue.res +12 -2
  157. package/src/util/Util_DynamoDb.res +5 -3
  158. package/src/util/Util_DynamoDbStream.res +7 -3
  159. package/src/util/Util_DynamoDbStream_Runtime.res +1 -2
  160. package/src/util/Util_DynamoDb_Runtime.res +23 -41
  161. package/src/util/Util_HostUiDomain.res +6 -1
  162. package/src/util/Util_Kinesis_Runtime.res +10 -11
  163. package/src/util/Util_Lambda.res +12 -5
  164. package/src/util/Util_LambdaEnvBudget.res +5 -5
  165. package/src/util/Util_LambdaLogging.res +1 -2
  166. package/src/util/Util_LogGroup_Adopting.res +1 -4
  167. package/src/util/Util_ResourceNaming.res +1 -2
  168. package/src/util/Util_SNS.res +8 -3
  169. package/src/util/Util_SNS_FIFO.res +1 -1
  170. package/src/util/Util_SNS_Runtime.res +11 -10
  171. package/src/util/Util_SQS.res +4 -2
  172. package/src/util/Util_SQS_FIFO.res +5 -2
  173. package/src/util/Util_SQS_Runtime.res +37 -36
  174. package/src/util/Util_ShellConfig.res +3 -2
  175. package/src/util/Util_StaticBundle.res +1 -3
  176. package/src/util/Util_StoreLayout.res +4 -1
  177. package/tests/AWS_TagsTest.res +16 -5
  178. package/tests/AppSyncEventsSigner_OpsTest.res +11 -2
  179. package/tests/AppSync_AdapterTest.res +286 -224
  180. package/tests/AppSync_AdapterTest.res.mjs +69 -0
  181. package/tests/AppSync_Resolver_RetryingTest.res +64 -44
  182. package/tests/AppSync_RetirementNarrowingTest.res +59 -46
  183. package/tests/AppSync_SdlDecorateTest.res +22 -20
  184. package/tests/AppSync_SourceApiAssociation_RetryingTest.res +40 -22
  185. package/tests/Auth_ActiveRolePoolAttachmentTest.res +114 -107
  186. package/tests/Auth_ActiveRoleStoreTest.res +12 -9
  187. package/tests/Auth_ActiveRoleStore_SchemaTest.res +2 -1
  188. package/tests/Auth_ActiveRoleTrigger_OpsTest.res +20 -16
  189. package/tests/Auth_CognitoTest.res +31 -46
  190. package/tests/Auth_LoginIdentifierTest.res +51 -0
  191. package/tests/Auth_LoginIdentifierTest.res.mjs +51 -0
  192. package/tests/Auth_SignUpModeTest.res +56 -0
  193. package/tests/Auth_SignUpModeTest.res.mjs +53 -0
  194. package/tests/AutomationSliceEntryPoint_OpsTest.res +69 -67
  195. package/tests/BakeConvergenceTest.res +22 -25
  196. package/tests/Capability_MessagingTest.res +28 -12
  197. package/tests/CommandTopicQueuePolicyTest.res +1 -2
  198. package/tests/CounterEntryPoint_OpsTest.res +3 -7
  199. package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res +306 -210
  200. package/tests/EventCollectorConnectLambdaPreviewTest.res +14 -7
  201. package/tests/EventCollectorEntryPoint_OpsTest.res +12 -4
  202. package/tests/EventCollectorPluginDefinitionAssetTest.res +18 -11
  203. package/tests/EventCollectorReadyGateTest.res +5 -4
  204. package/tests/EventLogStorage_DynamoDb_RuntimeTest.res +1 -2
  205. package/tests/EventMapperEntryPoint_OpsTest.res +1 -3
  206. package/tests/ExtensionPointEntryPoint_OpsTest.res +1 -4
  207. package/tests/HandlerFactoryDispatchTest.res +97 -70
  208. package/tests/MCP_LambdaTest.res +16 -27
  209. package/tests/PgChangeFeedRelay_IntegrationTest.res +123 -93
  210. package/tests/PgChangeFeedRelay_RuntimeTest.res +13 -10
  211. package/tests/PgMigrationEntryPoint_IntegrationTest.res +0 -1
  212. package/tests/PgPipeline_IntegrationTest.res +80 -66
  213. package/tests/PgQueryDbUnion_IntegrationTest.res +1 -2
  214. package/tests/PgQueryResolverEntryPoint_OpsTest.res +2 -6
  215. package/tests/PgQueryResolver_LambdaTest.res +41 -24
  216. package/tests/Platform_AdminScan_OpsTest.res +4 -1
  217. package/tests/Platform_ComponentDefinitions_Lambda_OpsTest.res +137 -129
  218. package/tests/ProjectionEntryPoint_DisplayNameTest.res +7 -3
  219. package/tests/ProjectionEntryPoint_UnionStampTest.res +3 -2
  220. package/tests/ProvisionAccountsTest.res +142 -0
  221. package/tests/ProvisionAccountsTest.res.mjs +153 -0
  222. package/tests/ProvisionAdminTest.res +55 -0
  223. package/tests/ProvisionAdminTest.res.mjs +66 -0
  224. package/tests/ProvisionIdentityTest.res +91 -9
  225. package/tests/ProvisionIdentityTest.res.mjs +66 -1
  226. package/tests/QueryDbOwnerIndexTableTest.res +6 -4
  227. package/tests/QueryDbResolvers_AppSyncTest.res +23 -16
  228. package/tests/QueryInterceptor_LambdaTest.res +11 -13
  229. package/tests/ReadModelEntryPoint_OpsTest.res +43 -41
  230. package/tests/RuntimeExtensionEntryPoint_OpsTest.res +4 -3
  231. package/tests/SideEffectEntryPoint_OpsTest.res +23 -18
  232. package/tests/StateChangeDescriptorParityTest.res +28 -26
  233. package/tests/StateTopicKeySchemaTest.res +18 -15
  234. package/tests/StateViewSliceEntryPoint_OpsTest.res +55 -44
  235. package/tests/TaskBucketEntryPoint_OpsTest.res +13 -13
  236. package/tests/Upload_ClaimTest.res +3 -3
  237. package/tests/Util_AwsErrorTest.res +4 -7
  238. package/tests/Util_BundleDependencyClosureTest.res +15 -3
  239. package/tests/Util_BundleEsmLoaderTest.res +3 -3
  240. package/tests/Util_BundleResolveTest.res +4 -6
  241. package/tests/Util_BundleRuntimeExtensionTest.res +17 -18
  242. package/tests/Util_DcbMetricsTest.res +6 -6
  243. package/tests/Util_DynamoDbStreamTest.res +4 -5
  244. package/tests/Util_DynamoDbTest.res +3 -2
  245. package/tests/Util_LambdaEnvBudgetTest.res +22 -18
  246. package/tests/Util_LambdaLoggingTest.res +9 -8
  247. package/tests/Util_LogGroup_AdoptingTest.res +10 -5
  248. package/tests/Util_LogRetentionTest.res +6 -2
  249. package/tests/Util_OwnerScopeEnvTest.res +35 -8
  250. package/tests/Util_OwnerScopeEnvTest.res.mjs +13 -0
  251. package/tests/Util_SQS_RuntimeTest.res +5 -7
  252. package/tests/Util_ShellConfigTest.res +7 -17
  253. package/tests/Util_StaticBundleTest.res +3 -8
  254. package/tests/Util_StoreLayoutTest.res +17 -12
  255. package/tests/integration/AggregateEntryPoint_IntegrationTest.res +1 -4
  256. package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +15 -15
  257. package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +296 -232
  258. package/tests/integration/DcbIntegrationHarness.res +8 -8
  259. package/tests/integration/EpCompositeSlice.res +16 -8
  260. package/tests/integration/QueryDbUnion_DynamoDb_IntegrationTest.res +8 -10
  261. package/tests/integration/StateViewSliceEntryPoint_IntegrationTest.res +10 -10
  262. package/tests/integration/SvsTestSlice_Projection.res +1 -3
  263. package/tests/util/Util_AlarmSpecTest.res +62 -49
@@ -16,7 +16,9 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
16
16
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
17
17
  import * as Plugin$ReventlessAws from "./components/Plugin.res.mjs";
18
18
  import * as Util_Sury$Reventless from "@reventlessdev/reventless-spec/src/util/Util_Sury.res.mjs";
19
+ import * as AdminGroup$Reventless from "@reventlessdev/reventless-spec/src/types/AdminGroup.res.mjs";
19
20
  import * as Logger$ReventlessCore from "@reventlessdev/reventless-core/src/util/Logger.res.mjs";
21
+ import * as OwnerScope$Reventless from "@reventlessdev/reventless-spec/src/types/OwnerScope.res.mjs";
20
22
  import * as Plugin$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/component/Plugin.res.mjs";
21
23
  import * as AWS_Tags$ReventlessAws from "./adapter/AWS_Tags.res.mjs";
22
24
  import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
@@ -150,6 +152,7 @@ let messagingEmailProviderRef = {
150
152
  };
151
153
 
152
154
  function MakeWithConfig(Config) {
155
+ OwnerScope$Reventless.defaultElevatedGroups([AdminGroup$Reventless.name]);
153
156
  Stdlib_Option.forEach(Config.commandHandlerConfig.aggregates, param => {
154
157
  Stdlib_Option.forEach(param.sync, AggregateRuntime_Builder_Single$ReventlessAws.setConfig);
155
158
  Stdlib_Option.forEach(param.async, AggregateRuntime_Builder_Single_Async$ReventlessAws.setConfig);
@@ -211,7 +214,7 @@ function MakeWithConfig(Config) {
211
214
  subscriptionSources: []
212
215
  });
213
216
  let adminSourceSdl = () => {
214
- let baseFragment = AppSync_Adapter$ReventlessAws.injectAwsAuthAll(Platform_AdminApi$ReventlessCore.baseFragment(Config.cloner), "Admin", undefined);
217
+ let baseFragment = AppSync_Adapter$ReventlessAws.injectAwsAuthAll(Platform_AdminApi$ReventlessCore.baseFragment(Config.cloner), AdminGroup$Reventless.name, undefined);
215
218
  return AppSync_SdlDecorate$ReventlessAws.stampCanonicalTypes(AppSync_Adapter$ReventlessAws.stitchStandaloneWithAwsDirectives(baseFragment));
216
219
  };
217
220
  let match;
@@ -687,7 +690,8 @@ function MakeWithConfig(Config) {
687
690
  };
688
691
  let provisionPgChangeFeedRelay = () => {
689
692
  let feedTargets = (connectionConfig, logName, feed, isClassic) => Stdlib_Array.filterMap(PgProjectionFeed$ReventlessAws.getFeedQueues(), fq => {
690
- if (isClassic ? fq.includeClassic : fq.includeDcb) {
693
+ let included = isClassic ? fq.includeClassic : fq.includeDcb;
694
+ if (included) {
691
695
  return {
692
696
  connectionConfig: connectionConfig,
693
697
  logName: logName,
@@ -1438,10 +1442,13 @@ function MakeWithConfig(Config) {
1438
1442
  if (missing.length !== 0) {
1439
1443
  Stdlib_JsError.throwWithMessage(CapabilityNeed$Reventless.unmetMessage(missing) + Belt_SetString.toArray(Belt_SetString.fromArray(missing.map(u => {
1440
1444
  let match = u.need;
1441
- if (match === "Geocoding") {
1442
- return `\n Geocoding is \`Capability_Geocoding_AwsLocation.make\`, passed to the platform as \`~geocoderPlaceIndex\`.`;
1443
- } else {
1444
- return `\n Messaging is \`Capability_Messaging.make\`, passed to the platform as \`~messagingSender\`. The sender itself is configuration and has no default: set \`platform:messagingEmailSender\` in Pulumi.<stack>.yaml (or REVENTLESS_MESSAGING_EMAIL_SENDER), then verify the address with SES — or \`platform:messagingEmailProvider: log\` to log every message and send none.`;
1445
+ switch (match) {
1446
+ case "Geocoding" :
1447
+ return `\n Geocoding is \`Capability_Geocoding_AwsLocation.make\`, passed to the platform as \`~geocoderPlaceIndex\`.`;
1448
+ case "Messaging" :
1449
+ return `\n Messaging is \`Capability_Messaging.make\`, passed to the platform as \`~messagingSender\`. The sender itself is configuration and has no default: set \`platform:messagingEmailSender\` in Pulumi.<stack>.yaml (or REVENTLESS_MESSAGING_EMAIL_SENDER), then verify the address with SES — or \`platform:messagingEmailProvider: log\` to log every message and send none.`;
1450
+ case "IdentityProvider" :
1451
+ return `\n IdentityProvider has no backend on any platform yet — the seam and the refusal exist, the Cognito and local implementations do not. A plugin declaring this need cannot be deployed until one lands; nothing about this deployment's configuration will change that.`;
1445
1452
  }
1446
1453
  }))).join(""));
1447
1454
  }
@@ -1549,6 +1556,7 @@ function MakeWithConfig(Config) {
1549
1556
 
1550
1557
  function Make($star) {
1551
1558
  let commandHandlerConfig = {};
1559
+ OwnerScope$Reventless.defaultElevatedGroups([AdminGroup$Reventless.name]);
1552
1560
  Stdlib_Option.forEach(commandHandlerConfig.aggregates, param => {
1553
1561
  Stdlib_Option.forEach(param.sync, AggregateRuntime_Builder_Single$ReventlessAws.setConfig);
1554
1562
  Stdlib_Option.forEach(param.async, AggregateRuntime_Builder_Single_Async$ReventlessAws.setConfig);
@@ -1610,7 +1618,7 @@ function Make($star) {
1610
1618
  subscriptionSources: []
1611
1619
  });
1612
1620
  let adminSourceSdl = () => {
1613
- let baseFragment = AppSync_Adapter$ReventlessAws.injectAwsAuthAll(Platform_AdminApi$ReventlessCore.baseFragment(false), "Admin", undefined);
1621
+ let baseFragment = AppSync_Adapter$ReventlessAws.injectAwsAuthAll(Platform_AdminApi$ReventlessCore.baseFragment(false), AdminGroup$Reventless.name, undefined);
1614
1622
  return AppSync_SdlDecorate$ReventlessAws.stampCanonicalTypes(AppSync_Adapter$ReventlessAws.stitchStandaloneWithAwsDirectives(baseFragment));
1615
1623
  };
1616
1624
  let match;
@@ -2086,7 +2094,8 @@ function Make($star) {
2086
2094
  };
2087
2095
  let provisionPgChangeFeedRelay = () => {
2088
2096
  let feedTargets = (connectionConfig, logName, feed, isClassic) => Stdlib_Array.filterMap(PgProjectionFeed$ReventlessAws.getFeedQueues(), fq => {
2089
- if (isClassic ? fq.includeClassic : fq.includeDcb) {
2097
+ let included = isClassic ? fq.includeClassic : fq.includeDcb;
2098
+ if (included) {
2090
2099
  return {
2091
2100
  connectionConfig: connectionConfig,
2092
2101
  logName: logName,
@@ -2812,10 +2821,13 @@ function Make($star) {
2812
2821
  if (missing.length !== 0) {
2813
2822
  Stdlib_JsError.throwWithMessage(CapabilityNeed$Reventless.unmetMessage(missing) + Belt_SetString.toArray(Belt_SetString.fromArray(missing.map(u => {
2814
2823
  let match = u.need;
2815
- if (match === "Geocoding") {
2816
- return `\n Geocoding is \`Capability_Geocoding_AwsLocation.make\`, passed to the platform as \`~geocoderPlaceIndex\`.`;
2817
- } else {
2818
- return `\n Messaging is \`Capability_Messaging.make\`, passed to the platform as \`~messagingSender\`. The sender itself is configuration and has no default: set \`platform:messagingEmailSender\` in Pulumi.<stack>.yaml (or REVENTLESS_MESSAGING_EMAIL_SENDER), then verify the address with SES — or \`platform:messagingEmailProvider: log\` to log every message and send none.`;
2824
+ switch (match) {
2825
+ case "Geocoding" :
2826
+ return `\n Geocoding is \`Capability_Geocoding_AwsLocation.make\`, passed to the platform as \`~geocoderPlaceIndex\`.`;
2827
+ case "Messaging" :
2828
+ return `\n Messaging is \`Capability_Messaging.make\`, passed to the platform as \`~messagingSender\`. The sender itself is configuration and has no default: set \`platform:messagingEmailSender\` in Pulumi.<stack>.yaml (or REVENTLESS_MESSAGING_EMAIL_SENDER), then verify the address with SES — or \`platform:messagingEmailProvider: log\` to log every message and send none.`;
2829
+ case "IdentityProvider" :
2830
+ return `\n IdentityProvider has no backend on any platform yet — the seam and the refusal exist, the Cognito and local implementations do not. A plugin declaring this need cannot be deployed until one lands; nothing about this deployment's configuration will change that.`;
2819
2831
  }
2820
2832
  }))).join(""));
2821
2833
  }
@@ -45,7 +45,9 @@
45
45
  // The "proper" fix — `inboundAppSyncResolverParams<'runtimeParts>` — would
46
46
  // require propagating `'runtimeParts` through `platformHooks`, `Plugin_Builder`,
47
47
  // and `Admin`.
48
- external asLambdaRuntime: ReventlessCore.Runtime.environment<unknown> => ReventlessCore.Runtime.environment<Util.Lambda.runtimeParts> = "%identity"
48
+ external asLambdaRuntime: ReventlessCore.Runtime.environment<
49
+ unknown,
50
+ > => ReventlessCore.Runtime.environment<Util.Lambda.runtimeParts> = "%identity"
49
51
 
50
52
  // ─────────────────────────────────────────────────────────────────────────────
51
53
  // CAST 2 — hook callback arguments (unknown → concrete component types)
@@ -62,8 +64,13 @@ external asLambdaRuntime: ReventlessCore.Runtime.environment<unknown> => Reventl
62
64
  // `reventless-core` cannot import `DcbEventLog.component`, `CommandTopic.component`,
63
65
  // or `CommandTopic_Adapter.remoteChannel`. The AWS platform registers these
64
66
  // callbacks and is the only caller, always passing the correct concrete value.
65
- external asDcbEventLogComponent: unknown => ReventlessCore.Component.t<unit, ReventlessCore.DcbEventLog.outputs, unit> = "%identity"
66
- external asDcbCommandTopicComponent: unknown => ReventlessCore.CommandTopic.component<unit> = "%identity"
67
+ external asDcbEventLogComponent: unknown => ReventlessCore.Component.t<
68
+ unit,
69
+ ReventlessCore.DcbEventLog.outputs,
70
+ unit,
71
+ > = "%identity"
72
+ external asDcbCommandTopicComponent: unknown => ReventlessCore.CommandTopic.component<unit> =
73
+ "%identity"
67
74
  external asDcbEventLog: unknown => ReventlessCore.DcbEventLog.component = "%identity"
68
75
  external asRemoteChannel: unknown => ReventlessCore.CommandTopic_Adapter.remoteChannel = "%identity"
69
76
 
@@ -103,4 +110,6 @@ external asSqsChannelParts: 'a => Util.SQS.channelParts = "%identity"
103
110
  // level — it is a mismatch between ReScript's JS boxing convention and Pulumi's
104
111
  // Proxy-based lazy evaluation model.
105
112
  external _toUnknown: 'a => unknown = "%identity"
106
- let wrapHookedValue: 'a => ReventlessCore.Plugin_Helpers.hookedValue<unknown> = x => {val: x->_toUnknown}
113
+ let wrapHookedValue: 'a => ReventlessCore.Plugin_Helpers.hookedValue<unknown> = x => {
114
+ val: x->_toUnknown,
115
+ }
@@ -12,15 +12,24 @@ type cognitoUserPool = {
12
12
  is declared with the trigger's ARN), while the mutation that writes it is
13
13
  provisioned after the API — see [Auth_ActiveRoleStore.res]. */
14
14
  activeRoleTable: Auth_ActiveRoleStore.storeTable,
15
+ /** The sign-in attribute this stack created the pool with. `None` in BYO mode:
16
+ the pool's own choice was made elsewhere and no lookup here reads it back,
17
+ so reporting one would be a guess. */
18
+ loginIdentifier: option<Auth_LoginIdentifier.t>,
15
19
  }
16
20
 
17
21
  /**
18
22
  * Resolve the Cognito UserPool used by AppSync auth. Two modes:
19
23
  *
20
24
  * - **Auto**: no `platform:identityProviderId` config — create a fresh UserPool
21
- * with SPA-friendly defaults (email username, 12-char password policy, no
22
- * MFA, admin-only user creation). Caller is responsible for creating
23
- * groups (`Admin`, `User`, …) and users via the AWS console / CLI.
25
+ * with SPA-friendly defaults (email sign-in unless `platform:loginIdentifier`
26
+ * says otherwise, 12-char password policy, no MFA, and admin-only user
27
+ * creation unless `platform:signUpMode` says otherwise), plus the
28
+ * administrator group named by [Reventless.AdminGroup] and an elevated-groups
29
+ * default naming it. What it does **not** create is the first administrator:
30
+ * accounts are not stack resources, and a pool full of them is not something a
31
+ * `pulumi destroy` should be able to empty. `provision-admin` makes that one,
32
+ * and no step of this needs the AWS console.
24
33
  *
25
34
  * - **BYO**: provider ID provided — skip pool creation, look up the existing
26
35
  * pool via `aws.cognito.getUserPool` for its ARN. Lookup precedence
@@ -38,10 +47,21 @@ type cognitoUserPool = {
38
47
  * Pulumi can destroy without touching the parent pool).
39
48
  *
40
49
  * Always exports `identityProviderId`, `identityProviderClientId`,
41
- * `identityProviderArn`, `identityProviderRegion`, `identityProviderManaged` and
42
- * `activeRoleStore` as stack outputs so downstream stacks (and Stage D AppSync
43
- * wiring) can read them via `StackReference` — plus, for one release, the
44
- * deprecated `cognito*` spellings of the first five.
50
+ * `identityProviderArn`, `identityProviderRegion`, `identityProviderManaged`,
51
+ * `identityProviderLoginIdentifier`, `identityProviderAdminGroup` and
52
+ * `activeRoleStore` as stack outputs so
53
+ * downstream stacks (and Stage D AppSync wiring) can read them via
54
+ * `StackReference` — plus, for one release, the deprecated `cognito*` spellings
55
+ * of the first five.
56
+ *
57
+ * 🚨 In auto mode `platform:loginIdentifier` picks the sign-in attribute, and it
58
+ * is the one setting no later deploy can correct: changing it replaces the pool
59
+ * and empties it. Absent means `email`. See [Auth_LoginIdentifier].
60
+ *
61
+ * `platform:signUpMode` decides whether a stranger may register themselves.
62
+ * Absent means `adminOnly`. It is the opposite kind of setting — an ordinary
63
+ * in-place update, free and reversible on a pool full of accounts — but on a
64
+ * pool shared between stacks the flip is pool-wide. See [Auth_SignUpMode].
45
65
  *
46
66
  * Also provisions the role-state table and the pre-token-generation trigger that
47
67
  * narrows `cognito:groups` to a caller's chosen role. They belong here rather
@@ -86,6 +106,42 @@ let _identityProviderId = (~cfg: Pulumi.Config.t): option<string> => {
86
106
  }
87
107
  }
88
108
 
109
+ /** The sign-in attribute for a pool this stack creates, from
110
+ `platform:loginIdentifier` (or `REVENTLESS_LOGIN_IDENTIFIER` / the sidecar).
111
+
112
+ Absent means `email`, which is what every pool so far was created with. An
113
+ unrecognised spelling fails the deploy — see [Auth_LoginIdentifier] for why
114
+ defaulting past a typo here is unrecoverable. */
115
+ let _loginIdentifier = (~cfg: Pulumi.Config.t): Auth_LoginIdentifier.t => {
116
+ let raw = switch Util_LocalConfig.get("loginIdentifier") {
117
+ | Some(_) as v => v
118
+ | None => cfg->Pulumi.Config.get("loginIdentifier")
119
+ }
120
+ switch Auth_LoginIdentifier.parse(raw) {
121
+ | Ok(identifier) => identifier
122
+ | Error(message) => JsError.throwWithMessage(message)
123
+ }
124
+ }
125
+
126
+ /** Whether a stranger may create their own account in a pool this stack creates,
127
+ from `platform:signUpMode` (or `REVENTLESS_SIGN_UP_MODE` / the sidecar).
128
+
129
+ Absent means `adminOnly`, which is what every pool so far was created with, so
130
+ an existing stack redeploys unchanged. Unlike the sign-in attribute this is an
131
+ ordinary in-place update on a live pool — but an unrecognised spelling still
132
+ fails the deploy, because defaulting past it would refuse every registration
133
+ while the config read as if it allowed them. See [Auth_SignUpMode]. */
134
+ let _signUpMode = (~cfg: Pulumi.Config.t): Auth_SignUpMode.t => {
135
+ let raw = switch Util_LocalConfig.get("signUpMode") {
136
+ | Some(_) as v => v
137
+ | None => cfg->Pulumi.Config.get("signUpMode")
138
+ }
139
+ switch Auth_SignUpMode.parse(raw) {
140
+ | Ok(mode) => mode
141
+ | Error(message) => JsError.throwWithMessage(message)
142
+ }
143
+ }
144
+
89
145
  let _resolveUncached = (): cognitoUserPool => {
90
146
  let cfg = Pulumi.Config.make(Some("platform"))
91
147
  let existingPoolId = _identityProviderId(~cfg)
@@ -183,11 +239,19 @@ let _resolveUncached = (): cognitoUserPool => {
183
239
  poolArn: lookup->Pulumi.Output.apply(r => r.arn),
184
240
  managed: false,
185
241
  activeRoleTable,
242
+ loginIdentifier: None,
186
243
  }
187
244
 
188
245
  | None =>
246
+ let loginIdentifier = _loginIdentifier(~cfg)
247
+ let signUpMode = _signUpMode(~cfg)
248
+ // In place, unlike the sign-in attribute below: `AdminCreateUserConfig` is a
249
+ // member of `UpdateUserPoolRequest`, so flipping this on a pool full of
250
+ // accounts is an ordinary update rather than a replacement.
189
251
  let adminConfig: PulumiAws.Cognito.UserPool.adminCreateUserConfig = {
190
- allowAdminCreateUserOnly: Pulumi.Input.make(true),
252
+ allowAdminCreateUserOnly: Pulumi.Input.make(
253
+ signUpMode->Auth_SignUpMode.allowAdminCreateUserOnly,
254
+ ),
191
255
  }
192
256
  let pwdPolicy: PulumiAws.Cognito.UserPool.passwordPolicy = {
193
257
  minimumLength: Pulumi.Input.make(12),
@@ -204,7 +268,13 @@ let _resolveUncached = (): cognitoUserPool => {
204
268
  ~name="HostUiPool",
205
269
  ~args={
206
270
  adminCreateUserConfig: Pulumi.Input.make(adminConfig),
207
- usernameAttributes: Pulumi.Input.make([Pulumi.Input.make("email")]),
271
+ // 🚨 Changing this on a live stack replaces the pool and empties it —
272
+ // Cognito has no update for the sign-in attribute. Chosen once, here.
273
+ usernameAttributes: Pulumi.Input.make(
274
+ loginIdentifier
275
+ ->Auth_LoginIdentifier.usernameAttributes
276
+ ->Array.map(Pulumi.Input.make),
277
+ ),
208
278
  passwordPolicy: Pulumi.Input.make(pwdPolicy),
209
279
  mfaConfiguration: Pulumi.Input.make("OFF"),
210
280
  lambdaConfig: Pulumi.Input.make({
@@ -219,6 +289,23 @@ let _resolveUncached = (): cognitoUserPool => {
219
289
  },
220
290
  )
221
291
 
292
+ // The administrator group, declared beside the pool that holds it.
293
+ //
294
+ // Auto mode only, and the restriction is the point: a group is a pool-level
295
+ // fact, and on a pool this stack does not own those are not this stack's to
296
+ // declare. Two stacks pointed at one shared provider would each declare this
297
+ // group, and the second would fail on a name that already exists — the same
298
+ // split, for the same reason, as [Auth_SignUpMode] and the active-role store.
299
+ // The BYO half is `provision-admin`, which creates the group beside the first
300
+ // administrator who needs it.
301
+ //
302
+ // An ordinary child resource: the pool is ours, so this needs no out-of-band
303
+ // call and Pulumi's state stays the authority for whether it exists.
304
+ let _adminGroup = Util_CognitoGroupUser.addUserGroup(
305
+ ~name=Reventless.AdminGroup.name,
306
+ ~userPoolId=pool.id,
307
+ )
308
+
222
309
  let tokenUnits2: PulumiAws.Cognito.UserPoolClient.tokenValidityUnits = {
223
310
  accessToken: Pulumi.Input.make("minutes"),
224
311
  idToken: Pulumi.Input.make("minutes"),
@@ -247,6 +334,7 @@ let _resolveUncached = (): cognitoUserPool => {
247
334
  poolArn: pool.arn,
248
335
  managed: true,
249
336
  activeRoleTable,
337
+ loginIdentifier: Some(loginIdentifier),
250
338
  }
251
339
  }
252
340
 
@@ -279,11 +367,23 @@ let _resolveUncached = (): cognitoUserPool => {
279
367
  let managedStr = Pulumi.Output.make(result.managed ? "true" : "false")
280
368
  let regionOutput = Pulumi.Output.make(regionStr)
281
369
 
370
+ // The sign-in attribute is unchangeable after creation, so the value a pool was
371
+ // born with has to be readable somewhere other than the source that has since
372
+ // moved on. `unknown` for a BYO pool: this stack did not choose it and does not
373
+ // read it back.
374
+ let loginIdentifierStr = Pulumi.Output.make(
375
+ switch result.loginIdentifier {
376
+ | Some(identifier) => Auth_LoginIdentifier.toString(identifier)
377
+ | None => "unknown"
378
+ },
379
+ )
380
+
282
381
  Pulumi.Pulumi.export("identityProviderId", result.poolId)
283
382
  Pulumi.Pulumi.export("identityProviderClientId", result.clientId)
284
383
  Pulumi.Pulumi.export("identityProviderArn", result.poolArn)
285
384
  Pulumi.Pulumi.export("identityProviderRegion", regionOutput)
286
385
  Pulumi.Pulumi.export("identityProviderManaged", managedStr)
386
+ Pulumi.Pulumi.export("identityProviderLoginIdentifier", loginIdentifierStr)
287
387
 
288
388
  // Deprecated spellings — see above.
289
389
  Pulumi.Pulumi.export("cognitoUserPoolId", result.poolId)
@@ -292,6 +392,16 @@ let _resolveUncached = (): cognitoUserPool => {
292
392
  Pulumi.Pulumi.export("cognitoRegion", regionOutput)
293
393
  Pulumi.Pulumi.export("cognitoUserPoolManaged", managedStr)
294
394
 
395
+ // The group that administers this deployment, readable without reading source.
396
+ // `provision-admin` puts its first user in it, and a deployment overriding who
397
+ // is elevated needs to know which name it is overriding.
398
+ //
399
+ // Exported in both pool modes although only auto mode *declares* the group: the
400
+ // name is what a caller needs either way, and an output that appeared in one
401
+ // mode and not the other would read as "there is no administrator group here"
402
+ // rather than "this stack did not create it".
403
+ Pulumi.Pulumi.export("identityProviderAdminGroup", Pulumi.Output.make(Reventless.AdminGroup.name))
404
+
295
405
  // Exported so an operator can read back the store this provider resolved to —
296
406
  // the name is derived, not configured, so this is a convenience for checking
297
407
  // rather than a value anything is meant to copy into a config.
@@ -4,10 +4,15 @@ import * as Aws from "@pulumi/aws";
4
4
  import * as Pulumi$Pulumi from "@reventlessdev/rescript-pulumi-pulumi/src/Pulumi.res.mjs";
5
5
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
6
6
  import * as Pulumi from "@pulumi/pulumi";
7
+ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
8
+ import * as AdminGroup$Reventless from "@reventlessdev/reventless-spec/src/types/AdminGroup.res.mjs";
7
9
  import * as Logger$ReventlessCore from "@reventlessdev/reventless-core/src/util/Logger.res.mjs";
8
10
  import * as AWS_Tags$ReventlessAws from "./adapter/AWS_Tags.res.mjs";
11
+ import * as Auth_SignUpMode$ReventlessAws from "./adapter/Auth/Auth_SignUpMode.res.mjs";
9
12
  import * as Util_LocalConfig$ReventlessAws from "./util/Util_LocalConfig.res.mjs";
10
13
  import * as Auth_ActiveRoleStore$ReventlessAws from "./adapter/Auth/Auth_ActiveRoleStore.res.mjs";
14
+ import * as Auth_LoginIdentifier$ReventlessAws from "./adapter/Auth/Auth_LoginIdentifier.res.mjs";
15
+ import * as Util_CognitoGroupUser$ReventlessAws from "./util/Util_CognitoGroupUser.res.mjs";
11
16
  import * as Auth_ActiveRoleTrigger$ReventlessAws from "./adapter/Auth/Auth_ActiveRoleTrigger.res.mjs";
12
17
  import * as Auth_ActiveRolePoolAttachment$ReventlessAws from "./adapter/Auth/Auth_ActiveRolePoolAttachment.res.mjs";
13
18
 
@@ -35,6 +40,28 @@ function _identityProviderId(cfg) {
35
40
  }
36
41
  }
37
42
 
43
+ function _loginIdentifier(cfg) {
44
+ let v = Util_LocalConfig$ReventlessAws.get("loginIdentifier");
45
+ let raw = v !== undefined ? v : cfg.get("loginIdentifier");
46
+ let identifier = Auth_LoginIdentifier$ReventlessAws.parse(raw);
47
+ if (identifier.TAG === "Ok") {
48
+ return identifier._0;
49
+ } else {
50
+ return Stdlib_JsError.throwWithMessage(identifier._0);
51
+ }
52
+ }
53
+
54
+ function _signUpMode(cfg) {
55
+ let v = Util_LocalConfig$ReventlessAws.get("signUpMode");
56
+ let raw = v !== undefined ? v : cfg.get("signUpMode");
57
+ let mode = Auth_SignUpMode$ReventlessAws.parse(raw);
58
+ if (mode.TAG === "Ok") {
59
+ return mode._0;
60
+ } else {
61
+ return Stdlib_JsError.throwWithMessage(mode._0);
62
+ }
63
+ }
64
+
38
65
  function _resolveUncached() {
39
66
  let cfg = new Pulumi.Config("platform");
40
67
  let existingPoolId = _identityProviderId(cfg);
@@ -77,11 +104,14 @@ function _resolveUncached() {
77
104
  clientId: client.id,
78
105
  poolArn: lookup.apply(r => r.arn),
79
106
  managed: false,
80
- activeRoleTable: activeRoleTable
107
+ activeRoleTable: activeRoleTable,
108
+ loginIdentifier: undefined
81
109
  };
82
110
  } else {
111
+ let loginIdentifier = _loginIdentifier(cfg);
112
+ let signUpMode = _signUpMode(cfg);
83
113
  let adminConfig = {
84
- allowAdminCreateUserOnly: true
114
+ allowAdminCreateUserOnly: Auth_SignUpMode$ReventlessAws.allowAdminCreateUserOnly(signUpMode)
85
115
  };
86
116
  let pwdPolicy_minimumLength = 12;
87
117
  let pwdPolicy_requireLowercase = true;
@@ -98,11 +128,12 @@ function _resolveUncached() {
98
128
  preTokenGeneration: activeRoleTrigger.functionArn
99
129
  },
100
130
  adminCreateUserConfig: adminConfig,
101
- usernameAttributes: ["email"],
131
+ usernameAttributes: Auth_LoginIdentifier$ReventlessAws.usernameAttributes(loginIdentifier).map(prim => prim),
102
132
  passwordPolicy: pwdPolicy,
103
133
  mfaConfiguration: "OFF",
104
134
  tags: AWS_Tags$ReventlessAws.make("HostUiPool", "Platform", "Auth", "Platform", undefined, undefined, undefined, undefined)
105
135
  });
136
+ Util_CognitoGroupUser$ReventlessAws.addUserGroup(AdminGroup$Reventless.name, pool.id);
106
137
  let tokenUnits2_accessToken = "minutes";
107
138
  let tokenUnits2_idToken = "minutes";
108
139
  let tokenUnits2_refreshToken = "days";
@@ -129,23 +160,28 @@ function _resolveUncached() {
129
160
  clientId: client$1.id,
130
161
  poolArn: pool.arn,
131
162
  managed: true,
132
- activeRoleTable: activeRoleTable
163
+ activeRoleTable: activeRoleTable,
164
+ loginIdentifier: loginIdentifier
133
165
  };
134
166
  }
135
167
  Auth_ActiveRoleTrigger$ReventlessAws.grantInvoke(activeRoleTrigger, result.poolArn, undefined, {});
136
168
  let regionStr = Stdlib_Option.getOr(new Pulumi.Config("aws").get("region"), "unknown");
137
169
  let managedStr = Pulumi.output(result.managed ? "true" : "false");
138
170
  let regionOutput = Pulumi.output(regionStr);
171
+ let identifier = result.loginIdentifier;
172
+ let loginIdentifierStr = Pulumi.output(identifier !== undefined ? Auth_LoginIdentifier$ReventlessAws.toString(identifier) : "unknown");
139
173
  Pulumi$Pulumi.$$export("identityProviderId", result.poolId);
140
174
  Pulumi$Pulumi.$$export("identityProviderClientId", result.clientId);
141
175
  Pulumi$Pulumi.$$export("identityProviderArn", result.poolArn);
142
176
  Pulumi$Pulumi.$$export("identityProviderRegion", regionOutput);
143
177
  Pulumi$Pulumi.$$export("identityProviderManaged", managedStr);
178
+ Pulumi$Pulumi.$$export("identityProviderLoginIdentifier", loginIdentifierStr);
144
179
  Pulumi$Pulumi.$$export("cognitoUserPoolId", result.poolId);
145
180
  Pulumi$Pulumi.$$export("cognitoUserPoolClientId", result.clientId);
146
181
  Pulumi$Pulumi.$$export("cognitoUserPoolArn", result.poolArn);
147
182
  Pulumi$Pulumi.$$export("cognitoRegion", regionOutput);
148
183
  Pulumi$Pulumi.$$export("cognitoUserPoolManaged", managedStr);
184
+ Pulumi$Pulumi.$$export("identityProviderAdminGroup", Pulumi.output(AdminGroup$Reventless.name));
149
185
  Pulumi$Pulumi.$$export("activeRoleStore", result.activeRoleTable.name);
150
186
  return result;
151
187
  }
@@ -168,6 +204,8 @@ export {
168
204
  log,
169
205
  _deprecatedPoolIdKey,
170
206
  _identityProviderId,
207
+ _loginIdentifier,
208
+ _signUpMode,
171
209
  _resolveUncached,
172
210
  _cached,
173
211
  resolveCognitoUserPool,
@@ -17,7 +17,9 @@ let sha256hex = (data: string): string =>
17
17
  let hmacFromStr = (key: string, data: string): NodeCrypto.buffer =>
18
18
  NodeCrypto.createHmac("sha256", key)->NodeCrypto.hmacUpdate(data)->NodeCrypto.hmacDigestBuffer
19
19
  let hmacFromBuf = (key: NodeCrypto.buffer, data: string): NodeCrypto.buffer =>
20
- NodeCrypto.createHmacFromBuffer("sha256", key)->NodeCrypto.hmacUpdate(data)->NodeCrypto.hmacDigestBuffer
20
+ NodeCrypto.createHmacFromBuffer("sha256", key)
21
+ ->NodeCrypto.hmacUpdate(data)
22
+ ->NodeCrypto.hmacDigestBuffer
21
23
 
22
24
  // ── SigV4 ───────────────────────────────────────────────────────────────────
23
25
 
@@ -71,7 +73,10 @@ let signedHeaders = (
71
73
  let kRegion = hmacFromBuf(kDate, region)
72
74
  let kService = hmacFromBuf(kRegion, "appsync")
73
75
  let kSigning = hmacFromBuf(kService, "aws4_request")
74
- let signature = NodeCrypto.createHmacFromBuffer("sha256", kSigning)->NodeCrypto.hmacUpdate(stringToSign)->NodeCrypto.hmacDigest("hex")
76
+ let signature =
77
+ NodeCrypto.createHmacFromBuffer("sha256", kSigning)
78
+ ->NodeCrypto.hmacUpdate(stringToSign)
79
+ ->NodeCrypto.hmacDigest("hex")
75
80
 
76
81
  let authorization = `AWS4-HMAC-SHA256 Credential=${creds.accessKeyId}/${scope}, SignedHeaders=${signedHeaderList}, Signature=${signature}`
77
82
  let out = Dict.fromArray(sorted)
@@ -115,5 +120,4 @@ let postEvent = async (
115
120
 
116
121
  // AppSync Events channel segments allow only [A-Za-z0-9-]; anything else
117
122
  // collapses to `-`. Mirrors the UI's AutoLive.normalizeSegment.
118
- let pathSegment = (value: string): string =>
119
- value->String.replaceRegExp(%re("/[^A-Za-z0-9-]/g"), "-")
123
+ let pathSegment = (value: string): string => value->String.replaceRegExp(/[^A-Za-z0-9-]/g, "-")
@@ -43,7 +43,6 @@
43
43
  installed, subscribe goes through the API-level auth modes only
44
44
  (single-tenant open-core case).
45
45
  */
46
-
47
46
  module Api = PulumiAws.AwsNative.AppSync.Api
48
47
  module ChannelNamespace = PulumiAws.AwsNative.AppSync.ChannelNamespace
49
48
 
@@ -158,15 +157,18 @@ let make = (
158
157
  let subscribeAuth = subscribeAuthRef.contents
159
158
  let codeHandlersInput: option<Pulumi.Input.t<string>> =
160
159
  subscribeAuth->Option.map(c => c.codeHandlers->Pulumi.Input.make)
161
- let handlerConfigsInput: option<Pulumi.Input.t<ChannelNamespace.handlerConfigsArgs>> =
162
- subscribeAuth->Option.map(c => {
160
+ let handlerConfigsInput: option<
161
+ Pulumi.Input.t<ChannelNamespace.handlerConfigsArgs>,
162
+ > = subscribeAuth->Option.map(c =>
163
+ {
163
164
  ChannelNamespace.onSubscribe: {
164
165
  ChannelNamespace.behavior: ChannelNamespace.handlerBehaviorCode->Pulumi.Input.make,
165
166
  integration: {
166
167
  ChannelNamespace.dataSourceName: c.dataSourceName,
167
168
  }->Pulumi.Input.make,
168
169
  }->Pulumi.Input.make,
169
- }->Pulumi.Input.make)
170
+ }->Pulumi.Input.make
171
+ )
170
172
  let defaultNamespace = ChannelNamespace.make(
171
173
  ~name=name ++ "DefaultNS",
172
174
  ~args={
@@ -182,14 +184,12 @@ let make = (
182
184
  // API-level `defaultPublishAuthModes` (IAM-only), so authenticated browsers
183
185
  // can publish ephemeral payloads on `/client/**` while `/default/**` change
184
186
  // descriptors stay Lambda-only.
185
- let clientAuthModes: Pulumi.Input.t<
186
- array<Pulumi.Input.t<ChannelNamespace.authMode>>,
187
- > =
187
+ let clientAuthModes: Pulumi.Input.t<array<Pulumi.Input.t<ChannelNamespace.authMode>>> =
188
188
  [
189
- ({authType: Api.amazonCognitoUserPools->Pulumi.Input.make}: ChannelNamespace.authMode)
190
- ->Pulumi.Input.make,
191
- ({authType: Api.awsIam->Pulumi.Input.make}: ChannelNamespace.authMode)
192
- ->Pulumi.Input.make,
189
+ (
190
+ {authType: Api.amazonCognitoUserPools->Pulumi.Input.make}: ChannelNamespace.authMode
191
+ )->Pulumi.Input.make,
192
+ ({authType: Api.awsIam->Pulumi.Input.make}: ChannelNamespace.authMode)->Pulumi.Input.make,
193
193
  ]->Pulumi.Input.make
194
194
  let clientNamespace = ChannelNamespace.make(
195
195
  ~name=name ++ "ClientNS",
@@ -208,6 +208,4 @@ let make = (
208
208
  /** HTTP endpoint URL for use as Lambda `APPSYNC_ENDPOINT` env var.
209
209
  Constructs `https://{dns.http}` from the raw domain name in the API output. */
210
210
  let httpEndpoint = (eventsApi: t): Pulumi.Output.t<string> =>
211
- eventsApi.api.dns->Pulumi.Output.apply(dns =>
212
- "https://" ++ dns.http->Option.getOr("")
213
- )
211
+ eventsApi.api.dns->Pulumi.Output.apply(dns => "https://" ++ dns.http->Option.getOr(""))
@@ -2,7 +2,6 @@
2
2
  `PulumiAws.AppSync.Resolver` that uses `@pulumi/aws-native` (Cloud Control
3
3
  API) so the CFN handler can internally wait out schema -> resolver
4
4
  propagation. See docs/plans/done/appsync-resolver-aws-native.md. */
5
-
6
5
  module Native = PulumiAws.AwsNative.AppSync.Resolver
7
6
  module Functions = PulumiAws.AppSync.Resolver.Functions
8
7
 
@@ -28,7 +27,7 @@ let makeUnitJsResolver = (
28
27
  code,
29
28
  runtime: Native.appsyncJs->Pulumi.Input.make,
30
29
  },
31
- ~opts=opts,
30
+ ~opts,
32
31
  )
33
32
 
34
33
  let makeSubscriptionResolverCode = (~filter: option<string>): string => {
@@ -62,7 +61,7 @@ let makeSubscriptionResolver = (
62
61
  code: makeSubscriptionResolverCode(~filter=subscriptionFilter)->Pulumi.Input.make,
63
62
  runtime: Native.appsyncJs->Pulumi.Input.make,
64
63
  },
65
- ~opts=opts,
64
+ ~opts,
66
65
  )
67
66
 
68
67
  let makePipelineJsResolver = (
@@ -89,5 +88,5 @@ let makePipelineJsResolver = (
89
88
  }: Native.pipelineConfig
90
89
  )->Pulumi.Input.make,
91
90
  },
92
- ~opts=opts,
91
+ ~opts,
93
92
  )