@reventlessdev/rescript-pulumi-aws 3.0.0-alpha.13 → 3.0.0-alpha.15
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 +20 -0
- package/package.json +8 -7
- package/rescript.json +2 -1
- package/src/AppSync/AppSync_Resolver_Functions.res.mjs +13 -15
- package/src/IAM/PolicyDocument.res +2 -2
- package/src/IAM/PolicyDocument.res.mjs +3 -3
- package/src/Lambda/Lambda.res +126 -46
- package/src/Lambda/Lambda.res.mjs +152 -23
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
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.15 (2026-09-21)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **deps:** update rescript to 12.3.1 ([ea1ce37](https://github.com/ReventlessDev/reventless-core/commit/ea1ce377297640f6d0d360e6c84c778d59ecbcc5))
|
|
11
|
+
* **deps:** update sury to 11.0.0 ([8715b22](https://github.com/ReventlessDev/reventless-core/commit/8715b22b33856c46ba57518aad151065c123a995))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 3.0.0-alpha.14 (2026-09-16)
|
|
15
|
+
|
|
16
|
+
* fix(aws)!: stop a deploy that finds no Lambda layer ([62957f4](https://github.com/ReventlessDev/reventless-core/commit/62957f444ab2120f672b9ac0564f786d64090864))
|
|
17
|
+
|
|
18
|
+
### BREAKING CHANGES
|
|
19
|
+
|
|
20
|
+
* PulumiAws.Lambda.reventlessLayerArn is now a function that
|
|
21
|
+
returns the ARN and throws when there is none. Use Lambda.reventlessLayers()
|
|
22
|
+
for a function's layers argument.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
6
26
|
# 3.0.0-alpha.13 (2026-09-11)
|
|
7
27
|
|
|
8
28
|
**Note:** Version bump only for package @reventlessdev/rescript-pulumi-aws
|
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.15",
|
|
4
4
|
"description": "ReScript bindings for @pulumi/aws",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -21,17 +21,18 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@pulumi/aws": "~7.19.0",
|
|
23
23
|
"@pulumi/aws-native": "^1.62.0",
|
|
24
|
-
"sury": "11.0.0
|
|
25
|
-
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.
|
|
26
|
-
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.
|
|
24
|
+
"sury": "11.0.0",
|
|
25
|
+
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.20",
|
|
26
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.22",
|
|
27
|
+
"@reventlessdev/rescript-node": "2.0.0-alpha.13"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"esbuild": "^0.25.12",
|
|
30
|
-
"rescript": "12.3.
|
|
31
|
-
"sury-ppx": "11.0.0
|
|
31
|
+
"rescript": "12.3.1",
|
|
32
|
+
"sury-ppx": "11.0.0"
|
|
32
33
|
},
|
|
33
34
|
"peerDependencies": {
|
|
34
|
-
"rescript": "12.3.
|
|
35
|
+
"rescript": "^12.3.1"
|
|
35
36
|
},
|
|
36
37
|
"gitHead": "ddea51534dc210635d7b11968089627b3b697ce2",
|
|
37
38
|
"publishConfig": {
|
package/rescript.json
CHANGED
|
@@ -977,9 +977,9 @@ export function request(ctx) {
|
|
|
977
977
|
`;
|
|
978
978
|
}
|
|
979
979
|
|
|
980
|
-
function resolveIds(idsField, sortField, ownerField, retiredField, retiredValues,
|
|
980
|
+
function resolveIds(idsField, sortField, ownerField, retiredField, retiredValues, elevatedGroupsOpt) {
|
|
981
|
+
let elevatedGroups = elevatedGroupsOpt !== undefined ? elevatedGroupsOpt : [];
|
|
981
982
|
return tableName => {
|
|
982
|
-
let elevatedGroups = $staropt$star !== undefined ? $staropt$star : [];
|
|
983
983
|
let keysCode = sortField !== undefined ? `id => ({ id: util.dynamodb.toString(id.id), ` + sortField + `: util.dynamodb.toString(id.` + sortField + `) })` : `id => ({ id: util.dynamodb.toString(id) })`;
|
|
984
984
|
return importUtil + `
|
|
985
985
|
import { runtime } from '@aws-appsync/utils';
|
|
@@ -1011,10 +1011,9 @@ export function response(ctx) {
|
|
|
1011
1011
|
};
|
|
1012
1012
|
}
|
|
1013
1013
|
|
|
1014
|
-
function batchGetItemsByIds(ownerField, retiredField, retiredValues,
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
return importUtil + `
|
|
1014
|
+
function batchGetItemsByIds(ownerField, retiredField, retiredValues, elevatedGroupsOpt) {
|
|
1015
|
+
let elevatedGroups = elevatedGroupsOpt !== undefined ? elevatedGroupsOpt : [];
|
|
1016
|
+
return tableName => importUtil + `
|
|
1018
1017
|
import { runtime } from '@aws-appsync/utils';
|
|
1019
1018
|
export function request(ctx) {
|
|
1020
1019
|
const ids = ctx.args.ids ?? [];
|
|
@@ -1039,22 +1038,21 @@ export function response(ctx) {
|
|
|
1039
1038
|
// caller does not own is dropped rather than refused, for the reason the
|
|
1040
1039
|
// single-key door answers null: distinguishing "not yours" from "not there"
|
|
1041
1040
|
// would make this door an oracle for which ids exist.` + (
|
|
1042
|
-
|
|
1043
|
-
|
|
1041
|
+
ownerField !== undefined ? ownerGuardPreamble(ownerField, elevatedGroups) : ""
|
|
1042
|
+
) + retiredGuardPreamble(retiredField, retiredValues, elevatedGroups, Stdlib_Option.isSome(ownerField)) + `
|
|
1044
1043
|
return (ctx.result?.data?.['` + tableName + `'] ?? []).filter(item =>
|
|
1045
1044
|
item !== null` + (
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1045
|
+
Stdlib_Option.isSome(ownerField) ? " && _owns(item)" : ""
|
|
1046
|
+
) + (
|
|
1047
|
+
Stdlib_Option.isSome(retiredField) ? " && _live(item)" : ""
|
|
1048
|
+
) + `);
|
|
1050
1049
|
}
|
|
1051
1050
|
`;
|
|
1052
|
-
};
|
|
1053
1051
|
}
|
|
1054
1052
|
|
|
1055
|
-
function refsByIds(labelField, retiredField, retiredValues, namedWhenRetired, imageExpr, ownerField,
|
|
1053
|
+
function refsByIds(labelField, retiredField, retiredValues, namedWhenRetired, imageExpr, ownerField, elevatedGroupsOpt) {
|
|
1054
|
+
let elevatedGroups = elevatedGroupsOpt !== undefined ? elevatedGroupsOpt : [];
|
|
1056
1055
|
return tableName => {
|
|
1057
|
-
let elevatedGroups = $staropt$star !== undefined ? $staropt$star : [];
|
|
1058
1056
|
let ownerGuard = ownerField !== undefined ? ownerGuardPreamble(ownerField, elevatedGroups) : "\n const _owns = (row) => true;";
|
|
1059
1057
|
let retiredExpr;
|
|
1060
1058
|
if (retiredField !== undefined) {
|
|
@@ -124,12 +124,12 @@ type t = policy
|
|
|
124
124
|
|
|
125
125
|
let toJsonString: t => string = t => {
|
|
126
126
|
t
|
|
127
|
-
->S.
|
|
127
|
+
->S.convertOrThrow(~from=policySchema, ~to=S.json)
|
|
128
128
|
->JSON.stringify(~space=1)
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
let fromJsonString: string => t = (policyString: string) =>
|
|
132
|
-
policyString->S.
|
|
132
|
+
S.JsonString(policyString)->S.convertOrThrow(~from=S.jsonString, ~to=policySchema)
|
|
133
133
|
|
|
134
134
|
let make = (~version=Version2012, ~id=?, ~statements) => {
|
|
135
135
|
version,
|
|
@@ -48,7 +48,7 @@ let conditionEntrySchema = Sury.union([
|
|
|
48
48
|
Sury.$schema(s => (s.m(Sury.array(Sury.string))))
|
|
49
49
|
]);
|
|
50
50
|
|
|
51
|
-
let conditionMapSchema = Sury.
|
|
51
|
+
let conditionMapSchema = Sury.record(conditionEntrySchema);
|
|
52
52
|
|
|
53
53
|
let conditionSchema = Sury.$schema(s => ({
|
|
54
54
|
StringEquals: s.m(Sury.$option(conditionMapSchema)),
|
|
@@ -121,11 +121,11 @@ let policySchema = Sury.$schema(s => ({
|
|
|
121
121
|
}));
|
|
122
122
|
|
|
123
123
|
function toJsonString(t) {
|
|
124
|
-
return JSON.stringify(S.
|
|
124
|
+
return JSON.stringify(S.convertOrThrow(t, policySchema, undefined, Sury.json), undefined, 1);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
function fromJsonString(policyString) {
|
|
128
|
-
return S.
|
|
128
|
+
return S.convertOrThrow(policyString, Sury.jsonString, undefined, policySchema);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
function make(versionOpt, id, statements) {
|
package/src/Lambda/Lambda.res
CHANGED
|
@@ -46,53 +46,136 @@ type eventHandlerNoResult<'event> = eventHandler<'event, unit>
|
|
|
46
46
|
@send
|
|
47
47
|
external getRemainingTimeInMillis: context => int = "getRemainingTimeInMillis"
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
} else {
|
|
73
|
-
Some(trimmed)
|
|
74
|
-
}
|
|
75
|
-
} catch {
|
|
76
|
-
| _ => None
|
|
49
|
+
/** The outcome of looking for the Reventless layer. `region` is `None` when
|
|
50
|
+
neither the stack nor the environment names one, and the AWS CLI's default
|
|
51
|
+
region was asked. */
|
|
52
|
+
type layerLookup =
|
|
53
|
+
| Found(string)
|
|
54
|
+
| NotFound({parameter: string, region: option<string>})
|
|
55
|
+
| CouldNotLook({parameter: string, region: option<string>, reason: string})
|
|
56
|
+
|
|
57
|
+
let layerParameter = stack => `/reventless/layer-arn/${stack}`
|
|
58
|
+
|
|
59
|
+
let _nonEmpty = value =>
|
|
60
|
+
switch value->Option.map(String.trim) {
|
|
61
|
+
| Some("") | None => None
|
|
62
|
+
| trimmed => trimmed
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let _lookupRegion = () =>
|
|
66
|
+
switch Pulumi.Config.make(Some("aws"))->Pulumi.Config.get("region")->_nonEmpty {
|
|
67
|
+
| Some(_) as region => region
|
|
68
|
+
| None =>
|
|
69
|
+
switch NodeProcess.env->Dict.get("AWS_REGION")->_nonEmpty {
|
|
70
|
+
| Some(_) as region => region
|
|
71
|
+
| None => NodeProcess.env->Dict.get("AWS_DEFAULT_REGION")->_nonEmpty
|
|
77
72
|
}
|
|
78
73
|
}
|
|
79
74
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
75
|
+
let _firstLine = text =>
|
|
76
|
+
text
|
|
77
|
+
->String.split("\n")
|
|
78
|
+
->Array.map(String.trim)
|
|
79
|
+
->Array.find(line => line !== "")
|
|
80
|
+
->Option.getOr("the AWS CLI exited without saying why")
|
|
81
|
+
|
|
82
|
+
/** Reads the result of `aws ssm get-parameter`: only `ParameterNotFound` means
|
|
83
|
+
there is no layer; a missing CLI or a refused call means nobody could tell. */
|
|
84
|
+
let classifySsmLookup = (
|
|
85
|
+
~parameter,
|
|
86
|
+
~region,
|
|
87
|
+
result: NodeChildProcess.spawnSyncResult,
|
|
88
|
+
): layerLookup => {
|
|
89
|
+
let stderr = result.stderr->Nullable.toOption->Option.getOr("")
|
|
90
|
+
switch (result.error->Nullable.toOption, result.status->Nullable.toOption) {
|
|
91
|
+
| (Some(error), _) =>
|
|
92
|
+
let message = error->JsExn.message->Option.getOr("unknown error")
|
|
93
|
+
CouldNotLook({parameter, region, reason: `the AWS CLI could not be run (${message})`})
|
|
94
|
+
| (None, Some(0)) =>
|
|
95
|
+
switch result.stdout->Nullable.toOption->_nonEmpty {
|
|
96
|
+
| None | Some("None") => NotFound({parameter, region})
|
|
97
|
+
| Some(arn) => Found(arn)
|
|
98
|
+
}
|
|
99
|
+
| (None, _) if stderr->String.includes("ParameterNotFound") => NotFound({parameter, region})
|
|
100
|
+
| (None, _) => CouldNotLook({parameter, region, reason: _firstLine(stderr)})
|
|
101
|
+
}
|
|
94
102
|
}
|
|
95
103
|
|
|
104
|
+
let _lookupInSsm = (): layerLookup => {
|
|
105
|
+
let parameter = layerParameter(Pulumi.Pulumi.getStackName())
|
|
106
|
+
let region = _lookupRegion()
|
|
107
|
+
let regionArgs = region->Option.mapOr([], region => ["--region", region])
|
|
108
|
+
NodeChildProcess.spawnSync(
|
|
109
|
+
"aws",
|
|
110
|
+
[
|
|
111
|
+
"ssm",
|
|
112
|
+
"get-parameter",
|
|
113
|
+
"--name",
|
|
114
|
+
parameter,
|
|
115
|
+
"--query",
|
|
116
|
+
"Parameter.Value",
|
|
117
|
+
"--output",
|
|
118
|
+
"text",
|
|
119
|
+
]->Array.concat(regionArgs),
|
|
120
|
+
{encoding: "utf8"},
|
|
121
|
+
)->classifySsmLookup(~parameter, ~region, _)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let _lookup: ref<option<layerLookup>> = ref(None)
|
|
125
|
+
|
|
126
|
+
/** Looks once per deploy: `REVENTLESS_LAYER_ARN` when set (CI exports it),
|
|
127
|
+
otherwise the stack's SSM parameter through the AWS CLI, in the stack's
|
|
128
|
+
`aws:region` when it sets one. */
|
|
129
|
+
let lookupLayer = (): layerLookup =>
|
|
130
|
+
switch _lookup.contents {
|
|
131
|
+
| Some(lookup) => lookup
|
|
132
|
+
| None =>
|
|
133
|
+
let lookup = switch NodeProcess.env->Dict.get("REVENTLESS_LAYER_ARN")->_nonEmpty {
|
|
134
|
+
| Some(arn) => Found(arn)
|
|
135
|
+
| None => _lookupInSsm()
|
|
136
|
+
}
|
|
137
|
+
_lookup := Some(lookup)
|
|
138
|
+
lookup
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let _regionName = region =>
|
|
142
|
+
region->Option.mapOr("the AWS CLI's default region", region => `region ${region}`)
|
|
143
|
+
|
|
144
|
+
let _publishHint = `Publish the layer and store its ARN in that parameter, or set REVENTLESS_LAYER_ARN: https://docs.reventless.dev/infrastructure/aws/get-started#the-lambda-layer`
|
|
145
|
+
|
|
146
|
+
/** Why a deploy cannot go on without the layer, or `None` when it was found. */
|
|
147
|
+
let missingLayerMessage = lookup =>
|
|
148
|
+
switch lookup {
|
|
149
|
+
| Found(_) => None
|
|
150
|
+
| NotFound({parameter, region}) =>
|
|
151
|
+
Some(
|
|
152
|
+
`No Reventless Lambda layer: the SSM parameter ${parameter} does not exist in ${_regionName(
|
|
153
|
+
region,
|
|
154
|
+
)}. Without the layer every function fails with "Cannot find package" on its first run. ${_publishHint}`,
|
|
155
|
+
)
|
|
156
|
+
| CouldNotLook({parameter, region, reason}) =>
|
|
157
|
+
Some(
|
|
158
|
+
`Could not look up the Reventless Lambda layer in the SSM parameter ${parameter} (${_regionName(
|
|
159
|
+
region,
|
|
160
|
+
)}): ${reason}. ${_publishHint}`,
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** The layer's ARN. Throws with `missingLayerMessage` when there is none, so a
|
|
165
|
+
function is never created without the framework code it imports. */
|
|
166
|
+
let reventlessLayerArn = (): string =>
|
|
167
|
+
switch lookupLayer() {
|
|
168
|
+
| Found(arn) => arn
|
|
169
|
+
| lookup =>
|
|
170
|
+
JsError.throwWithMessage(
|
|
171
|
+
missingLayerMessage(lookup)->Option.getOr("No Reventless Lambda layer"),
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** The `layers` argument of every framework function. */
|
|
176
|
+
let reventlessLayers = (): Pulumi.Input.t<array<Pulumi.Input.t<string>>> =>
|
|
177
|
+
[reventlessLayerArn()->Pulumi.Input.make]->Pulumi.Input.make
|
|
178
|
+
|
|
96
179
|
@val
|
|
97
180
|
external environment: option<string> = "process.env.Environment"
|
|
98
181
|
|
|
@@ -150,10 +233,7 @@ module CallbackFunction = {
|
|
|
150
233
|
~memorySize=1024->Pulumi.Input.make,
|
|
151
234
|
~timeout=180->Pulumi.Input.make,
|
|
152
235
|
~runtime=NodeJs22,
|
|
153
|
-
~layers=
|
|
154
|
-
->Option.map(arn => [arn->Pulumi.Input.make])
|
|
155
|
-
->Option.getOr([])
|
|
156
|
-
->Pulumi.Input.make,
|
|
236
|
+
~layers=reventlessLayers(),
|
|
157
237
|
~vpcConfig=?,
|
|
158
238
|
~tags=?,
|
|
159
239
|
~environment={
|
|
@@ -1,43 +1,161 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
3
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
|
-
import * as Child_process from "child_process";
|
|
5
5
|
import * as Pulumi from "@pulumi/pulumi";
|
|
6
|
+
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
7
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
8
|
+
import * as Nodechild_process from "node:child_process";
|
|
6
9
|
import * as PolicyDocument$PulumiAws from "../IAM/PolicyDocument.res.mjs";
|
|
7
10
|
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
function layerParameter(stack) {
|
|
12
|
+
return `/reventless/layer-arn/` + stack;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function _nonEmpty(value) {
|
|
16
|
+
let trimmed = Stdlib_Option.map(value, prim => prim.trim());
|
|
17
|
+
if (trimmed !== undefined && trimmed !== "") {
|
|
18
|
+
return trimmed;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function _lookupRegion() {
|
|
23
|
+
let region = _nonEmpty(new Pulumi.Config("aws").get("region"));
|
|
24
|
+
if (region !== undefined) {
|
|
25
|
+
return region;
|
|
12
26
|
}
|
|
13
|
-
|
|
14
|
-
|
|
27
|
+
let region$1 = _nonEmpty(process.env["AWS_REGION"]);
|
|
28
|
+
if (region$1 !== undefined) {
|
|
29
|
+
return region$1;
|
|
30
|
+
} else {
|
|
31
|
+
return _nonEmpty(process.env["AWS_DEFAULT_REGION"]);
|
|
15
32
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function _firstLine(text) {
|
|
36
|
+
return Stdlib_Option.getOr(text.split("\n").map(prim => prim.trim()).find(line => line !== ""), "the AWS CLI exited without saying why");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function classifySsmLookup(parameter, region, result) {
|
|
40
|
+
let stderr = Stdlib_Option.getOr(Primitive_option.fromNullable(result.stderr), "");
|
|
41
|
+
let match = result.error;
|
|
42
|
+
let match$1 = result.status;
|
|
43
|
+
if (match == null) {
|
|
44
|
+
if (!(match$1 == null) && match$1 === 0) {
|
|
45
|
+
let arn = _nonEmpty(Primitive_option.fromNullable(result.stdout));
|
|
46
|
+
if (arn !== undefined && arn !== "None") {
|
|
47
|
+
return {
|
|
48
|
+
TAG: "Found",
|
|
49
|
+
_0: arn
|
|
50
|
+
};
|
|
51
|
+
} else {
|
|
52
|
+
return {
|
|
53
|
+
TAG: "NotFound",
|
|
54
|
+
parameter: parameter,
|
|
55
|
+
region: region
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (stderr.includes("ParameterNotFound")) {
|
|
60
|
+
return {
|
|
61
|
+
TAG: "NotFound",
|
|
62
|
+
parameter: parameter,
|
|
63
|
+
region: region
|
|
64
|
+
};
|
|
24
65
|
} else {
|
|
25
|
-
return
|
|
66
|
+
return {
|
|
67
|
+
TAG: "CouldNotLook",
|
|
68
|
+
parameter: parameter,
|
|
69
|
+
region: region,
|
|
70
|
+
reason: _firstLine(stderr)
|
|
71
|
+
};
|
|
26
72
|
}
|
|
27
|
-
} catch (exn) {
|
|
28
|
-
return;
|
|
29
73
|
}
|
|
74
|
+
let message = Stdlib_Option.getOr(Stdlib_JsExn.message(match), "unknown error");
|
|
75
|
+
return {
|
|
76
|
+
TAG: "CouldNotLook",
|
|
77
|
+
parameter: parameter,
|
|
78
|
+
region: region,
|
|
79
|
+
reason: `the AWS CLI could not be run (` + message + `)`
|
|
80
|
+
};
|
|
30
81
|
}
|
|
31
82
|
|
|
32
|
-
|
|
83
|
+
function _lookupInSsm() {
|
|
84
|
+
let parameter = layerParameter(Pulumi.getStack());
|
|
85
|
+
let region = _lookupRegion();
|
|
86
|
+
let regionArgs = Stdlib_Option.mapOr(region, [], region => [
|
|
87
|
+
"--region",
|
|
88
|
+
region
|
|
89
|
+
]);
|
|
90
|
+
return classifySsmLookup(parameter, region, Nodechild_process.spawnSync("aws", [
|
|
91
|
+
"ssm",
|
|
92
|
+
"get-parameter",
|
|
93
|
+
"--name",
|
|
94
|
+
parameter,
|
|
95
|
+
"--query",
|
|
96
|
+
"Parameter.Value",
|
|
97
|
+
"--output",
|
|
98
|
+
"text"
|
|
99
|
+
].concat(regionArgs), {
|
|
100
|
+
encoding: "utf8"
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
33
103
|
|
|
34
|
-
let
|
|
104
|
+
let _lookup = {
|
|
105
|
+
contents: undefined
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
function lookupLayer() {
|
|
109
|
+
let lookup = _lookup.contents;
|
|
110
|
+
if (lookup !== undefined) {
|
|
111
|
+
return lookup;
|
|
112
|
+
}
|
|
113
|
+
let arn = _nonEmpty(process.env["REVENTLESS_LAYER_ARN"]);
|
|
114
|
+
let lookup$1 = arn !== undefined ? ({
|
|
115
|
+
TAG: "Found",
|
|
116
|
+
_0: arn
|
|
117
|
+
}) : _lookupInSsm();
|
|
118
|
+
_lookup.contents = lookup$1;
|
|
119
|
+
return lookup$1;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function _regionName(region) {
|
|
123
|
+
return Stdlib_Option.mapOr(region, "the AWS CLI's default region", region => `region ` + region);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let _publishHint = `Publish the layer and store its ARN in that parameter, or set REVENTLESS_LAYER_ARN: https://docs.reventless.dev/infrastructure/aws/get-started#the-lambda-layer`;
|
|
127
|
+
|
|
128
|
+
function missingLayerMessage(lookup) {
|
|
129
|
+
switch (lookup.TAG) {
|
|
130
|
+
case "Found" :
|
|
131
|
+
return;
|
|
132
|
+
case "NotFound" :
|
|
133
|
+
return `No Reventless Lambda layer: the SSM parameter ` + lookup.parameter + ` does not exist in ` + _regionName(lookup.region) + `. Without the layer every function fails with "Cannot find package" on its first run. ` + _publishHint;
|
|
134
|
+
case "CouldNotLook" :
|
|
135
|
+
return `Could not look up the Reventless Lambda layer in the SSM parameter ` + lookup.parameter + ` (` + _regionName(lookup.region) + `): ` + lookup.reason + `. ` + _publishHint;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function reventlessLayerArn() {
|
|
140
|
+
let arn = lookupLayer();
|
|
141
|
+
switch (arn.TAG) {
|
|
142
|
+
case "Found" :
|
|
143
|
+
return arn._0;
|
|
144
|
+
case "NotFound" :
|
|
145
|
+
case "CouldNotLook" :
|
|
146
|
+
return Stdlib_JsError.throwWithMessage(Stdlib_Option.getOr(missingLayerMessage(arn), "No Reventless Lambda layer"));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function reventlessLayers() {
|
|
151
|
+
return [reventlessLayerArn()];
|
|
152
|
+
}
|
|
35
153
|
|
|
36
154
|
function make(callback, role, policies, deadLetterConfig, tracingConfig, memorySizeOpt, timeoutOpt, runtimeOpt, layersOpt, vpcConfig, tags, environmentOpt) {
|
|
37
155
|
let memorySize = memorySizeOpt !== undefined ? memorySizeOpt : 1024;
|
|
38
156
|
let timeout = timeoutOpt !== undefined ? timeoutOpt : 180;
|
|
39
157
|
let runtime = runtimeOpt !== undefined ? runtimeOpt : "nodejs22.x";
|
|
40
|
-
let layers = layersOpt !== undefined ? layersOpt :
|
|
158
|
+
let layers = layersOpt !== undefined ? layersOpt : [reventlessLayerArn()];
|
|
41
159
|
let environment = environmentOpt !== undefined ? environmentOpt : ({
|
|
42
160
|
variables: Object.fromEntries([[
|
|
43
161
|
"Environment",
|
|
@@ -86,12 +204,23 @@ let defaultLoggingPolicyDocument = PolicyDocument$PulumiAws.make(undefined, unde
|
|
|
86
204
|
}]);
|
|
87
205
|
|
|
88
206
|
export {
|
|
89
|
-
|
|
207
|
+
layerParameter,
|
|
208
|
+
_nonEmpty,
|
|
209
|
+
_lookupRegion,
|
|
210
|
+
_firstLine,
|
|
211
|
+
classifySsmLookup,
|
|
212
|
+
_lookupInSsm,
|
|
213
|
+
_lookup,
|
|
214
|
+
lookupLayer,
|
|
215
|
+
_regionName,
|
|
216
|
+
_publishHint,
|
|
217
|
+
missingLayerMessage,
|
|
90
218
|
reventlessLayerArn,
|
|
219
|
+
reventlessLayers,
|
|
91
220
|
CallbackFunction,
|
|
92
221
|
$$Function,
|
|
93
222
|
Permission,
|
|
94
223
|
Invocation,
|
|
95
224
|
defaultLoggingPolicyDocument,
|
|
96
225
|
}
|
|
97
|
-
/*
|
|
226
|
+
/* defaultLoggingPolicyDocument Not a pure module */
|