@reventlessdev/rescript-pulumi-aws 3.0.0-alpha.11 → 3.0.0-alpha.13
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 +16 -0
- package/package.json +3 -3
- package/src/AppSync/AppSync_ResolverRuntime.res +4 -5
- package/src/AppSync/AppSync_Resolver_Functions.res +137 -111
- package/src/AppSync/AppSync_SourceApiAssociation.res +1 -3
- package/src/AwsNative/AppSync/AwsNative_AppSync_Api.res +2 -3
- package/src/AwsNative/AppSync/AwsNative_AppSync_ChannelNamespace.res +2 -6
- package/src/AwsNative/AppSync/AwsNative_AppSync_Resolver.res +2 -5
- package/src/Cloudwatch/Cloudwatch_LogMetricFilter.res +0 -1
- package/src/Cloudwatch/Cloudwatch_MetricAlarm.res +0 -1
- package/src/Cognito/Cognito_UserPool.res +2 -4
- package/src/IAM/IAM.res +1 -1
- package/src/Kinesis/Kinesis_Stream.res +3 -6
- package/src/Lambda/FunctionUrl.res +5 -2
- package/src/Lambda/Lambda.res +6 -10
- package/src/Rds/Rds_Cluster.res +0 -1
- package/src/Rds/Rds_Instance.res +0 -1
- package/src/Rds/Rds_Proxy.res +1 -2
- package/src/S3/S3_BucketV2.res +1 -3
- package/src/example/CustomDomainExample.res +2 -3
- package/src/example/MergedApiExample.res +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.13 (2026-09-11)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @reventlessdev/rescript-pulumi-aws
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 3.0.0-alpha.12 (2026-09-09)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @reventlessdev/rescript-pulumi-aws
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
# 3.0.0-alpha.11 (2026-09-08)
|
|
7
23
|
|
|
8
24
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/rescript-pulumi-aws",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.13",
|
|
4
4
|
"description": "ReScript bindings for @pulumi/aws",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"@pulumi/aws": "~7.19.0",
|
|
23
23
|
"@pulumi/aws-native": "^1.62.0",
|
|
24
24
|
"sury": "11.0.0-rc.2",
|
|
25
|
-
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.
|
|
26
|
-
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.
|
|
25
|
+
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.18",
|
|
26
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.20"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"esbuild": "^0.25.12",
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Context types
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
1
5
|
/** Bindings for @aws-appsync/utils and AppSync JS resolver context types.
|
|
2
6
|
Used in resolver source files compiled to APPSYNC_JS — not Pulumi deploy-time code.
|
|
3
7
|
|
|
@@ -6,11 +10,6 @@
|
|
|
6
10
|
AppSync provides the module as an object with named exports. When bundled with
|
|
7
11
|
esbuild (--external:@aws-appsync/utils), the import is preserved for AppSync runtime.
|
|
8
12
|
*/
|
|
9
|
-
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
// Context types
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
|
|
14
13
|
type error = {
|
|
15
14
|
message: string,
|
|
16
15
|
@as("type") type_: string,
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
exported `request` and `response` functions, ready to be passed as the `code`
|
|
5
5
|
field of AppSync_Resolver.makeUnitJsResolver / makePipelineJsResolver.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
7
|
+
let // ---------------------------------------------------------------------------
|
|
9
8
|
// Shared response snippets (inlined into each resolver's template literal)
|
|
10
9
|
// ---------------------------------------------------------------------------
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
resultResponseCode = `
|
|
13
12
|
export function response(ctx) {
|
|
14
13
|
if (ctx.error) util.error(ctx.error.message, ctx.error.type);
|
|
15
14
|
return ctx.result;
|
|
@@ -191,15 +190,18 @@ let ownerScopedResultResponse = (
|
|
|
191
190
|
| _ =>
|
|
192
191
|
let ownerPart = switch ownerField {
|
|
193
192
|
// Takes the row it ignores: APPSYNC_JS type-checks the resolver, so a
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
193
|
+
// zero-parameter stub called as `_owns(row)` is TS2554 ("Expected 0
|
|
194
|
+
// arguments, but got 1") and AppSync rejects the whole resolver at create
|
|
195
|
+
// time with "The code contains one or more errors". Only a door that emits
|
|
196
|
+
// the call conditionally is safe with a bare `() => true`, and that is not a
|
|
197
|
+
// property worth relying on across three templates.
|
|
198
|
+
| None => "\n const _owns = (row) => true;"
|
|
200
199
|
| Some(field) =>
|
|
201
200
|
`
|
|
202
|
-
// ── owner scoping (generated) ──${ownerGuardPreamble(
|
|
201
|
+
// ── owner scoping (generated) ──${ownerGuardPreamble(
|
|
202
|
+
~ownerField=field,
|
|
203
|
+
~elevatedGroups,
|
|
204
|
+
)}`
|
|
203
205
|
}
|
|
204
206
|
let retiredPart = retiredGuardPreamble(
|
|
205
207
|
~retiredField,
|
|
@@ -210,7 +212,9 @@ let ownerScopedResultResponse = (
|
|
|
210
212
|
`
|
|
211
213
|
export function response(ctx) {
|
|
212
214
|
if (ctx.error) util.error(ctx.error.message, ctx.error.type);${ownerPart}${retiredPart}
|
|
213
|
-
return _owns(ctx.result)${retiredField->Option.isSome
|
|
215
|
+
return _owns(ctx.result)${retiredField->Option.isSome
|
|
216
|
+
? " && _live(ctx.result)"
|
|
217
|
+
: ""} ? ctx.result : null;
|
|
214
218
|
}`
|
|
215
219
|
}
|
|
216
220
|
|
|
@@ -226,15 +230,18 @@ let ownerScopedFirstResultResponse = (
|
|
|
226
230
|
| _ =>
|
|
227
231
|
let ownerPart = switch ownerField {
|
|
228
232
|
// Takes the row it ignores: APPSYNC_JS type-checks the resolver, so a
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
233
|
+
// zero-parameter stub called as `_owns(row)` is TS2554 ("Expected 0
|
|
234
|
+
// arguments, but got 1") and AppSync rejects the whole resolver at create
|
|
235
|
+
// time with "The code contains one or more errors". Only a door that emits
|
|
236
|
+
// the call conditionally is safe with a bare `() => true`, and that is not a
|
|
237
|
+
// property worth relying on across three templates.
|
|
238
|
+
| None => "\n const _owns = (row) => true;"
|
|
235
239
|
| Some(field) =>
|
|
236
240
|
`
|
|
237
|
-
// ── owner scoping (generated) ──${ownerGuardPreamble(
|
|
241
|
+
// ── owner scoping (generated) ──${ownerGuardPreamble(
|
|
242
|
+
~ownerField=field,
|
|
243
|
+
~elevatedGroups,
|
|
244
|
+
)}`
|
|
238
245
|
}
|
|
239
246
|
let retiredPart = retiredGuardPreamble(
|
|
240
247
|
~retiredField,
|
|
@@ -255,8 +262,7 @@ export function response(ctx) {
|
|
|
255
262
|
// ---------------------------------------------------------------------------
|
|
256
263
|
|
|
257
264
|
/** Pipeline resolver code with no pre-processing and a standard error-check response. */
|
|
258
|
-
let pipelinePassThrough =
|
|
259
|
-
`${importUtil}
|
|
265
|
+
let pipelinePassThrough = `${importUtil}
|
|
260
266
|
export function request(ctx) { return {}; }
|
|
261
267
|
${resultResponseCode}
|
|
262
268
|
`->Pulumi.Input.make
|
|
@@ -329,8 +335,7 @@ export function request(ctx) {
|
|
|
329
335
|
${ownerScopedResultResponse(~ownerField, ~elevatedGroups, ~retiredField?, ~retiredValues?)}
|
|
330
336
|
`->Pulumi.Input.make
|
|
331
337
|
|
|
332
|
-
let queryById =
|
|
333
|
-
`${importUtil}
|
|
338
|
+
let queryById = `${importUtil}
|
|
334
339
|
export function request(ctx) {
|
|
335
340
|
return {
|
|
336
341
|
operation: 'Query',
|
|
@@ -348,11 +353,11 @@ ${resultResponseCode}
|
|
|
348
353
|
Relay pagination: `first`/`after` (forward) or `last`/`before` (backward).
|
|
349
354
|
Cursor is base64 of the sort key value.
|
|
350
355
|
Returns a Relay `{ edges, pageInfo }` shape reusing the entity's `Connection` type. */
|
|
351
|
-
// A list in everything but its name, so it scopes the way `listAllItemsConnection`
|
|
356
|
+
let // A list in everything but its name, so it scopes the way `listAllItemsConnection`
|
|
352
357
|
// does — a FilterExpression on the request, not a guard on the response. The
|
|
353
358
|
// response is where the page is cut, and narrowing after that cut would report
|
|
354
359
|
// `hasNextPage` from a count the caller was never allowed to see.
|
|
355
|
-
|
|
360
|
+
queryItemsWithSortConditions = (
|
|
356
361
|
sortField: string,
|
|
357
362
|
~ownerField: option<string>=?,
|
|
358
363
|
~elevatedGroups: array<string>=[],
|
|
@@ -585,7 +590,8 @@ index among that window's matches (`n`). Pre-window cursors carried
|
|
|
585
590
|
tag existed came off a Scan. Only a door with more than one read tests it — see
|
|
586
591
|
`cursorPathGuard`.
|
|
587
592
|
*/
|
|
588
|
-
let cursorDecode = (~args: string) =>
|
|
593
|
+
let cursorDecode = (~args: string) =>
|
|
594
|
+
`
|
|
589
595
|
let _window = null;
|
|
590
596
|
let _from = 0;
|
|
591
597
|
let _cursorPath = null;
|
|
@@ -779,7 +785,11 @@ export function request(ctx) {
|
|
|
779
785
|
values[':' + key] = '' + value;
|
|
780
786
|
}
|
|
781
787
|
});
|
|
782
|
-
${ownerFilterClause(~ownerField, ~elevatedGroups)}${retiredFilterClause(
|
|
788
|
+
${ownerFilterClause(~ownerField, ~elevatedGroups)}${retiredFilterClause(
|
|
789
|
+
~retiredField,
|
|
790
|
+
~retiredValues,
|
|
791
|
+
~elevatedGroups,
|
|
792
|
+
)}${indexCursorPreamble}
|
|
783
793
|
const result = {
|
|
784
794
|
operation: 'Query',
|
|
785
795
|
query,
|
|
@@ -842,7 +852,11 @@ export function request(ctx) {
|
|
|
842
852
|
values[':' + key] = '' + value;
|
|
843
853
|
}
|
|
844
854
|
});
|
|
845
|
-
${ownerFilterClause(~ownerField, ~elevatedGroups)}${retiredFilterClause(
|
|
855
|
+
${ownerFilterClause(~ownerField, ~elevatedGroups)}${retiredFilterClause(
|
|
856
|
+
~retiredField,
|
|
857
|
+
~retiredValues,
|
|
858
|
+
~elevatedGroups,
|
|
859
|
+
)}${indexCursorPreamble}
|
|
846
860
|
const result = {
|
|
847
861
|
operation: 'Query',
|
|
848
862
|
query,
|
|
@@ -863,8 +877,7 @@ ${indexConnectionResponseCode}
|
|
|
863
877
|
// DynamoDB read — list all
|
|
864
878
|
// ---------------------------------------------------------------------------
|
|
865
879
|
|
|
866
|
-
let listAllItems =
|
|
867
|
-
`${importUtil}
|
|
880
|
+
let listAllItems = `${importUtil}
|
|
868
881
|
export function request(ctx) {
|
|
869
882
|
return {
|
|
870
883
|
operation: 'Scan',
|
|
@@ -928,7 +941,8 @@ let listAllItemsConnection = (
|
|
|
928
941
|
// have nothing to name in the key condition.
|
|
929
942
|
let ownerIndex = ownerField->Option.isSome ? ownerIndex : None
|
|
930
943
|
let requireAttributeClause = switch requireAttribute {
|
|
931
|
-
| Some(attr) =>
|
|
944
|
+
| Some(attr) =>
|
|
945
|
+
`
|
|
932
946
|
names['#${attr}'] = '${attr}';
|
|
933
947
|
parts.push('attribute_exists(#${attr})');`
|
|
934
948
|
| None => ""
|
|
@@ -986,7 +1000,8 @@ let listAllItemsConnection = (
|
|
|
986
1000
|
let elevatedLiteral = elevatedGroups->Array.map(g => `'${g}'`)->Array.join(", ")
|
|
987
1001
|
let exemptPrelude = switch ownerField {
|
|
988
1002
|
| Some(_) => ""
|
|
989
|
-
| None =>
|
|
1003
|
+
| None =>
|
|
1004
|
+
`
|
|
990
1005
|
const _id = ctx.identity;
|
|
991
1006
|
const _sub = _id == null ? null : _id.sub;
|
|
992
1007
|
const _groups = (_id != null && _id.claims != null && _id.claims['cognito:groups']) || [];
|
|
@@ -1007,10 +1022,13 @@ ${switch retiredValues {
|
|
|
1007
1022
|
// once for the whole clause — a row that states no lifecycle is not
|
|
1008
1023
|
// retired, the same reading every other adapter takes.
|
|
1009
1024
|
| Some(states) =>
|
|
1010
|
-
let placeholders =
|
|
1025
|
+
let placeholders =
|
|
1026
|
+
states->Array.mapWithIndex((state, i) => (`:retiredValue${Int.toString(i)}`, state))
|
|
1011
1027
|
let assignments =
|
|
1012
1028
|
placeholders
|
|
1013
|
-
->Array.map(((ph, state)) =>
|
|
1029
|
+
->Array.map(((ph, state)) =>
|
|
1030
|
+
` values['${ph}'] = util.dynamodb.toDynamoDB('${state}');`
|
|
1031
|
+
)
|
|
1014
1032
|
->Array.join("\n")
|
|
1015
1033
|
let comparisons =
|
|
1016
1034
|
placeholders->Array.map(((ph, _)) => `#retired <> ${ph}`)->Array.join(" AND ")
|
|
@@ -1026,16 +1044,19 @@ ${switch retiredValues {
|
|
|
1026
1044
|
}
|
|
1027
1045
|
let filterClauses =
|
|
1028
1046
|
filterFields
|
|
1029
|
-
->Array.map(f =>
|
|
1047
|
+
->Array.map(f =>
|
|
1048
|
+
`
|
|
1030
1049
|
if (filter.${f}Eq !== undefined && filter.${f}Eq !== null && filter.${f}Eq !== '') {
|
|
1031
1050
|
names['#${f}'] = '${f}';
|
|
1032
1051
|
values[':${f}Eq'] = util.dynamodb.toDynamoDB(filter.${f}Eq);
|
|
1033
1052
|
parts.push('#${f} = :${f}Eq');
|
|
1034
|
-
}`
|
|
1053
|
+
}`
|
|
1054
|
+
)
|
|
1035
1055
|
->Array.join("")
|
|
1036
1056
|
let rangeClauses =
|
|
1037
1057
|
rangeFields
|
|
1038
|
-
->Array.map(f =>
|
|
1058
|
+
->Array.map(f =>
|
|
1059
|
+
`
|
|
1039
1060
|
if (filter.${f}From !== undefined && filter.${f}From !== null && filter.${f}From !== '') {
|
|
1040
1061
|
names['#${f}'] = '${f}';
|
|
1041
1062
|
values[':${f}From'] = util.dynamodb.toDynamoDB(filter.${f}From);
|
|
@@ -1045,10 +1066,10 @@ ${switch retiredValues {
|
|
|
1045
1066
|
names['#${f}'] = '${f}';
|
|
1046
1067
|
values[':${f}To'] = util.dynamodb.toDynamoDB(filter.${f}To);
|
|
1047
1068
|
parts.push('#${f} <= :${f}To');
|
|
1048
|
-
}`
|
|
1069
|
+
}`
|
|
1070
|
+
)
|
|
1049
1071
|
->Array.join("")
|
|
1050
|
-
let sortFieldsLiteral =
|
|
1051
|
-
sortFields->Array.map(f => `'${f}'`)->Array.join(", ")
|
|
1072
|
+
let sortFieldsLiteral = sortFields->Array.map(f => `'${f}'`)->Array.join(", ")
|
|
1052
1073
|
// When the Query branch already ordered on the index's own sort key, the page
|
|
1053
1074
|
// arrives globally ordered and re-sorting it here is the one way to break that
|
|
1054
1075
|
// order — a sort over a page is not a sort over the caller's rows.
|
|
@@ -1090,8 +1111,7 @@ ${switch retiredValues {
|
|
|
1090
1111
|
// halves, because both need it: the request to set `scanIndexForward`, the
|
|
1091
1112
|
// response to leave an already-ordered page alone.
|
|
1092
1113
|
let indexOrderedExpr = switch (ownerIndex, ownerIndexSortField) {
|
|
1093
|
-
| (Some(_), Some(sf)) =>
|
|
1094
|
-
`!_exempt && !!(ctx.args.orderBy && ctx.args.orderBy.field === '${sf}')`
|
|
1114
|
+
| (Some(_), Some(sf)) => `!_exempt && !!(ctx.args.orderBy && ctx.args.orderBy.field === '${sf}')`
|
|
1095
1115
|
| _ => "false"
|
|
1096
1116
|
}
|
|
1097
1117
|
// The two reads, chosen by the same test that used to choose a predicate.
|
|
@@ -1099,7 +1119,8 @@ ${switch retiredValues {
|
|
|
1099
1119
|
// branch inside one resolver — no second field, no second data source, no
|
|
1100
1120
|
// client change.
|
|
1101
1121
|
let requestOperation = switch (ownerField, ownerIndex) {
|
|
1102
|
-
| (Some(field), Some(index)) =>
|
|
1122
|
+
| (Some(field), Some(index)) =>
|
|
1123
|
+
`
|
|
1103
1124
|
const _indexOrdered = ${indexOrderedExpr};
|
|
1104
1125
|
const req = _exempt
|
|
1105
1126
|
? {
|
|
@@ -1119,7 +1140,8 @@ ${switch retiredValues {
|
|
|
1119
1140
|
nextToken: _window,
|
|
1120
1141
|
scanIndexForward: !(_indexOrdered && ctx.args.orderBy.direction === 'DESC'),
|
|
1121
1142
|
};`
|
|
1122
|
-
| _ =>
|
|
1143
|
+
| _ =>
|
|
1144
|
+
`
|
|
1123
1145
|
const req = {
|
|
1124
1146
|
operation: 'Scan',
|
|
1125
1147
|
limit: ${listPageWindowBudget},
|
|
@@ -1130,7 +1152,8 @@ ${switch retiredValues {
|
|
|
1130
1152
|
let requestPathGuard = ownerIndex->Option.isSome ? cursorPathGuard : ""
|
|
1131
1153
|
let responsePathPreamble = switch ownerIndex {
|
|
1132
1154
|
| None => ""
|
|
1133
|
-
| Some(_) =>
|
|
1155
|
+
| Some(_) =>
|
|
1156
|
+
`${ownerIdentityPreamble}
|
|
1134
1157
|
const _path = _exempt ? 's' : 'q';
|
|
1135
1158
|
const _indexOrdered = ${indexOrderedExpr};`
|
|
1136
1159
|
}
|
|
@@ -1224,7 +1247,10 @@ let resolvedFieldResponse = (
|
|
|
1224
1247
|
| None => "\n const _owns = (row) => true;"
|
|
1225
1248
|
| Some(field) =>
|
|
1226
1249
|
`
|
|
1227
|
-
// ── owner scoping (generated) ──${ownerGuardPreamble(
|
|
1250
|
+
// ── owner scoping (generated) ──${ownerGuardPreamble(
|
|
1251
|
+
~ownerField=field,
|
|
1252
|
+
~elevatedGroups,
|
|
1253
|
+
)}`
|
|
1228
1254
|
}
|
|
1229
1255
|
let retiredPart = retiredGuardPreamble(
|
|
1230
1256
|
~retiredField,
|
|
@@ -1427,13 +1453,14 @@ let resolveIds = (
|
|
|
1427
1453
|
~retiredField: option<string>=?,
|
|
1428
1454
|
~retiredValues: option<array<string>>=?,
|
|
1429
1455
|
~elevatedGroups: array<string>=[],
|
|
1430
|
-
) =>
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1456
|
+
) =>
|
|
1457
|
+
(tableName: string) => {
|
|
1458
|
+
let keysCode = switch sortField {
|
|
1459
|
+
| Some(sf) =>
|
|
1460
|
+
`id => ({ id: util.dynamodb.toString(id.id), ${sf}: util.dynamodb.toString(id.${sf}) })`
|
|
1461
|
+
| None => `id => ({ id: util.dynamodb.toString(id) })`
|
|
1462
|
+
}
|
|
1463
|
+
`${importUtil}
|
|
1437
1464
|
import { runtime } from '@aws-appsync/utils';
|
|
1438
1465
|
export function request(ctx) {
|
|
1439
1466
|
const idList = ctx.source.${idsField} ?? [];
|
|
@@ -1450,21 +1477,21 @@ export function request(ctx) {
|
|
|
1450
1477
|
}
|
|
1451
1478
|
export function response(ctx) {
|
|
1452
1479
|
if (ctx.error) util.error(ctx.error.message, ctx.error.type);${switch ownerField {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1480
|
+
| None => ""
|
|
1481
|
+
| Some(field) => ownerGuardPreamble(~ownerField=field, ~elevatedGroups)
|
|
1482
|
+
}}${retiredGuardPreamble(
|
|
1483
|
+
~retiredField,
|
|
1484
|
+
~retiredValues,
|
|
1485
|
+
~elevatedGroups,
|
|
1486
|
+
~ownerScoped=ownerField->Option.isSome,
|
|
1487
|
+
)}
|
|
1461
1488
|
return (ctx.result?.data?.['${tableName}'] ?? []).filter(item =>
|
|
1462
1489
|
item !== null${ownerField->Option.isSome ? " && _owns(item)" : ""}${retiredField->Option.isSome
|
|
1463
|
-
|
|
1464
|
-
|
|
1490
|
+
? " && _live(item)"
|
|
1491
|
+
: ""});
|
|
1465
1492
|
}
|
|
1466
1493
|
`
|
|
1467
|
-
}
|
|
1494
|
+
}
|
|
1468
1495
|
|
|
1469
1496
|
/** Batched-by-ids — reads `ctx.args.ids: [String!]!` through one BatchGetItem.
|
|
1470
1497
|
Missing ids drop out; empty input short-circuits without hitting DDB. The
|
|
@@ -1475,8 +1502,9 @@ let batchGetItemsByIds = (
|
|
|
1475
1502
|
~retiredField: option<string>=?,
|
|
1476
1503
|
~retiredValues: option<array<string>>=?,
|
|
1477
1504
|
~elevatedGroups: array<string>=[],
|
|
1478
|
-
) =>
|
|
1479
|
-
|
|
1505
|
+
) =>
|
|
1506
|
+
(tableName: string) =>
|
|
1507
|
+
`${importUtil}
|
|
1480
1508
|
import { runtime } from '@aws-appsync/utils';
|
|
1481
1509
|
export function request(ctx) {
|
|
1482
1510
|
const ids = ctx.args.ids ?? [];
|
|
@@ -1501,18 +1529,18 @@ export function response(ctx) {
|
|
|
1501
1529
|
// caller does not own is dropped rather than refused, for the reason the
|
|
1502
1530
|
// single-key door answers null: distinguishing "not yours" from "not there"
|
|
1503
1531
|
// would make this door an oracle for which ids exist.${switch ownerField {
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1532
|
+
| None => ""
|
|
1533
|
+
| Some(field) => ownerGuardPreamble(~ownerField=field, ~elevatedGroups)
|
|
1534
|
+
}}${retiredGuardPreamble(
|
|
1535
|
+
~retiredField,
|
|
1536
|
+
~retiredValues,
|
|
1537
|
+
~elevatedGroups,
|
|
1538
|
+
~ownerScoped=ownerField->Option.isSome,
|
|
1539
|
+
)}
|
|
1512
1540
|
return (ctx.result?.data?.['${tableName}'] ?? []).filter(item =>
|
|
1513
1541
|
item !== null${ownerField->Option.isSome ? " && _owns(item)" : ""}${retiredField->Option.isSome
|
|
1514
|
-
|
|
1515
|
-
|
|
1542
|
+
? " && _live(item)"
|
|
1543
|
+
: ""});
|
|
1516
1544
|
}
|
|
1517
1545
|
`
|
|
1518
1546
|
|
|
@@ -1536,35 +1564,36 @@ let refsByIds = (
|
|
|
1536
1564
|
~imageExpr: option<string>=?,
|
|
1537
1565
|
~ownerField: option<string>=?,
|
|
1538
1566
|
~elevatedGroups: array<string>=[],
|
|
1539
|
-
) =>
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1567
|
+
) =>
|
|
1568
|
+
(tableName: string) => {
|
|
1569
|
+
let ownerGuard = switch ownerField {
|
|
1570
|
+
// Takes the row it ignores: APPSYNC_JS type-checks the resolver, so a
|
|
1571
|
+
// zero-parameter stub called as `_owns(row)` is TS2554 ("Expected 0
|
|
1572
|
+
// arguments, but got 1") and AppSync rejects the whole resolver at create
|
|
1573
|
+
// time with "The code contains one or more errors". Only a door that emits
|
|
1574
|
+
// the call conditionally is safe with a bare `() => true`, and that is not a
|
|
1575
|
+
// property worth relying on across three templates.
|
|
1576
|
+
| None => "\n const _owns = (row) => true;"
|
|
1577
|
+
| Some(field) => ownerGuardPreamble(~ownerField=field, ~elevatedGroups)
|
|
1578
|
+
}
|
|
1579
|
+
// Retirement, in the vocabulary the row itself uses: a member test for the
|
|
1580
|
+
// state form, truthiness for the boolean one. Absent keeps the row live, which
|
|
1581
|
+
// is what a row written before the annotation is.
|
|
1582
|
+
let retiredExpr = switch (retiredField, retiredValues) {
|
|
1583
|
+
| (None, _) => "false"
|
|
1584
|
+
| (Some(f), Some(values)) =>
|
|
1585
|
+
let literal = values->Array.map(v => `'${v}'`)->Array.join(", ")
|
|
1586
|
+
`[${literal}].indexOf(row['${f}']) >= 0`
|
|
1587
|
+
| (Some(f), None) => `row['${f}'] === true`
|
|
1588
|
+
}
|
|
1589
|
+
// Only the state form has a state to name, and only a retired row reports one:
|
|
1590
|
+
// this door names rows, it does not publish a lifecycle column to callers the
|
|
1591
|
+
// list withholds.
|
|
1592
|
+
let stateExpr = switch (retiredField, retiredValues) {
|
|
1593
|
+
| (Some(f), Some(_)) => `_retired(row) ? (row['${f}'] ?? null) : null`
|
|
1594
|
+
| _ => "null"
|
|
1595
|
+
}
|
|
1596
|
+
`${importUtil}
|
|
1568
1597
|
import { runtime } from '@aws-appsync/utils';
|
|
1569
1598
|
export function request(ctx) {
|
|
1570
1599
|
const ids = ctx.args.ids ?? [];
|
|
@@ -1595,14 +1624,13 @@ export function response(ctx) {
|
|
|
1595
1624
|
}));
|
|
1596
1625
|
}
|
|
1597
1626
|
`
|
|
1598
|
-
}
|
|
1627
|
+
}
|
|
1599
1628
|
|
|
1600
1629
|
// ---------------------------------------------------------------------------
|
|
1601
1630
|
// DynamoDB write
|
|
1602
1631
|
// ---------------------------------------------------------------------------
|
|
1603
1632
|
|
|
1604
|
-
let putItem =
|
|
1605
|
-
`${importUtil}
|
|
1633
|
+
let putItem = `${importUtil}
|
|
1606
1634
|
export function request(ctx) {
|
|
1607
1635
|
return {
|
|
1608
1636
|
operation: 'PutItem',
|
|
@@ -1629,8 +1657,7 @@ export function request(ctx) {
|
|
|
1629
1657
|
${resultResponseCode}
|
|
1630
1658
|
`->Pulumi.Input.make
|
|
1631
1659
|
|
|
1632
|
-
let deleteItem =
|
|
1633
|
-
`${importUtil}
|
|
1660
|
+
let deleteItem = `${importUtil}
|
|
1634
1661
|
export function request(ctx) {
|
|
1635
1662
|
return {
|
|
1636
1663
|
operation: 'DeleteItem',
|
|
@@ -1773,8 +1800,7 @@ export function response(ctx) {
|
|
|
1773
1800
|
let authorizeIndexedAccessRequest = authorizeIndexedAccess
|
|
1774
1801
|
|
|
1775
1802
|
/** @deprecated The response check is now part of authorizeIndexedAccess. */
|
|
1776
|
-
let authorizeIndexedAccessResponse = (~group as _: string) =>
|
|
1777
|
-
resultResponseCode->Pulumi.Input.make
|
|
1803
|
+
let authorizeIndexedAccessResponse = (~group as _: string) => resultResponseCode->Pulumi.Input.make
|
|
1778
1804
|
|
|
1779
1805
|
// ---------------------------------------------------------------------------
|
|
1780
1806
|
// Response-only helpers
|
|
@@ -28,9 +28,7 @@ type args = {
|
|
|
28
28
|
mergedApiArn?: Pulumi.Input.t<string>,
|
|
29
29
|
sourceApiId?: Pulumi.Input.t<string>,
|
|
30
30
|
sourceApiArn?: Pulumi.Input.t<string>,
|
|
31
|
-
sourceApiAssociationConfigs?: Pulumi.Input.t<
|
|
32
|
-
array<Pulumi.Input.t<sourceApiAssociationConfig>>,
|
|
33
|
-
>,
|
|
31
|
+
sourceApiAssociationConfigs?: Pulumi.Input.t<array<Pulumi.Input.t<sourceApiAssociationConfig>>>,
|
|
34
32
|
description?: Pulumi.Input.t<string>,
|
|
35
33
|
}
|
|
36
34
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
+
// ── Auth types ────────────────────────────────────────────────────────────────
|
|
2
|
+
|
|
1
3
|
/** @pulumi/aws-native/appsync/Api — AppSync Events (Pub/Sub) API.
|
|
2
4
|
Distinct from AppSync GraphQL API (`aws.appsync.GraphQLApi`).
|
|
3
5
|
Used for real-time server-to-client event push via AppSync Events channels.
|
|
4
6
|
See: https://www.pulumi.com/registry/packages/aws-native/api-docs/appsync/api
|
|
5
7
|
*/
|
|
6
|
-
|
|
7
|
-
// ── Auth types ────────────────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
8
|
/** Authentication mode for connections / publish / subscribe. */
|
|
10
9
|
type authMode = {
|
|
11
10
|
/** Auth type string — use the `authType` constants below. */
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
Channels within the namespace are addressed as `/default/{channelName}`.
|
|
5
5
|
See: https://www.pulumi.com/registry/packages/aws-native/api-docs/appsync/channelnamespace
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
7
|
type authMode = {
|
|
9
8
|
authType?: Pulumi.Input.t<string>,
|
|
10
9
|
}
|
|
@@ -74,8 +73,5 @@ type args = {
|
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
@module("@pulumi/aws-native") @scope("appsync") @new
|
|
77
|
-
external make: (
|
|
78
|
-
|
|
79
|
-
~args: args,
|
|
80
|
-
~opts: option<Pulumi.CustomResourceOptions.t>=?,
|
|
81
|
-
) => t = "ChannelNamespace"
|
|
76
|
+
external make: (~name: string, ~args: args, ~opts: option<Pulumi.CustomResourceOptions.t>=?) => t =
|
|
77
|
+
"ChannelNamespace"
|
|
@@ -32,8 +32,5 @@ type args = {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
@module("@pulumi/aws-native") @scope("appsync") @new
|
|
35
|
-
external make: (
|
|
36
|
-
|
|
37
|
-
~args: args,
|
|
38
|
-
~opts: option<Pulumi.CustomResourceOptions.t>=?,
|
|
39
|
-
) => t = "Resolver"
|
|
35
|
+
external make: (~name: string, ~args: args, ~opts: option<Pulumi.CustomResourceOptions.t>=?) => t =
|
|
36
|
+
"Resolver"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** @pulumi/aws/cloudwatch/logmetricfilter
|
|
2
2
|
see: https://www.pulumi.com/registry/packages/aws/api-docs/cloudwatch/logmetricfilter/
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
4
|
/** How matched log events are turned into a CloudWatch metric data point.
|
|
6
5
|
`value`/`dimensions` use metric-filter JSON selectors (e.g. `"$.value"`). */
|
|
7
6
|
type metricTransformation = {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** @pulumi/aws/cloudwatch/metricalarm
|
|
2
2
|
see: https://www.pulumi.com/registry/packages/aws/api-docs/cloudwatch/metricalarm/
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
4
|
type t = {arn: Pulumi.Output.t<string>, id: Pulumi.Output.t<string>}
|
|
6
5
|
|
|
7
6
|
/** Single-metric alarm args. `comparisonOperator` uses CloudWatch's operator
|
|
@@ -119,7 +119,5 @@ type getResult = {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
@module("@pulumi/aws") @scope("cognito") @val
|
|
122
|
-
external getUserPoolOutput: (
|
|
123
|
-
|
|
124
|
-
~opts: InvokeOptions.t=?,
|
|
125
|
-
) => Output.t<getResult> = "getUserPoolOutput"
|
|
122
|
+
external getUserPoolOutput: (~args: getArgs, ~opts: InvokeOptions.t=?) => Output.t<getResult> =
|
|
123
|
+
"getUserPoolOutput"
|
package/src/IAM/IAM.res
CHANGED
|
@@ -54,11 +54,8 @@ module EventSubscription = {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
@module("@pulumi/aws") @scope("kinesis") @new
|
|
57
|
-
external make: (
|
|
58
|
-
|
|
59
|
-
~args: args=?,
|
|
60
|
-
~opts: Pulumi.CustomResourceOptions.t=?
|
|
61
|
-
) => stream = "Stream"
|
|
57
|
+
external make: (~name: string, ~args: args=?, ~opts: Pulumi.CustomResourceOptions.t=?) => stream =
|
|
58
|
+
"Stream"
|
|
62
59
|
|
|
63
60
|
@send
|
|
64
61
|
external onEvent: (
|
|
@@ -66,5 +63,5 @@ external onEvent: (
|
|
|
66
63
|
~name: string,
|
|
67
64
|
~handler: Lambda.eventHandlerNoResult<event>,
|
|
68
65
|
~args: subscriptionArgs=?,
|
|
69
|
-
~opts: Pulumi.CustomResourceOptions.t
|
|
66
|
+
~opts: Pulumi.CustomResourceOptions.t=?,
|
|
70
67
|
) => EventSubscription.t = "onEvent"
|
|
@@ -37,5 +37,8 @@ external make: (~name: string, ~args: args, ~opts: Pulumi.CustomResourceOptions.
|
|
|
37
37
|
"FunctionUrl"
|
|
38
38
|
|
|
39
39
|
@module("@pulumi/aws") @scope(("lambda", "FunctionUrl"))
|
|
40
|
-
external get: (
|
|
41
|
-
|
|
40
|
+
external get: (
|
|
41
|
+
~name: string,
|
|
42
|
+
~id: Pulumi.Input.t<string>,
|
|
43
|
+
~opts: Pulumi.CustomResourceOptions.t=?,
|
|
44
|
+
) => t = "get"
|
package/src/Lambda/Lambda.res
CHANGED
|
@@ -88,11 +88,10 @@ let _resolveLayerArnFromSsm = (): option<string> =>
|
|
|
88
88
|
* manually.
|
|
89
89
|
* 3. `None` when both fail — Lambdas deploy without the layer.
|
|
90
90
|
*/
|
|
91
|
-
let reventlessLayerArn: option<string> =
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
91
|
+
let reventlessLayerArn: option<string> = switch _layerArnEnv {
|
|
92
|
+
| Some(arn) if arn->String.trim->String.length > 0 => Some(arn->String.trim)
|
|
93
|
+
| _ => _resolveLayerArnFromSsm()
|
|
94
|
+
}
|
|
96
95
|
|
|
97
96
|
@val
|
|
98
97
|
external environment: option<string> = "process.env.Environment"
|
|
@@ -262,11 +261,8 @@ module Function = {
|
|
|
262
261
|
}
|
|
263
262
|
|
|
264
263
|
@module("@pulumi/aws") @scope("lambda") @new
|
|
265
|
-
external make: (
|
|
266
|
-
|
|
267
|
-
~args: args,
|
|
268
|
-
~opts: Pulumi.CustomResourceOptions.t=?,
|
|
269
|
-
) => t = "Function"
|
|
264
|
+
external make: (~name: string, ~args: args, ~opts: Pulumi.CustomResourceOptions.t=?) => t =
|
|
265
|
+
"Function"
|
|
270
266
|
|
|
271
267
|
@module("@pulumi/aws") @scope(("lambda", "Function"))
|
|
272
268
|
external get: (
|
package/src/Rds/Rds_Cluster.res
CHANGED
package/src/Rds/Rds_Instance.res
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** @pulumi/aws/rds/instance
|
|
2
2
|
see: https://www.pulumi.com/registry/packages/aws/api-docs/rds/instance
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
4
|
/** One entry of `masterUserSecrets`, populated when `manageMasterUserPassword`
|
|
6
5
|
is true — RDS creates and rotates the master password in Secrets Manager and
|
|
7
6
|
reports the secret ARN here. */
|
package/src/Rds/Rds_Proxy.res
CHANGED
|
@@ -34,5 +34,4 @@ type args = {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
@module("@pulumi/aws") @scope("rds") @new
|
|
37
|
-
external make: (~name: string, ~args: args, ~opts: Pulumi.CustomResourceOptions.t=?) => t =
|
|
38
|
-
"Proxy"
|
|
37
|
+
external make: (~name: string, ~args: args, ~opts: Pulumi.CustomResourceOptions.t=?) => t = "Proxy"
|
package/src/S3/S3_BucketV2.res
CHANGED
|
@@ -18,9 +18,8 @@ let cert = Acm.Certificate.make(
|
|
|
18
18
|
~opts={provider: usEast1},
|
|
19
19
|
)
|
|
20
20
|
|
|
21
|
-
let firstValidationOption =
|
|
22
|
-
opts->Array.getUnsafe(0)
|
|
23
|
-
)
|
|
21
|
+
let firstValidationOption =
|
|
22
|
+
cert.domainValidationOptions->Pulumi.Output.apply(opts => opts->Array.getUnsafe(0))
|
|
24
23
|
|
|
25
24
|
let validationRecord = Route53.Record.make(
|
|
26
25
|
~name="example-cert-validation",
|
|
@@ -8,9 +8,7 @@
|
|
|
8
8
|
let mergedExecRole = IAM.Role.make(
|
|
9
9
|
~name="example-merged-exec-role",
|
|
10
10
|
~args={
|
|
11
|
-
assumeRolePolicy: Pulumi.Input.make(
|
|
12
|
-
`{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"appsync.amazonaws.com"},"Action":"sts:AssumeRole"}]}`,
|
|
13
|
-
),
|
|
11
|
+
assumeRolePolicy: Pulumi.Input.make(`{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"appsync.amazonaws.com"},"Action":"sts:AssumeRole"}]}`),
|
|
14
12
|
},
|
|
15
13
|
)
|
|
16
14
|
|