@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.
- package/CHANGELOG.md +36 -0
- package/package.json +15 -12
- package/run-provision-accounts.mjs +3 -0
- package/run-provision-admin.mjs +3 -0
- package/scripts/ProvisionAccounts.res +325 -0
- package/scripts/ProvisionAccounts.res.mjs +337 -0
- package/scripts/ProvisionAdmin.res +275 -0
- package/scripts/ProvisionAdmin.res.mjs +289 -0
- package/scripts/ProvisionCognito.res +149 -0
- package/scripts/ProvisionCognito.res.mjs +98 -0
- package/scripts/ProvisionIdentity.res +84 -14
- package/scripts/ProvisionIdentity.res.mjs +72 -7
- package/scripts/ProvisionProvider.res +104 -0
- package/scripts/ProvisionProvider.res.mjs +123 -0
- package/src/Platform.res +358 -329
- package/src/Platform.res.mjs +24 -12
- package/src/Platform_Casts.res +13 -4
- package/src/Platform_Stack.res +119 -9
- package/src/Platform_Stack.res.mjs +42 -4
- package/src/adapter/Api/AppSyncEventsSigner_Ops.res +8 -4
- package/src/adapter/Api/AppSync_EventsApi.res +12 -14
- package/src/adapter/Api/AppSync_Resolver_Native.res +3 -4
- package/src/adapter/Api/AppSync_Resolver_Retrying.res +78 -70
- package/src/adapter/Api/AppSync_SourceApiAssociation_Retrying.res +11 -8
- package/src/adapter/Api/Platform_AdminScan_Ops.res +15 -14
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +10 -2
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +40 -50
- package/src/adapter/Api/Platform_UIFragments_Lambda.res +39 -32
- package/src/adapter/Api/Platform_UIFragments_Lambda_Ops.res +5 -2
- package/src/adapter/Auth/Auth_ActiveRolePoolAttachment.res +0 -1
- package/src/adapter/Auth/Auth_ActiveRoleStore.res +1 -2
- package/src/adapter/Auth/Auth_ActiveRoleStore_Schema.res +1 -4
- package/src/adapter/Auth/Auth_ActiveRoleTrigger_Ops.res +5 -2
- package/src/adapter/Auth/Auth_Cognito.res +3 -9
- package/src/adapter/Auth/Auth_LoginIdentifier.res +66 -0
- package/src/adapter/Auth/Auth_LoginIdentifier.res.mjs +70 -0
- package/src/adapter/Auth/Auth_SignUpMode.res +78 -0
- package/src/adapter/Auth/Auth_SignUpMode.res.mjs +56 -0
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +1 -4
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res +3 -1
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res +1 -4
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +7 -4
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +6 -1
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +7 -4
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res +24 -18
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +9 -4
- package/src/adapter/CommandTopic/CommandTopicRegistry.res +1 -4
- package/src/adapter/Counter/CounterHandler_DynamoDbStream.res +15 -15
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res +9 -5
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +179 -213
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +5 -5
- package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res +6 -2
- package/src/adapter/EventCollector/EventCollectorChannel_SQS.res +14 -7
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res +14 -7
- package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res +6 -3
- package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res +6 -1
- package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res +13 -17
- package/src/adapter/EventLog/EventLogStorage_Postgres.res +7 -4
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +12 -7
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync_Ops.res +4 -2
- package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res +3 -2
- package/src/adapter/EventTopic/EventTopicPublisher_SNS.res +20 -12
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res +21 -9
- package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res +5 -3
- package/src/adapter/Geocoder/Geocoder_AwsLocation_Resolver.res +6 -3
- package/src/adapter/Mcp/MCP_Lambda.res +31 -46
- package/src/adapter/Messaging/Messaging_Ses_Backend.res +11 -7
- package/src/adapter/Messaging/Messaging_Ses_Backend.res.mjs +2 -4
- package/src/adapter/Monitoring/Monitoring_CloudWatch.res +16 -16
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res +5 -10
- package/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res +4 -2
- package/src/adapter/Postgres/PgConnection.res +6 -5
- package/src/adapter/Postgres/PgMigration_Builder.res +4 -8
- package/src/adapter/Postgres/PgRuntime.res +4 -7
- package/src/adapter/QueryDb/PgQueryResolver_Builder.res +9 -11
- package/src/adapter/QueryDb/PgQueryResolver_Lambda.res +22 -21
- package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res +114 -111
- package/src/adapter/QueryDb/QueryDbResolvers_Lambda.res +1 -7
- package/src/adapter/QueryDb/QueryDbStorage.res +4 -2
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res +23 -24
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res +8 -2
- package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res +71 -73
- package/src/adapter/QueryDb/QueryDbStorage_Postgres.res +5 -2
- package/src/adapter/QueryDb/QueryInterceptor_Provisioning.res +1 -4
- package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res +8 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +73 -81
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +72 -78
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +44 -67
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +44 -67
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +53 -82
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +47 -77
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +23 -11
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res.mjs +5 -1
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +80 -97
- package/src/adapter/Runtime/CounterEntryPoint_Ops.res +2 -7
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +16 -10
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +24 -15
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +17 -37
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +31 -57
- package/src/adapter/Runtime/EventMapperEntryPoint_Ops.res +18 -24
- package/src/adapter/Runtime/ExtensionPointEntryPoint_Ops.res +1 -5
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +4 -3
- package/src/adapter/Runtime/HeartbeatEntryPoint.res +0 -1
- package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.res +4 -2
- package/src/adapter/Runtime/PgMigrationEntryPoint.res +0 -1
- package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res +3 -2
- package/src/adapter/Runtime/PluginExtensionPointEntryPoint.res +1 -2
- package/src/adapter/Runtime/ProjectionEntryPoint_Ops.res +4 -5
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +22 -10
- package/src/adapter/Runtime/RuntimeExtensionEntryPoint_Ops.res +8 -2
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +14 -31
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +16 -17
- package/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res +10 -9
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +46 -52
- package/src/adapter/Runtime/StreamRoutedEntryPoint_Ops.res +36 -41
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +31 -37
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +6 -7
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +4 -6
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res +2 -6
- package/src/adapter/StateTopic/StateTopic_AppSync.res +21 -16
- package/src/adapter/StateTopic/StateTopic_AppSync_Ops.res +36 -32
- package/src/adapter/Task/TaskBucket_S3.res +6 -1
- package/src/adapter/Upload/Upload_Claim_S3.res +17 -20
- package/src/adapter/Upload/Upload_Claim_S3_Ops.res +5 -2
- package/src/adapter/Upload/Upload_Presign_S3.res +51 -49
- package/src/capability/Capability_Geocoding_AwsLocation.res +4 -1
- package/src/capability/Capability_Messaging.res +4 -5
- package/src/capability/Capability_Messaging_Ses.res +3 -1
- package/src/capability/Capability_ObjectStore_S3.res +1 -7
- package/src/components/Api/AppSync_Adapter.res +80 -109
- package/src/components/Api/AppSync_Adapter.res.mjs +26 -60
- package/src/components/Api/AppSync_SdlDecorate.res +118 -31
- package/src/components/Api/AppSync_SdlDecorate.res.mjs +45 -0
- package/src/components/AutomationSlice_Builder.res +6 -4
- package/src/components/ExtensionPoint_Builder.res +9 -10
- package/src/components/InboundTranslationSlice_Builder.res +7 -8
- package/src/components/OutboundTranslationSlice_Builder.res +14 -8
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +1 -1
- package/src/components/SideEffectHandler_Single.res +4 -4
- package/src/components/StateViewSlice_Builder.res +6 -4
- package/src/components/StateViewSlice_Builder_Stream.res +6 -4
- package/src/components/Task_Builder_PerBucket.res +10 -11
- package/src/plugin/cloner/ClonerRunner_Fargate.res +3 -10
- package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res +1 -4
- package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res +5 -5
- package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +19 -21
- package/src/plugin/runtime/PluginRuntime_Builder.res +167 -188
- package/src/plugin/runtime/Util_PluginMessage_Runtime.res +6 -5
- package/src/plugin/stack/Plugin_Stack.res +104 -103
- package/src/util/Util_AlarmSpec.res +2 -1
- package/src/util/Util_AppSync.res +8 -2
- package/src/util/Util_AppSync_Caller.res +15 -14
- package/src/util/Util_Bundle.res +46 -42
- package/src/util/Util_CognitoGroupUser_Runtime.res +32 -34
- package/src/util/Util_Cognito_Runtime.res +11 -7
- package/src/util/Util_DeadLetterQueue.res +12 -2
- package/src/util/Util_DynamoDb.res +5 -3
- package/src/util/Util_DynamoDbStream.res +7 -3
- package/src/util/Util_DynamoDbStream_Runtime.res +1 -2
- package/src/util/Util_DynamoDb_Runtime.res +23 -41
- package/src/util/Util_HostUiDomain.res +6 -1
- package/src/util/Util_Kinesis_Runtime.res +10 -11
- package/src/util/Util_Lambda.res +12 -5
- package/src/util/Util_LambdaEnvBudget.res +5 -5
- package/src/util/Util_LambdaLogging.res +1 -2
- package/src/util/Util_LogGroup_Adopting.res +1 -4
- package/src/util/Util_ResourceNaming.res +1 -2
- package/src/util/Util_SNS.res +8 -3
- package/src/util/Util_SNS_FIFO.res +1 -1
- package/src/util/Util_SNS_Runtime.res +11 -10
- package/src/util/Util_SQS.res +4 -2
- package/src/util/Util_SQS_FIFO.res +5 -2
- package/src/util/Util_SQS_Runtime.res +37 -36
- package/src/util/Util_ShellConfig.res +3 -2
- package/src/util/Util_StaticBundle.res +1 -3
- package/src/util/Util_StoreLayout.res +4 -1
- package/tests/AWS_TagsTest.res +16 -5
- package/tests/AppSyncEventsSigner_OpsTest.res +11 -2
- package/tests/AppSync_AdapterTest.res +286 -224
- package/tests/AppSync_AdapterTest.res.mjs +69 -0
- package/tests/AppSync_Resolver_RetryingTest.res +64 -44
- package/tests/AppSync_RetirementNarrowingTest.res +59 -46
- package/tests/AppSync_SdlDecorateTest.res +22 -20
- package/tests/AppSync_SourceApiAssociation_RetryingTest.res +40 -22
- package/tests/Auth_ActiveRolePoolAttachmentTest.res +114 -107
- package/tests/Auth_ActiveRoleStoreTest.res +12 -9
- package/tests/Auth_ActiveRoleStore_SchemaTest.res +2 -1
- package/tests/Auth_ActiveRoleTrigger_OpsTest.res +20 -16
- package/tests/Auth_CognitoTest.res +31 -46
- package/tests/Auth_LoginIdentifierTest.res +51 -0
- package/tests/Auth_LoginIdentifierTest.res.mjs +51 -0
- package/tests/Auth_SignUpModeTest.res +56 -0
- package/tests/Auth_SignUpModeTest.res.mjs +53 -0
- package/tests/AutomationSliceEntryPoint_OpsTest.res +69 -67
- package/tests/BakeConvergenceTest.res +22 -25
- package/tests/Capability_MessagingTest.res +28 -12
- package/tests/CommandTopicQueuePolicyTest.res +1 -2
- package/tests/CounterEntryPoint_OpsTest.res +3 -7
- package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res +306 -210
- package/tests/EventCollectorConnectLambdaPreviewTest.res +14 -7
- package/tests/EventCollectorEntryPoint_OpsTest.res +12 -4
- package/tests/EventCollectorPluginDefinitionAssetTest.res +18 -11
- package/tests/EventCollectorReadyGateTest.res +5 -4
- package/tests/EventLogStorage_DynamoDb_RuntimeTest.res +1 -2
- package/tests/EventMapperEntryPoint_OpsTest.res +1 -3
- package/tests/ExtensionPointEntryPoint_OpsTest.res +1 -4
- package/tests/HandlerFactoryDispatchTest.res +97 -70
- package/tests/MCP_LambdaTest.res +16 -27
- package/tests/PgChangeFeedRelay_IntegrationTest.res +123 -93
- package/tests/PgChangeFeedRelay_RuntimeTest.res +13 -10
- package/tests/PgMigrationEntryPoint_IntegrationTest.res +0 -1
- package/tests/PgPipeline_IntegrationTest.res +80 -66
- package/tests/PgQueryDbUnion_IntegrationTest.res +1 -2
- package/tests/PgQueryResolverEntryPoint_OpsTest.res +2 -6
- package/tests/PgQueryResolver_LambdaTest.res +41 -24
- package/tests/Platform_AdminScan_OpsTest.res +4 -1
- package/tests/Platform_ComponentDefinitions_Lambda_OpsTest.res +137 -129
- package/tests/ProjectionEntryPoint_DisplayNameTest.res +7 -3
- package/tests/ProjectionEntryPoint_UnionStampTest.res +3 -2
- package/tests/ProvisionAccountsTest.res +142 -0
- package/tests/ProvisionAccountsTest.res.mjs +153 -0
- package/tests/ProvisionAdminTest.res +55 -0
- package/tests/ProvisionAdminTest.res.mjs +66 -0
- package/tests/ProvisionIdentityTest.res +91 -9
- package/tests/ProvisionIdentityTest.res.mjs +66 -1
- package/tests/QueryDbOwnerIndexTableTest.res +6 -4
- package/tests/QueryDbResolvers_AppSyncTest.res +23 -16
- package/tests/QueryInterceptor_LambdaTest.res +11 -13
- package/tests/ReadModelEntryPoint_OpsTest.res +43 -41
- package/tests/RuntimeExtensionEntryPoint_OpsTest.res +4 -3
- package/tests/SideEffectEntryPoint_OpsTest.res +23 -18
- package/tests/StateChangeDescriptorParityTest.res +28 -26
- package/tests/StateTopicKeySchemaTest.res +18 -15
- package/tests/StateViewSliceEntryPoint_OpsTest.res +55 -44
- package/tests/TaskBucketEntryPoint_OpsTest.res +13 -13
- package/tests/Upload_ClaimTest.res +3 -3
- package/tests/Util_AwsErrorTest.res +4 -7
- package/tests/Util_BundleDependencyClosureTest.res +15 -3
- package/tests/Util_BundleEsmLoaderTest.res +3 -3
- package/tests/Util_BundleResolveTest.res +4 -6
- package/tests/Util_BundleRuntimeExtensionTest.res +17 -18
- package/tests/Util_DcbMetricsTest.res +6 -6
- package/tests/Util_DynamoDbStreamTest.res +4 -5
- package/tests/Util_DynamoDbTest.res +3 -2
- package/tests/Util_LambdaEnvBudgetTest.res +22 -18
- package/tests/Util_LambdaLoggingTest.res +9 -8
- package/tests/Util_LogGroup_AdoptingTest.res +10 -5
- package/tests/Util_LogRetentionTest.res +6 -2
- package/tests/Util_OwnerScopeEnvTest.res +35 -8
- package/tests/Util_OwnerScopeEnvTest.res.mjs +13 -0
- package/tests/Util_SQS_RuntimeTest.res +5 -7
- package/tests/Util_ShellConfigTest.res +7 -17
- package/tests/Util_StaticBundleTest.res +3 -8
- package/tests/Util_StoreLayoutTest.res +17 -12
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res +1 -4
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +15 -15
- package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +296 -232
- package/tests/integration/DcbIntegrationHarness.res +8 -8
- package/tests/integration/EpCompositeSlice.res +16 -8
- package/tests/integration/QueryDbUnion_DynamoDb_IntegrationTest.res +8 -10
- package/tests/integration/StateViewSliceEntryPoint_IntegrationTest.res +10 -10
- package/tests/integration/SvsTestSlice_Projection.res +1 -3
- package/tests/util/Util_AlarmSpecTest.res +62 -49
|
@@ -44,9 +44,10 @@ let injectAwsSubscribe = (
|
|
|
44
44
|
// leaves a trailing colon on the token — drop it (same rule as
|
|
45
45
|
// GraphQL_Stitcher.rootTypeFieldNames).
|
|
46
46
|
let name = ReventlessCore.GraphQL_Stitcher.extractLeadingName(line)
|
|
47
|
-
let name =
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
let name =
|
|
48
|
+
name->String.endsWith(":")
|
|
49
|
+
? name->String.slice(~start=0, ~end=name->String.length - 1)
|
|
50
|
+
: name
|
|
50
51
|
switch sourceByField->Dict.get(name) {
|
|
51
52
|
| Some(mutations) =>
|
|
52
53
|
let list = mutations->Array.map(m => `"${m}"`)->Array.join(", ")
|
|
@@ -89,7 +90,11 @@ let formatCognitoGroupsDirective = (groups: array<string>): string => {
|
|
|
89
90
|
|
|
90
91
|
// The group-less Cognito directive: reachable by any authenticated Cognito
|
|
91
92
|
// caller. Emitted where a field or type is deliberately open — `AllowAuthenticated`,
|
|
92
|
-
//
|
|
93
|
+
// a field carrying no permission at all, and every object type.
|
|
94
|
+
//
|
|
95
|
+
// NOT for `AllowAnonymous`: "any authenticated caller" is the inverse of what
|
|
96
|
+
// that declares, and emitting this for it is the defect `permissionToGate` and
|
|
97
|
+
// `refuseAnonymousFields` above exist to prevent.
|
|
93
98
|
//
|
|
94
99
|
// Under `userPoolConfig.defaultAction: ALLOW` this is a no-op: an undirectived
|
|
95
100
|
// field is already reachable by any authenticated caller, so stamping it changes
|
|
@@ -111,6 +116,56 @@ let formatDualAuthDirective = (groups: option<array<string>>): string => {
|
|
|
111
116
|
`${cognito} @aws_iam`
|
|
112
117
|
}
|
|
113
118
|
|
|
119
|
+
// ── What a declared permission asks this API to enforce ─────────────────────
|
|
120
|
+
//
|
|
121
|
+
// Lives here rather than beside the Pulumi resources because it is the same
|
|
122
|
+
// concern as the directive vocabulary above: reading a spec-level rule and
|
|
123
|
+
// deciding what the schema says. Keeping the mapping next to the strings it
|
|
124
|
+
// maps onto is what stops a fourth spelling of a directive appearing.
|
|
125
|
+
|
|
126
|
+
/** Three arms rather than an `option<array<string>>`, which is the shape this
|
|
127
|
+
had while it was wrong: the option form could not hold `AllowAuthenticated`
|
|
128
|
+
and `AllowAnonymous` apart, so both became `None` and emitted one directive.
|
|
129
|
+
AppSync can enforce the first and cannot express the second at all. */
|
|
130
|
+
type fieldGate =
|
|
131
|
+
| Groups(array<string>)
|
|
132
|
+
| AnyAuthenticated
|
|
133
|
+
/** No directive can express this; the deploy is refused rather than gated
|
|
134
|
+
into its opposite. See `refuseAnonymousFields`. */
|
|
135
|
+
| Anonymous
|
|
136
|
+
|
|
137
|
+
let permissionToGate = (permission: Reventless.Authorization.permission): fieldGate =>
|
|
138
|
+
switch permission {
|
|
139
|
+
| AllowGroups([]) => Groups(["__deny_all__"])
|
|
140
|
+
| AllowGroups(groups) => Groups(groups)
|
|
141
|
+
| DenyAll => Groups(["__deny_all__"])
|
|
142
|
+
| AllowAuthenticated => AnyAuthenticated
|
|
143
|
+
| AllowAnonymous => Anonymous
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** The deploy-time refusal for fields declared `AllowAnonymous`, and the
|
|
147
|
+
sibling of `assertGateable` below: both refuse a schema that would claim a
|
|
148
|
+
gate it does not have. This one fires earlier, while the permission is still
|
|
149
|
+
a value — by SDL time the two permissions are indistinguishable. */
|
|
150
|
+
let refuseAnonymousFields = (fieldNames: array<string>): 'a =>
|
|
151
|
+
JsError.throwWithMessage(
|
|
152
|
+
`Refusing to push an AppSync schema that cannot honour AllowAnonymous.\n\n` ++
|
|
153
|
+
` ${fieldNames->Array.length->Int.toString} field(s) declare AllowAnonymous:\n` ++
|
|
154
|
+
` ${fieldNames->Array.join(", ")}\n\n` ++
|
|
155
|
+
`AppSync has no anonymous authorization mode. This API is provisioned with\n` ++
|
|
156
|
+
`AMAZON_COGNITO_USER_POOLS primary and AWS_IAM additional, so the only\n` ++
|
|
157
|
+
`directive available is @aws_cognito_user_pools — which means ANY\n` ++
|
|
158
|
+
`AUTHENTICATED caller, the opposite of what the spec declares. Mutations have\n` ++
|
|
159
|
+
`no runtime authorization check to correct it: on this platform the directive\n` ++
|
|
160
|
+
`is the whole enforcement.\n\n` ++
|
|
161
|
+
`The local platform DOES honour AllowAnonymous (its resolvers call\n` ++
|
|
162
|
+
`Authorization.isAllowed), so a spec that passes locally can still not be\n` ++
|
|
163
|
+
`deployable here. That divergence is the reason this refuses instead of\n` ++
|
|
164
|
+
`emitting a directive that reads as gated and is not.\n\n` ++
|
|
165
|
+
`To serve anonymous callers on AWS the API needs API_KEY added as a third\n` ++
|
|
166
|
+
`auth provider, plus something to rotate the key. Until then, declare the\n` ++ `field AllowAuthenticated (or AllowGroups) and mean it.`,
|
|
167
|
+
)
|
|
168
|
+
|
|
114
169
|
// Injects the Cognito group gate on ALL mutation, query, and subscription fields
|
|
115
170
|
// in a fragment. `~iamFieldNames` opts the named mutation/query fields into
|
|
116
171
|
// deploy-time IAM as well, appending the `@aws_iam` arm. Subscriptions are never
|
|
@@ -126,17 +181,20 @@ let injectAwsAuthAll = (
|
|
|
126
181
|
iamFieldNames->Array.includes(ReventlessCore.GraphQL_Stitcher.extractLeadingName(field))
|
|
127
182
|
let cognitoOnly = formatCognitoGroupsDirective([group])
|
|
128
183
|
|
|
129
|
-
let augmentedMutations =
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
184
|
+
let augmentedMutations =
|
|
185
|
+
parts.mutations->Array.map(field =>
|
|
186
|
+
isIam(field)
|
|
187
|
+
? `${field}\n ${formatDualAuthDirective(Some([group]))}`
|
|
188
|
+
: `${field}\n ${cognitoOnly}`
|
|
189
|
+
)
|
|
190
|
+
let augmentedQueries =
|
|
191
|
+
parts.queries->Array.map(field =>
|
|
192
|
+
isIam(field)
|
|
193
|
+
? `${field} ${formatDualAuthDirective(Some([group]))}`
|
|
194
|
+
: `${field} ${cognitoOnly}`
|
|
195
|
+
)
|
|
196
|
+
let augmentedSubscriptions =
|
|
197
|
+
parts.subscriptions->Array.map(field => `${field}\n ${cognitoOnly}`)
|
|
140
198
|
|
|
141
199
|
ReventlessCore.GraphQL_Stitcher.encode({
|
|
142
200
|
...parts,
|
|
@@ -150,12 +208,7 @@ let injectAwsAuthAll = (
|
|
|
150
208
|
// connections, injected by the stitcher) and the `CommandResult` members
|
|
151
209
|
// (mutation returns). Stamped once on the ASSEMBLED SDL so an IAM system
|
|
152
210
|
// caller (`@@reventless.systemCallable` fields) can traverse them.
|
|
153
|
-
let sharedIamTypeNames = [
|
|
154
|
-
"PageInfo",
|
|
155
|
-
"CommandAccepted",
|
|
156
|
-
"CommandRejected",
|
|
157
|
-
"CommandPending",
|
|
158
|
-
]
|
|
211
|
+
let sharedIamTypeNames = ["PageInfo", "CommandAccepted", "CommandRejected", "CommandPending"]
|
|
159
212
|
|
|
160
213
|
let stampSharedIamTypes = (sdl: string): string =>
|
|
161
214
|
sharedIamTypeNames->Array.reduce(sdl, (acc, name) =>
|
|
@@ -227,6 +280,31 @@ let stampAllTypesCognito = (sdl: string): string =>
|
|
|
227
280
|
)
|
|
228
281
|
->Array.join("\n")
|
|
229
282
|
|
|
283
|
+
// Insert the multi-auth pair into ONE type declaration's header, before its `{`.
|
|
284
|
+
//
|
|
285
|
+
// The sibling of `stampAllTypesCognito` and deliberately not folded into it:
|
|
286
|
+
// that one sweeps a whole assembled SDL and fills in the Cognito-only arm for
|
|
287
|
+
// anything undirectived, this one is applied to a declaration already chosen by
|
|
288
|
+
// its caller and adds the IAM arm the traversal needs. Different input, different
|
|
289
|
+
// directive, same header surgery.
|
|
290
|
+
//
|
|
291
|
+
// On a multi-auth API, object TYPES without auth directives are reachable only
|
|
292
|
+
// via the default auth mode: a field-level `@aws_iam` admits the system caller to
|
|
293
|
+
// the top-level field, but response shaping then walks the return types
|
|
294
|
+
// (`…Connection` → `…Edge` → node → nested state types) and dies with "Not
|
|
295
|
+
// Authorized to access <field> on type <T>" one level in. The group-less Cognito
|
|
296
|
+
// arm matches the accessibility an undirectived type already has (entry gating
|
|
297
|
+
// stays on the fields); the IAM arm admits the traversal.
|
|
298
|
+
let stampTypeDualAuth = (decl: string): string =>
|
|
299
|
+
switch decl->String.indexOfOpt("{") {
|
|
300
|
+
| Some(i) =>
|
|
301
|
+
decl->String.slice(~start=0, ~end=i) ++
|
|
302
|
+
formatDualAuthDirective(None) ++
|
|
303
|
+
" " ++
|
|
304
|
+
decl->String.slice(~start=i, ~end=decl->String.length)
|
|
305
|
+
| None => decl
|
|
306
|
+
}
|
|
307
|
+
|
|
230
308
|
// ── Deploy-time gate invariant ──────────────────────────────────────────────
|
|
231
309
|
//
|
|
232
310
|
// Refuse to push a schema that cannot be gated. This is the fail-closed
|
|
@@ -260,7 +338,7 @@ let rootOperationTypes = ["Query", "Mutation", "Subscription"]
|
|
|
260
338
|
let typeDeclNameOf = (line: string): option<string> =>
|
|
261
339
|
if line->String.startsWith("type ") {
|
|
262
340
|
let rest = line->String.slice(~start=5, ~end=line->String.length)
|
|
263
|
-
switch rest->String.search(
|
|
341
|
+
switch rest->String.search(/[\s{]/) {
|
|
264
342
|
| -1 => Some(rest)
|
|
265
343
|
| i => Some(rest->String.slice(~start=0, ~end=i))
|
|
266
344
|
}
|
|
@@ -271,7 +349,7 @@ let typeDeclNameOf = (line: string): option<string> =>
|
|
|
271
349
|
// A root-operation field line: exactly two spaces of indent then a name. Deeper
|
|
272
350
|
// indents are directive continuations of the field above.
|
|
273
351
|
let fieldNameOf = (line: string): option<string> =>
|
|
274
|
-
switch line->String.match(
|
|
352
|
+
switch line->String.match(/^ {2}(\w+)/) {
|
|
275
353
|
| Some(groups) => groups->Array.get(1)->Option.flatMap(x => x)
|
|
276
354
|
| None => None
|
|
277
355
|
}
|
|
@@ -388,7 +466,9 @@ let assertGateable = (sdl: string): string => {
|
|
|
388
466
|
let problems = []
|
|
389
467
|
if inertDirectives->Array.length > 0 {
|
|
390
468
|
problems->Array.push(
|
|
391
|
-
` ${inertDirectives
|
|
469
|
+
` ${inertDirectives
|
|
470
|
+
->Array.length
|
|
471
|
+
->Int.toString} field(s) carry @aws_auth, which AppSync IGNORES on a\n` ++
|
|
392
472
|
` multi-auth API (this adapter always adds AWS_IAM as an additional provider).\n` ++
|
|
393
473
|
` They are gated by nothing. Emit @aws_cognito_user_pools(cognito_groups: [...])\n` ++
|
|
394
474
|
` instead — see AppSync_SdlDecorate.formatCognitoGroupsDirective.\n` ++
|
|
@@ -397,14 +477,18 @@ let assertGateable = (sdl: string): string => {
|
|
|
397
477
|
}
|
|
398
478
|
if bareFields->Array.length > 0 {
|
|
399
479
|
problems->Array.push(
|
|
400
|
-
` ${bareFields
|
|
480
|
+
` ${bareFields
|
|
481
|
+
->Array.length
|
|
482
|
+
->Int.toString} root field(s) carry no enforced auth directive, so they are\n` ++
|
|
401
483
|
` reachable by ANY authenticated Cognito caller:\n` ++
|
|
402
484
|
` ${bareFields->Array.join(", ")}`,
|
|
403
485
|
)
|
|
404
486
|
}
|
|
405
487
|
if bareTypes->Array.length > 0 {
|
|
406
488
|
problems->Array.push(
|
|
407
|
-
` ${bareTypes
|
|
489
|
+
` ${bareTypes
|
|
490
|
+
->Array.length
|
|
491
|
+
->Int.toString} object type(s) carry no enforced auth directive:\n` ++
|
|
408
492
|
` ${bareTypes->Array.join(", ")}`,
|
|
409
493
|
)
|
|
410
494
|
}
|
|
@@ -416,8 +500,7 @@ let assertGateable = (sdl: string): string => {
|
|
|
416
500
|
`\n\nEvery field and type must carry @aws_cognito_user_pools (optionally with\n` ++
|
|
417
501
|
`cognito_groups) and/or @aws_iam. The sweep in stampUndirectivedFields /\n` ++
|
|
418
502
|
`stampAllTypesCognito should have covered this — a failure here means a schema\n` ++
|
|
419
|
-
`reached assembly by a path that bypasses them.\n` ++
|
|
420
|
-
`See docs/plans/appsync-group-authorization-unenforced.md.`,
|
|
503
|
+
`reached assembly by a path that bypasses them.\n` ++ `See docs/plans/appsync-group-authorization-unenforced.md.`,
|
|
421
504
|
)
|
|
422
505
|
}
|
|
423
506
|
sdl
|
|
@@ -441,9 +524,13 @@ let stampCanonicalTypes = (sdl: string): string =>
|
|
|
441
524
|
sdl
|
|
442
525
|
->String.split("\n")
|
|
443
526
|
->Array.map(line => {
|
|
444
|
-
let isObjectDef =
|
|
445
|
-
|
|
446
|
-
let
|
|
527
|
+
let isObjectDef =
|
|
528
|
+
canonicalTypeNames->Array.some(name => line->String.startsWith(`type ${name} `))
|
|
529
|
+
let isNodeDef =
|
|
530
|
+
line->String.startsWith("interface Node ") || line->String.startsWith("interface Node{")
|
|
531
|
+
let isUnionDef =
|
|
532
|
+
line->String.startsWith("union CommandResult ") ||
|
|
533
|
+
line->String.startsWith("union CommandResult=")
|
|
447
534
|
if line->String.includes("@canonical") {
|
|
448
535
|
line
|
|
449
536
|
} else if isObjectDef || isNodeDef {
|
|
@@ -51,6 +51,39 @@ function formatDualAuthDirective(groups) {
|
|
|
51
51
|
return cognito + ` @aws_iam`;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
function permissionToGate(permission) {
|
|
55
|
+
if (typeof permission !== "object") {
|
|
56
|
+
switch (permission) {
|
|
57
|
+
case "AllowAuthenticated" :
|
|
58
|
+
return "AnyAuthenticated";
|
|
59
|
+
case "AllowAnonymous" :
|
|
60
|
+
return "Anonymous";
|
|
61
|
+
case "DenyAll" :
|
|
62
|
+
return {
|
|
63
|
+
TAG: "Groups",
|
|
64
|
+
_0: ["__deny_all__"]
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
let groups = permission._0;
|
|
69
|
+
if (groups.length !== 0) {
|
|
70
|
+
return {
|
|
71
|
+
TAG: "Groups",
|
|
72
|
+
_0: groups
|
|
73
|
+
};
|
|
74
|
+
} else {
|
|
75
|
+
return {
|
|
76
|
+
TAG: "Groups",
|
|
77
|
+
_0: ["__deny_all__"]
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function refuseAnonymousFields(fieldNames) {
|
|
84
|
+
return Stdlib_JsError.throwWithMessage(`Refusing to push an AppSync schema that cannot honour AllowAnonymous.\n\n` + (` ` + fieldNames.length.toString() + ` field(s) declare AllowAnonymous:\n`) + (` ` + fieldNames.join(", ") + `\n\n`) + `AppSync has no anonymous authorization mode. This API is provisioned with\nAMAZON_COGNITO_USER_POOLS primary and AWS_IAM additional, so the only\ndirective available is @aws_cognito_user_pools — which means ANY\nAUTHENTICATED caller, the opposite of what the spec declares. Mutations have\nno runtime authorization check to correct it: on this platform the directive\nis the whole enforcement.\n\nThe local platform DOES honour AllowAnonymous (its resolvers call\nAuthorization.isAllowed), so a spec that passes locally can still not be\ndeployable here. That divergence is the reason this refuses instead of\nemitting a directive that reads as gated and is not.\n\nTo serve anonymous callers on AWS the API needs API_KEY added as a third\nauth provider, plus something to rotate the key. Until then, declare the\nfield AllowAuthenticated (or AllowGroups) and mean it.`);
|
|
85
|
+
}
|
|
86
|
+
|
|
54
87
|
function injectAwsAuthAll(fragment, group, iamFieldNamesOpt) {
|
|
55
88
|
let iamFieldNames = iamFieldNamesOpt !== undefined ? iamFieldNamesOpt : [];
|
|
56
89
|
let parts = GraphQL_Stitcher$ReventlessCore.decode(fragment);
|
|
@@ -122,6 +155,15 @@ function stampAllTypesCognito(sdl) {
|
|
|
122
155
|
}).join("\n");
|
|
123
156
|
}
|
|
124
157
|
|
|
158
|
+
function stampTypeDualAuth(decl) {
|
|
159
|
+
let i = Stdlib_String.indexOfOpt(decl, "{");
|
|
160
|
+
if (i !== undefined) {
|
|
161
|
+
return decl.slice(0, i) + formatDualAuthDirective(undefined) + " " + decl.slice(i, decl.length);
|
|
162
|
+
} else {
|
|
163
|
+
return decl;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
125
167
|
let enforcedDirectives = [
|
|
126
168
|
"@aws_cognito_user_pools",
|
|
127
169
|
"@aws_iam"
|
|
@@ -328,11 +370,14 @@ export {
|
|
|
328
370
|
formatCognitoGroupsDirective,
|
|
329
371
|
cognitoOpenDirective,
|
|
330
372
|
formatDualAuthDirective,
|
|
373
|
+
permissionToGate,
|
|
374
|
+
refuseAnonymousFields,
|
|
331
375
|
injectAwsAuthAll,
|
|
332
376
|
sharedIamTypeNames,
|
|
333
377
|
stampSharedIamTypes,
|
|
334
378
|
stampUndirectivedFields,
|
|
335
379
|
stampAllTypesCognito,
|
|
380
|
+
stampTypeDualAuth,
|
|
336
381
|
enforcedDirectives,
|
|
337
382
|
hasEnforcedDirective,
|
|
338
383
|
rootOperationTypes,
|
|
@@ -5,10 +5,12 @@ module EventCollectorChannel = EventCollectorChannel.DynamoDbStream
|
|
|
5
5
|
module RuntimeEnvironment = RuntimeEnvironment.Lambda
|
|
6
6
|
module EventCollectorRuntimeBuilder = AutomationSliceRuntime_Builder_Single
|
|
7
7
|
|
|
8
|
-
module Make = (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
module Make = (
|
|
9
|
+
Api: {
|
|
10
|
+
let api: unit => Types.AppSync.api
|
|
11
|
+
let apiRole: unit => Types.AppSync.role
|
|
12
|
+
},
|
|
13
|
+
) => {
|
|
12
14
|
module Inner = ReventlessCore.AutomationSlice_Builder.Make(
|
|
13
15
|
RuntimeEnvironment,
|
|
14
16
|
QueryDbStorage.DynamoDb,
|
|
@@ -12,13 +12,12 @@ module Defaults: ReventlessInfra.RuntimeDefaults.T = {
|
|
|
12
12
|
module Make = (
|
|
13
13
|
Spec: ReventlessInfra.ExtensionPointMapping.Spec,
|
|
14
14
|
Mappings: ReventlessInfra.ExtensionPoint.Mappings with module Spec := Spec,
|
|
15
|
-
): ReventlessInfra.ExtensionPoint.T =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
15
|
+
): ReventlessInfra.ExtensionPoint.T => ReventlessCore.ExtensionPoint_Builder.Make(
|
|
16
|
+
Spec,
|
|
17
|
+
Mappings,
|
|
18
|
+
RuntimeEnvironment,
|
|
19
|
+
CommandTopicChannel,
|
|
20
|
+
EventTopicPublisher.SNS,
|
|
21
|
+
ExtensionPointRuntimeBuilder,
|
|
22
|
+
Defaults,
|
|
23
|
+
)
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// InboundTranslationSlice_Builder (AWS)
|
|
2
2
|
// Wires AWS adapters and delegates to the core ReventlessCore.InboundTranslationSlice_Builder.
|
|
3
3
|
|
|
4
|
-
module Make = (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
module Make = (
|
|
5
|
+
Api: {
|
|
6
|
+
let api: unit => Types.AppSync.api
|
|
7
|
+
let apiRole: unit => Types.AppSync.role
|
|
8
|
+
},
|
|
9
|
+
) => {
|
|
8
10
|
module Inner = ReventlessCore.InboundTranslationSlice_Builder.Make(
|
|
9
11
|
QueryDbStorage.DynamoDb,
|
|
10
12
|
QueryDbResolvers.AppSync,
|
|
@@ -39,10 +41,7 @@ module Make = (Api: {
|
|
|
39
41
|
component->ReventlessCore.Component.outputs
|
|
40
42
|
switch outputs.queryDb.resources->Array.get(0) {
|
|
41
43
|
| Some(tableResource) =>
|
|
42
|
-
PluginRuntime_Builder.registerInboundAuditTableName(
|
|
43
|
-
~specName=Spec.name,
|
|
44
|
-
tableResource.name,
|
|
45
|
-
)
|
|
44
|
+
PluginRuntime_Builder.registerInboundAuditTableName(~specName=Spec.name, tableResource.name)
|
|
46
45
|
| None => ()
|
|
47
46
|
}
|
|
48
47
|
component
|
|
@@ -28,10 +28,12 @@ module DeployTimeCapabilities = {
|
|
|
28
28
|
let capabilities = () => Reventless.Capabilities.none
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
module Make = (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
module Make = (
|
|
32
|
+
Api: {
|
|
33
|
+
let api: unit => Types.AppSync.api
|
|
34
|
+
let apiRole: unit => Types.AppSync.role
|
|
35
|
+
},
|
|
36
|
+
) => {
|
|
35
37
|
module Inner = ReventlessCore.OutboundTranslationSlice_Builder.Make(
|
|
36
38
|
RuntimeEnvironment,
|
|
37
39
|
QueryDbStorage.DynamoDb,
|
|
@@ -53,7 +55,13 @@ module Make = (Api: {
|
|
|
53
55
|
type component = InnerMake.component
|
|
54
56
|
let queryDbName = InnerMake.queryDbName
|
|
55
57
|
|
|
56
|
-
let make = (
|
|
58
|
+
let make = (
|
|
59
|
+
~dcbEventLog,
|
|
60
|
+
~allEventTopics=Dict.make(),
|
|
61
|
+
~publishJsons,
|
|
62
|
+
~runtime=?,
|
|
63
|
+
~opts=?,
|
|
64
|
+
): component => {
|
|
57
65
|
let ots = InnerMake.make(~dcbEventLog, ~allEventTopics, ~publishJsons, ~runtime?, ~opts?)
|
|
58
66
|
|
|
59
67
|
let queryDbOutputs = (ots->ReventlessCore.Component.outputs).queryDb
|
|
@@ -67,9 +75,7 @@ module Make = (Api: {
|
|
|
67
75
|
// not carry.
|
|
68
76
|
let declaredSources = Spec.sourceNames
|
|
69
77
|
let sourceTopics =
|
|
70
|
-
allEventTopics->ReventlessCore.EventTopic.filter(
|
|
71
|
-
declaredSources->Belt.Set.String.fromArray,
|
|
72
|
-
)
|
|
78
|
+
allEventTopics->ReventlessCore.EventTopic.filter(declaredSources->Belt.Set.String.fromArray)
|
|
73
79
|
let consumesDcbLog =
|
|
74
80
|
declaredSources->Array.length == 0 ||
|
|
75
81
|
declaredSources->Array.some(name => !(allEventTopics->Dict.has(name)))
|
|
@@ -40,10 +40,10 @@ module Make = (): ReventlessCore.SideEffectHandler.T => {
|
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
// Derive npm specifiers from moduleUrl on each SideEffect module
|
|
43
|
-
let sideEffectModulePaths =
|
|
44
|
-
(module(SE: Reventless.SideEffect.T)) =>
|
|
45
|
-
Util_Bundle.getModuleSpecifier(SE.moduleUrl)
|
|
46
|
-
|
|
43
|
+
let sideEffectModulePaths =
|
|
44
|
+
sideEffects->Array.map((module(SE: Reventless.SideEffect.T)) =>
|
|
45
|
+
Util_Bundle.getModuleSpecifier(SE.moduleUrl)
|
|
46
|
+
)
|
|
47
47
|
|
|
48
48
|
EventCollectorRuntimeBuilder.registerSideEffectHandler(
|
|
49
49
|
~sideEffectHandlerName=name,
|
|
@@ -5,10 +5,12 @@ module EventCollectorChannel = EventCollectorChannel.DynamoDbStream
|
|
|
5
5
|
module RuntimeEnvironment = RuntimeEnvironment.Lambda
|
|
6
6
|
module EventCollectorRuntimeBuilder = StateViewSliceRuntime_Builder_Single
|
|
7
7
|
|
|
8
|
-
module Make = (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
module Make = (
|
|
9
|
+
Api: {
|
|
10
|
+
let api: unit => Types.AppSync.api
|
|
11
|
+
let apiRole: unit => Types.AppSync.role
|
|
12
|
+
},
|
|
13
|
+
) => {
|
|
12
14
|
module Inner = ReventlessCore.StateViewSlice_Builder.Make(
|
|
13
15
|
RuntimeEnvironment,
|
|
14
16
|
QueryDbStorage.Selectable,
|
|
@@ -9,10 +9,12 @@ module EventCollectorChannel = EventCollectorChannel.DynamoDbStream
|
|
|
9
9
|
module RuntimeEnvironment = RuntimeEnvironment.Lambda
|
|
10
10
|
module EventCollectorRuntimeBuilder = StateViewSliceRuntime_Builder_Single
|
|
11
11
|
|
|
12
|
-
module Make = (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
module Make = (
|
|
13
|
+
Api: {
|
|
14
|
+
let api: unit => Types.AppSync.api
|
|
15
|
+
let apiRole: unit => Types.AppSync.role
|
|
16
|
+
},
|
|
17
|
+
) => {
|
|
16
18
|
module Inner = ReventlessCore.StateViewSlice_Builder.Make(
|
|
17
19
|
RuntimeEnvironment,
|
|
18
20
|
QueryDbStorage.SelectableStream,
|
|
@@ -17,14 +17,13 @@ module Defaults: ReventlessInfra.RuntimeDefaults.T = {
|
|
|
17
17
|
|
|
18
18
|
module Make = (Spec: ReventlessCore.Task.Spec): (
|
|
19
19
|
ReventlessCore.Task.T with module Spec = Spec
|
|
20
|
-
) =>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
)
|
|
20
|
+
) => ReventlessCore.Task_Builder.Make(
|
|
21
|
+
Spec,
|
|
22
|
+
RuntimeEnvironment,
|
|
23
|
+
EventCollectorChannel,
|
|
24
|
+
EventCollectorRuntimeBuilder,
|
|
25
|
+
TaskRuntimeBuilder,
|
|
26
|
+
TaskBucket,
|
|
27
|
+
SideEffectHandler,
|
|
28
|
+
Defaults,
|
|
29
|
+
)
|
|
@@ -243,14 +243,8 @@ export const handler = async (event) => {
|
|
|
243
243
|
Lambda.Function.variables: Dict.fromArray([
|
|
244
244
|
("TASK_DEFINITION_ARN", taskDefinition.arn->Pulumi.Output.asInput),
|
|
245
245
|
("CLUSTER_ARN", cluster.arn->Pulumi.Output.asInput),
|
|
246
|
-
(
|
|
247
|
-
|
|
248
|
-
fullQualifiedStackName.organization->Pulumi.Input.make,
|
|
249
|
-
),
|
|
250
|
-
(
|
|
251
|
-
"STACK_PROJECT",
|
|
252
|
-
fullQualifiedStackName.project->Pulumi.Input.make,
|
|
253
|
-
),
|
|
246
|
+
("STACK_ORG", fullQualifiedStackName.organization->Pulumi.Input.make),
|
|
247
|
+
("STACK_PROJECT", fullQualifiedStackName.project->Pulumi.Input.make),
|
|
254
248
|
("STACK_STACK", fullQualifiedStackName.stack->Pulumi.Input.make),
|
|
255
249
|
(
|
|
256
250
|
"SUBNETS",
|
|
@@ -361,8 +355,7 @@ export const handler = async (event) => {
|
|
|
361
355
|
~opts,
|
|
362
356
|
)
|
|
363
357
|
|
|
364
|
-
let invokeCloneCode =
|
|
365
|
-
`import { util } from '@aws-appsync/utils';
|
|
358
|
+
let invokeCloneCode = `import { util } from '@aws-appsync/utils';
|
|
366
359
|
export function request(ctx) {
|
|
367
360
|
return {
|
|
368
361
|
operation: 'Invoke',
|
|
@@ -14,10 +14,7 @@ let clone = async (~taskDefinition, ~cluster, ~fullQualifiedStackName, ~subnets,
|
|
|
14
14
|
|
|
15
15
|
log.info(
|
|
16
16
|
~comp="ClonerRunner",
|
|
17
|
-
"clone: requested by user " ++
|
|
18
|
-
payload["meta"]["user"] ++
|
|
19
|
-
" from ip " ++
|
|
20
|
-
payload["meta"]["ip"],
|
|
17
|
+
"clone: requested by user " ++ payload["meta"]["user"] ++ " from ip " ++ payload["meta"]["ip"],
|
|
21
18
|
)
|
|
22
19
|
|
|
23
20
|
let _ = await {
|
|
@@ -57,10 +57,7 @@ let make: ReventlessCore.Heartbeat_Adapter.runnerMaker<runtimeParts> = (
|
|
|
57
57
|
~args={
|
|
58
58
|
policy: PulumiAws.PolicyDocument.mergePolicyDocuments(
|
|
59
59
|
name ++ "Policy",
|
|
60
|
-
[
|
|
61
|
-
PulumiAws.Lambda.defaultLoggingPolicyDocument,
|
|
62
|
-
heartbeatLambdaSendMessagePolicyDocument,
|
|
63
|
-
],
|
|
60
|
+
[PulumiAws.Lambda.defaultLoggingPolicyDocument, heartbeatLambdaSendMessagePolicyDocument],
|
|
64
61
|
)->Pulumi.Output.asInput,
|
|
65
62
|
role: lambdaRole.id->Pulumi.Output.asInput,
|
|
66
63
|
},
|
|
@@ -70,7 +67,10 @@ let make: ReventlessCore.Heartbeat_Adapter.runnerMaker<runtimeParts> = (
|
|
|
70
67
|
// The Lambda permission and CloudWatch event target genuinely need the
|
|
71
68
|
// Lambda's resolved arn/name, so they stay inside an apply.
|
|
72
69
|
let _permissionAndEventTarget =
|
|
73
|
-
(
|
|
70
|
+
(
|
|
71
|
+
lambda->Pulumi.Output.flatMap(lambda => lambda.arn),
|
|
72
|
+
lambda->Pulumi.Output.flatMap(lambda => lambda.name),
|
|
73
|
+
)
|
|
74
74
|
->Pulumi.Output.all2
|
|
75
75
|
->Pulumi.Output.apply(((lambdaArn, lambdaName)) => {
|
|
76
76
|
let _addHeartbeatLambdaPermission = PulumiAws.Lambda.Permission.make(
|
|
@@ -66,32 +66,30 @@ let forCommandTopic = (
|
|
|
66
66
|
publishToAggregatesEnvVars
|
|
67
67
|
->Dict.toArray
|
|
68
68
|
->Array.map(((aggName, envVar)) =>
|
|
69
|
-
`${aggName->JSON.stringifyAny->Option.getOr(`""`)}: ${envVar
|
|
69
|
+
`${aggName->JSON.stringifyAny->Option.getOr(`""`)}: ${envVar
|
|
70
|
+
->JSON.stringifyAny
|
|
71
|
+
->Option.getOr(`""`)}`
|
|
70
72
|
)
|
|
71
73
|
->Array.join(",")
|
|
72
74
|
|
|
73
75
|
// Build HANDLER_CONFIG JSON
|
|
74
76
|
let queueName =
|
|
75
|
-
queue.id->Pulumi.Output.apply(id =>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
->
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
let schedQueueArn = values->Array.getUnsafe(3)
|
|
92
|
-
let schedQueueName = values->Array.getUnsafe(4)
|
|
93
|
-
`{"queueUrl":"${queueUrl}","pluginReadModelTableName":"${rmTable}","schedulerRoleArn":"${schedRoleArn}","schedulerQueueArn":"${schedQueueArn}","schedulerQueueName":"${schedQueueName}","publishToAggregates":{${publishToAggregatesJson}}}`
|
|
94
|
-
})
|
|
77
|
+
queue.id->Pulumi.Output.apply(id => id->String.split("/")->Array.at(-1)->Option.getOr(id))
|
|
78
|
+
|
|
79
|
+
let handlerConfigJson = Pulumi.Output.all([
|
|
80
|
+
queue.id,
|
|
81
|
+
extras.pluginReadModelTableName->outputOrPlaceholder->Obj.magic,
|
|
82
|
+
extras.schedulerRoleArn->outputOrPlaceholder->Obj.magic,
|
|
83
|
+
queue.arn,
|
|
84
|
+
queueName,
|
|
85
|
+
])->Pulumi.Output.apply(values => {
|
|
86
|
+
let queueUrl = values->Array.getUnsafe(0)
|
|
87
|
+
let rmTable = values->Array.getUnsafe(1)
|
|
88
|
+
let schedRoleArn = values->Array.getUnsafe(2)
|
|
89
|
+
let schedQueueArn = values->Array.getUnsafe(3)
|
|
90
|
+
let schedQueueName = values->Array.getUnsafe(4)
|
|
91
|
+
`{"queueUrl":"${queueUrl}","pluginReadModelTableName":"${rmTable}","schedulerRoleArn":"${schedRoleArn}","schedulerQueueArn":"${schedQueueArn}","schedulerQueueName":"${schedQueueName}","publishToAggregates":{${publishToAggregatesJson}}}`
|
|
92
|
+
})
|
|
95
93
|
envVars->Dict.set("HANDLER_CONFIG", handlerConfigJson->Pulumi.Output.asInput)
|
|
96
94
|
|
|
97
95
|
// No user packages — all framework imports are in the Layer
|