@reventlessdev/reventless-aws 3.0.0-alpha.254 → 3.0.0-alpha.255

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 CHANGED
@@ -3,6 +3,13 @@
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.255 (2026-08-02)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **aws:** apply tier LOG_LEVEL + managed log groups to bespoke Lambda builders ([8814627](https://github.com/ReventlessDev/reventless-core/commit/8814627a200199616f407f4011d4e0b0e1895397))
11
+
12
+
6
13
  # 3.0.0-alpha.254 (2026-08-02)
7
14
 
8
15
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-aws",
3
- "version": "3.0.0-alpha.254",
3
+ "version": "3.0.0-alpha.255",
4
4
  "description": "AWS adapters for Reventless",
5
5
  "license": "Apache-2.0",
6
6
  "dependencies": {
@@ -12,12 +12,12 @@
12
12
  "sury": "11.0.0-alpha.4",
13
13
  "uuid": "^13.0.0",
14
14
  "@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.1",
15
- "@reventlessdev/rescript-jest": "1.0.0-alpha.10",
16
15
  "@reventlessdev/rescript-effect": "0.1.0-alpha.32",
16
+ "@reventlessdev/rescript-jest": "1.0.0-alpha.10",
17
17
  "@reventlessdev/rescript-node": "2.0.0-alpha.0",
18
18
  "@reventlessdev/rescript-pulumi-aws": "2.4.0-alpha.63",
19
- "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.18",
20
19
  "@reventlessdev/rescript-uuid": "2.0.0-alpha.0",
20
+ "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.18",
21
21
  "@reventlessdev/reventless-core": "3.0.0-alpha.201",
22
22
  "@reventlessdev/reventless-infra": "3.0.0-alpha.118",
23
23
  "@reventlessdev/reventless-postgres": "3.0.0-alpha.65",
@@ -120,6 +120,7 @@ let make = (
120
120
  ("ADMIN_ENTRY_JSON", adminEntryJson->Pulumi.Input.make),
121
121
  ("NODE_OPTIONS", Util_Bundle.esmLoaderNodeOptions->Pulumi.Input.make),
122
122
  ("ESM_FALLBACK_DIRS", Util_Bundle.esmFallbackDirs->Pulumi.Input.make),
123
+ Util_LambdaLogging.logLevelEntry(),
123
124
  ]),
124
125
  }: Lambda.Function.functionEnvironment
125
126
  )->Pulumi.Input.make,
@@ -127,6 +128,19 @@ let make = (
127
128
  ~opts,
128
129
  )
129
130
 
131
+ Util_LambdaLogging.makeManagedLogGroup(
132
+ ~name=name ++ "Lambda",
133
+ ~lambdaName=lambda.name,
134
+ ~tags=AWS.Tags.make(
135
+ ~name=name ++ "LambdaLogGroup",
136
+ ~kind=ReventlessCore.ComponentType.Platform,
137
+ ~role=Logs,
138
+ ~scope=Platform,
139
+ ),
140
+ ~opts,
141
+ (),
142
+ )
143
+
130
144
  let dataSourceRole = IAM.Role.makeWithDefaultPolicy(
131
145
  ~name=name ++ "DataSource",
132
146
  ~servicePrincipal=AWS.AppSync.principal->Pulumi.Output.make,
@@ -11,6 +11,7 @@ import * as AWS_Tags$ReventlessAws from "../AWS_Tags.res.mjs";
11
11
  import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/src/IAM/PolicyDocument.res.mjs";
12
12
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
13
13
  import * as Util_Pulumi$ReventlessCore from "@reventlessdev/reventless-core/src/util/Util_Pulumi.res.mjs";
14
+ import * as Util_LambdaLogging$ReventlessAws from "../../util/Util_LambdaLogging.res.mjs";
14
15
  import * as AppSync_Resolver_Native$ReventlessAws from "./AppSync_Resolver_Native.res.mjs";
15
16
  import * as Platform_Admin_Structure$ReventlessCore from "@reventlessdev/reventless-core/src/admin/Platform_Admin_Structure.res.mjs";
16
17
  import * as Platform_ComponentDefinitionsApi$ReventlessCore from "@reventlessdev/reventless-core/src/admin/Platform_ComponentDefinitionsApi.res.mjs";
@@ -86,11 +87,13 @@ function make(api, pluginReadModelTableName, opts) {
86
87
  [
87
88
  "ESM_FALLBACK_DIRS",
88
89
  Util_Bundle$ReventlessAws.esmFallbackDirs
89
- ]
90
+ ],
91
+ Util_LambdaLogging$ReventlessAws.logLevelEntry()
90
92
  ])
91
93
  },
92
94
  sourceCodeHash: match.sourceCodeHash
93
95
  }, opts$1);
96
+ Util_LambdaLogging$ReventlessAws.makeManagedLogGroup(name + "Lambda", lambda.name, AWS_Tags$ReventlessAws.make(name + "LambdaLogGroup", "Platform", "Logs", "Platform", undefined, undefined, undefined, undefined), opts$1, undefined);
94
97
  let dataSourceRole = IAM$PulumiAws.Role.makeWithDefaultPolicy(name + "DataSource", Pulumi.output(AWS$ReventlessAws.AppSync.principal), AWS_Tags$ReventlessAws.make(name + "DataSource", "Platform", "Identity", "Platform", undefined, undefined, undefined, undefined), opts$1);
95
98
  Pulumi.all([
96
99
  lambda.arn,
@@ -111,6 +111,7 @@ let make = (
111
111
  ("UI_FRAGMENT_RM_TABLE", uiFragmentRegistryTableName->Pulumi.Output.asInput),
112
112
  ("NODE_OPTIONS", Util_Bundle.esmLoaderNodeOptions->Pulumi.Input.make),
113
113
  ("ESM_FALLBACK_DIRS", Util_Bundle.esmFallbackDirs->Pulumi.Input.make),
114
+ Util_LambdaLogging.logLevelEntry(),
114
115
  ]),
115
116
  }: Lambda.Function.functionEnvironment
116
117
  )->Pulumi.Input.make,
@@ -118,6 +119,19 @@ let make = (
118
119
  ~opts,
119
120
  )
120
121
 
122
+ Util_LambdaLogging.makeManagedLogGroup(
123
+ ~name=name ++ "Lambda",
124
+ ~lambdaName=lambda.name,
125
+ ~tags=AWS.Tags.make(
126
+ ~name=name ++ "LambdaLogGroup",
127
+ ~kind=ReventlessCore.ComponentType.Platform,
128
+ ~role=Logs,
129
+ ~scope=Platform,
130
+ ),
131
+ ~opts,
132
+ (),
133
+ )
134
+
121
135
  let dataSourceRole = IAM.Role.makeWithDefaultPolicy(
122
136
  ~name=name ++ "DataSource",
123
137
  ~servicePrincipal=AWS.AppSync.principal->Pulumi.Output.make,
@@ -11,6 +11,7 @@ import * as AWS_Tags$ReventlessAws from "../AWS_Tags.res.mjs";
11
11
  import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/src/IAM/PolicyDocument.res.mjs";
12
12
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
13
13
  import * as Util_Pulumi$ReventlessCore from "@reventlessdev/reventless-core/src/util/Util_Pulumi.res.mjs";
14
+ import * as Util_LambdaLogging$ReventlessAws from "../../util/Util_LambdaLogging.res.mjs";
14
15
  import * as AppSync_Resolver_Native$ReventlessAws from "./AppSync_Resolver_Native.res.mjs";
15
16
 
16
17
  let resolverCode = `
@@ -79,11 +80,13 @@ function make(api, uiFragmentRegistryTableName, schemaReady, opts) {
79
80
  [
80
81
  "ESM_FALLBACK_DIRS",
81
82
  Util_Bundle$ReventlessAws.esmFallbackDirs
82
- ]
83
+ ],
84
+ Util_LambdaLogging$ReventlessAws.logLevelEntry()
83
85
  ])
84
86
  },
85
87
  sourceCodeHash: match.sourceCodeHash
86
88
  }, opts$1);
89
+ Util_LambdaLogging$ReventlessAws.makeManagedLogGroup(name + "Lambda", lambda.name, AWS_Tags$ReventlessAws.make(name + "LambdaLogGroup", "Platform", "Logs", "Platform", undefined, undefined, undefined, undefined), opts$1, undefined);
87
90
  let dataSourceRole = IAM$PulumiAws.Role.makeWithDefaultPolicy(name + "DataSource", Pulumi.output(AWS$ReventlessAws.AppSync.principal), AWS_Tags$ReventlessAws.make(name + "DataSource", "Platform", "Identity", "Platform", undefined, undefined, undefined, undefined), opts$1);
88
91
  Pulumi.all([
89
92
  lambda.arn,
@@ -122,6 +122,7 @@ let make = (
122
122
  ("PLACE_INDEX_NAME", placeIndexName),
123
123
  ("NODE_OPTIONS", Util_Bundle.esmLoaderNodeOptions->Pulumi.Input.make),
124
124
  ("ESM_FALLBACK_DIRS", Util_Bundle.esmFallbackDirs->Pulumi.Input.make),
125
+ Util_LambdaLogging.logLevelEntry(),
125
126
  ]),
126
127
  }: Lambda.Function.functionEnvironment
127
128
  )->Pulumi.Input.make,
@@ -129,6 +130,19 @@ let make = (
129
130
  ~opts?,
130
131
  )
131
132
 
133
+ Util_LambdaLogging.makeManagedLogGroup(
134
+ ~name=serviceName,
135
+ ~lambdaName=lambda.name,
136
+ ~tags=AWS.Tags.make(
137
+ ~name=serviceName ++ "LogGroup",
138
+ ~kind=ReventlessCore.ComponentType.Platform,
139
+ ~role=Logs,
140
+ ~scope=Platform,
141
+ ),
142
+ ~opts?,
143
+ (),
144
+ )
145
+
132
146
  let functionUrl = FunctionUrl.make(
133
147
  ~name=`${serviceName}Url`,
134
148
  ~args={
@@ -11,6 +11,7 @@ import * as AWS_Tags$ReventlessAws from "../AWS_Tags.res.mjs";
11
11
  import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/src/IAM/PolicyDocument.res.mjs";
12
12
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
13
13
  import * as Util_Pulumi$ReventlessCore from "@reventlessdev/reventless-core/src/util/Util_Pulumi.res.mjs";
14
+ import * as Util_LambdaLogging$ReventlessAws from "../../util/Util_LambdaLogging.res.mjs";
14
15
 
15
16
  function make(placeIndexName, corsOriginsOpt, opts) {
16
17
  let corsOrigins = corsOriginsOpt !== undefined ? corsOriginsOpt : ["*"];
@@ -73,11 +74,13 @@ function make(placeIndexName, corsOriginsOpt, opts) {
73
74
  [
74
75
  "ESM_FALLBACK_DIRS",
75
76
  Util_Bundle$ReventlessAws.esmFallbackDirs
76
- ]
77
+ ],
78
+ Util_LambdaLogging$ReventlessAws.logLevelEntry()
77
79
  ])
78
80
  },
79
81
  sourceCodeHash: match.sourceCodeHash
80
82
  }, opts$1 !== undefined ? Primitive_option.valFromOption(opts$1) : undefined);
83
+ Util_LambdaLogging$ReventlessAws.makeManagedLogGroup(serviceName, lambda.name, AWS_Tags$ReventlessAws.make(serviceName + "LogGroup", "Platform", "Logs", "Platform", undefined, undefined, undefined, undefined), opts$1, undefined);
81
84
  let functionUrl = new (Aws.lambda.FunctionUrl)(serviceName + `Url`, {
82
85
  authorizationType: "NONE",
83
86
  functionName: lambda.name,
@@ -243,18 +243,9 @@ let makeFromCodeAsset: (
243
243
 
244
244
  // Default the logger's minimum level per environment tier when nothing already
245
245
  // pinned one (caller `envVars` or a consumer-registered `additionalEnvVars`
246
- // win). Verbose on disposable dev stacks, quiet on prod/beta for every
247
- // Lambda, not just the command handlers.
248
- if variables->Dict.get("LOG_LEVEL")->Option.isNone {
249
- variables->Dict.set(
250
- "LOG_LEVEL",
251
- Util_LogRetention.logLevelFor(
252
- ~stack,
253
- ~prodStacks,
254
- ~configOverride=?Util_LocalConfig.get("logLevel"),
255
- )->Pulumi.Input.make,
256
- )
257
- }
246
+ // win) for every Lambda, via the shared helper so the bespoke
247
+ // `Lambda.Function.make` builders apply the identical policy.
248
+ Util_LambdaLogging.applyLogLevelDefault(variables)
258
249
 
259
250
  // ESM self-containment (Option C): every code archive built by
260
251
  // Util_Bundle.buildCodeArchive ships register-hook.mjs + layer-resolver.mjs at
@@ -23,6 +23,7 @@ import * as Util_IAM_Role$ReventlessAws from "../../util/Util_IAM_Role.res.mjs";
23
23
  import * as Util_LocalConfig$ReventlessAws from "../../util/Util_LocalConfig.res.mjs";
24
24
  import * as Util_HostUiDomain$ReventlessAws from "../../util/Util_HostUiDomain.res.mjs";
25
25
  import * as Util_LogRetention$ReventlessAws from "../../util/Util_LogRetention.res.mjs";
26
+ import * as Util_LambdaLogging$ReventlessAws from "../../util/Util_LambdaLogging.res.mjs";
26
27
 
27
28
  let additionalEnvVars = {};
28
29
 
@@ -101,9 +102,7 @@ function makeFromCodeAsset(name, unitKind, componentKind, code, sourceCodeHash,
101
102
  Stdlib_Dict.forEachWithKey(additionalEnvVars, (value, key) => {
102
103
  variables[key] = value;
103
104
  });
104
- if (Stdlib_Option.isNone(variables["LOG_LEVEL"])) {
105
- variables["LOG_LEVEL"] = Util_LogRetention$ReventlessAws.logLevelFor(stack, prodStacks, Util_LocalConfig$ReventlessAws.get("logLevel"));
106
- }
105
+ Util_LambdaLogging$ReventlessAws.applyLogLevelDefault(variables);
107
106
  variables["NODE_OPTIONS"] = Util_Bundle$ReventlessAws.esmLoaderNodeOptions;
108
107
  variables["ESM_FALLBACK_DIRS"] = Util_Bundle$ReventlessAws.esmFallbackDirs;
109
108
  let tags = tagsFor(name, "Runtime");
@@ -237,6 +237,7 @@ let finish = (
237
237
  ("STATE_TOPIC_MAP", topicMapJson->Pulumi.Output.asInput),
238
238
  ("NODE_OPTIONS", Util_Bundle.esmLoaderNodeOptions->Pulumi.Input.make),
239
239
  ("ESM_FALLBACK_DIRS", Util_Bundle.esmFallbackDirs->Pulumi.Input.make),
240
+ Util_LambdaLogging.logLevelEntry(),
240
241
  ]),
241
242
  }: Lambda.Function.functionEnvironment
242
243
  )->Pulumi.Input.make,
@@ -244,6 +245,19 @@ let finish = (
244
245
  ~opts,
245
246
  )
246
247
 
248
+ Util_LambdaLogging.makeManagedLogGroup(
249
+ ~name=name ++ "StateTopicPublisher",
250
+ ~lambdaName=lambda.name,
251
+ ~tags=AWS.Tags.make(
252
+ ~name=name ++ "StateTopicPublisherLogGroup",
253
+ ~kind=ReventlessCore.QueryDb.componentType,
254
+ ~role=Logs,
255
+ ~component=name,
256
+ ),
257
+ ~opts,
258
+ (),
259
+ )
260
+
247
261
  // One EventSourceMapping per stream, all targeting the shared Lambda.
248
262
  // Retry posture: the handler throws on 5xx / network errors and logs-and-
249
263
  // continues on 4xx. `maximumRetryAttempts: 3` bounds the per-record
@@ -12,6 +12,7 @@ import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/sr
12
12
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
13
13
  import * as Util_ReadModel$ReventlessCore from "@reventlessdev/reventless-core/src/util/Util_ReadModel.res.mjs";
14
14
  import * as AppSync_EventsApi$ReventlessAws from "../Api/AppSync_EventsApi.res.mjs";
15
+ import * as Util_LambdaLogging$ReventlessAws from "../../util/Util_LambdaLogging.res.mjs";
15
16
  import * as Util_DynamoDbStream$ReventlessAws from "../../util/Util_DynamoDbStream.res.mjs";
16
17
 
17
18
  let registry = {};
@@ -119,11 +120,13 @@ function finish(eventsApi, opts) {
119
120
  [
120
121
  "ESM_FALLBACK_DIRS",
121
122
  Util_Bundle$ReventlessAws.esmFallbackDirs
122
- ]
123
+ ],
124
+ Util_LambdaLogging$ReventlessAws.logLevelEntry()
123
125
  ])
124
126
  },
125
127
  sourceCodeHash: match.sourceCodeHash
126
128
  }, opts);
129
+ Util_LambdaLogging$ReventlessAws.makeManagedLogGroup(name + "StateTopicPublisher", lambda.name, AWS_Tags$ReventlessAws.make(name + "StateTopicPublisherLogGroup", QueryDb$ReventlessCore.componentType, "Logs", undefined, name, undefined, undefined, undefined), opts, undefined);
127
130
  entries.forEach(entry => {
128
131
  let esmName = entry.topicName + "Stream2" + name + "StateTopic";
129
132
  new (Aws.lambda.EventSourceMapping)(esmName, {
@@ -290,6 +290,7 @@ let finish = (
290
290
  ("CLAIM_REF_FIELDS", refFieldsJson->Pulumi.Output.asInput),
291
291
  ("NODE_OPTIONS", Util_Bundle.esmLoaderNodeOptions->Pulumi.Input.make),
292
292
  ("ESM_FALLBACK_DIRS", Util_Bundle.esmFallbackDirs->Pulumi.Input.make),
293
+ Util_LambdaLogging.logLevelEntry(),
293
294
  ]),
294
295
  }: Lambda.Function.functionEnvironment
295
296
  )->Pulumi.Input.make,
@@ -297,6 +298,19 @@ let finish = (
297
298
  ~opts,
298
299
  )
299
300
 
301
+ Util_LambdaLogging.makeManagedLogGroup(
302
+ ~name,
303
+ ~lambdaName=lambda.name,
304
+ ~tags=AWS.Tags.make(
305
+ ~name=name ++ "LogGroup",
306
+ ~kind=ReventlessCore.ComponentType.Plugin,
307
+ ~role=Logs,
308
+ ~component=name,
309
+ ),
310
+ ~opts,
311
+ (),
312
+ )
313
+
300
314
  // One mapping per event log stream, all targeting the one Lambda.
301
315
  // `maximumRetryAttempts` bounds a permanently failing record so it cannot
302
316
  // wedge the shard — the default of -1 retries forever, which would turn one
@@ -11,6 +11,7 @@ import * as AWS_Tags$ReventlessAws from "../AWS_Tags.res.mjs";
11
11
  import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/src/IAM/PolicyDocument.res.mjs";
12
12
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
13
13
  import * as StorageRefFields$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/StorageRefFields.res.mjs";
14
+ import * as Util_LambdaLogging$ReventlessAws from "../../util/Util_LambdaLogging.res.mjs";
14
15
  import * as Util_DynamoDbStream$ReventlessAws from "../../util/Util_DynamoDbStream.res.mjs";
15
16
 
16
17
  let registry = {};
@@ -154,11 +155,13 @@ function finish(plugin, stores, iteratorAgeAlarmMsOpt, opts) {
154
155
  [
155
156
  "ESM_FALLBACK_DIRS",
156
157
  Util_Bundle$ReventlessAws.esmFallbackDirs
157
- ]
158
+ ],
159
+ Util_LambdaLogging$ReventlessAws.logLevelEntry()
158
160
  ])
159
161
  },
160
162
  sourceCodeHash: match.sourceCodeHash
161
163
  }, opts);
164
+ Util_LambdaLogging$ReventlessAws.makeManagedLogGroup(name, lambda.name, AWS_Tags$ReventlessAws.make(name + "LogGroup", "Plugin", "Logs", undefined, name, undefined, undefined, undefined), opts, undefined);
162
165
  entries.forEach((entry, i) => {
163
166
  let esmName = name + `Stream` + i.toString();
164
167
  new (Aws.lambda.EventSourceMapping)(esmName, {
@@ -208,6 +208,7 @@ let make = (
208
208
  ("RELEASE_WINDOW_SECONDS", releaseWindowSeconds->Int.toString->Pulumi.Input.make),
209
209
  ("NODE_OPTIONS", Util_Bundle.esmLoaderNodeOptions->Pulumi.Input.make),
210
210
  ("ESM_FALLBACK_DIRS", Util_Bundle.esmFallbackDirs->Pulumi.Input.make),
211
+ Util_LambdaLogging.logLevelEntry(),
211
212
  ]),
212
213
  }: Lambda.Function.functionEnvironment
213
214
  )->Pulumi.Input.make,
@@ -215,6 +216,19 @@ let make = (
215
216
  ~opts,
216
217
  )
217
218
 
219
+ Util_LambdaLogging.makeManagedLogGroup(
220
+ ~name=name ++ "Lambda",
221
+ ~lambdaName=lambda.name,
222
+ ~tags=AWS.Tags.make(
223
+ ~name=name ++ "LambdaLogGroup",
224
+ ~kind=ReventlessCore.ComponentType.Platform,
225
+ ~role=Logs,
226
+ ~scope=Platform,
227
+ ),
228
+ ~opts,
229
+ (),
230
+ )
231
+
218
232
  let dataSourceRole = IAM.Role.makeWithDefaultPolicy(
219
233
  ~name=name ++ "DataSource",
220
234
  ~servicePrincipal=AWS.AppSync.principal->Pulumi.Output.make,
@@ -11,6 +11,7 @@ import * as AWS_Tags$ReventlessAws from "../AWS_Tags.res.mjs";
11
11
  import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/src/IAM/PolicyDocument.res.mjs";
12
12
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
13
13
  import * as Util_Pulumi$ReventlessCore from "@reventlessdev/reventless-core/src/util/Util_Pulumi.res.mjs";
14
+ import * as Util_LambdaLogging$ReventlessAws from "../../util/Util_LambdaLogging.res.mjs";
14
15
  import * as AppSync_Resolver_Native$ReventlessAws from "../Api/AppSync_Resolver_Native.res.mjs";
15
16
 
16
17
  function invokeCode(operation) {
@@ -123,11 +124,13 @@ function make(api, stores, releaseWindowSecondsOpt, nameOpt, opts) {
123
124
  [
124
125
  "ESM_FALLBACK_DIRS",
125
126
  Util_Bundle$ReventlessAws.esmFallbackDirs
126
- ]
127
+ ],
128
+ Util_LambdaLogging$ReventlessAws.logLevelEntry()
127
129
  ])
128
130
  },
129
131
  sourceCodeHash: match.sourceCodeHash
130
132
  }, opts$1);
133
+ Util_LambdaLogging$ReventlessAws.makeManagedLogGroup(name + "Lambda", lambda.name, AWS_Tags$ReventlessAws.make(name + "LambdaLogGroup", "Platform", "Logs", "Platform", undefined, undefined, undefined, undefined), opts$1, undefined);
131
134
  let dataSourceRole = IAM$PulumiAws.Role.makeWithDefaultPolicy(name + "DataSource", Pulumi.output(AWS$ReventlessAws.AppSync.principal), AWS_Tags$ReventlessAws.make(name + "DataSource", "Platform", "Identity", "Platform", undefined, undefined, undefined, undefined), opts$1);
132
135
  Pulumi.all([
133
136
  lambda.arn,
@@ -105,6 +105,7 @@ let handler = Lambda.Function.make(
105
105
  {
106
106
  Lambda.Function.variables: Dict.fromArray([
107
107
  ("Environment", Pulumi.Pulumi.getStackName()->Pulumi.Input.make),
108
+ Util_LambdaLogging.logLevelEntry(),
108
109
  ]),
109
110
  }: Lambda.Function.functionEnvironment
110
111
  )->Pulumi.Input.make,
@@ -11,6 +11,7 @@ import * as PolicyDocument$PulumiAws from "@reventlessdev/rescript-pulumi-aws/sr
11
11
  import * as Monitoring$ReventlessCore from "@reventlessdev/reventless-core/src/adapter/Monitoring/Monitoring.res.mjs";
12
12
  import * as Util_Bundle$ReventlessAws from "./Util_Bundle.res.mjs";
13
13
  import * as Util_Lambda$ReventlessAws from "./Util_Lambda.res.mjs";
14
+ import * as Util_LambdaLogging$ReventlessAws from "./Util_LambdaLogging.res.mjs";
14
15
  import * as Util_EventSourceMapping$ReventlessAws from "./Util_EventSourceMapping.res.mjs";
15
16
 
16
17
  let name = "DeadLetterQueue";
@@ -73,10 +74,13 @@ let handler = new (Aws.lambda.Function)(name, {
73
74
  layers: layers,
74
75
  tags: AWS_Tags$ReventlessAws.make(name, "Plugin", "DeadLetter", "Plugin", undefined, undefined, undefined, undefined),
75
76
  environment: {
76
- variables: Object.fromEntries([[
77
+ variables: Object.fromEntries([
78
+ [
77
79
  "Environment",
78
80
  Pulumi.getStack()
79
- ]])
81
+ ],
82
+ Util_LambdaLogging$ReventlessAws.logLevelEntry()
83
+ ])
80
84
  },
81
85
  sourceCodeHash: sourceCodeHash
82
86
  }, opts);
@@ -0,0 +1,83 @@
1
+ // Shared application of the environment-tiered logging policy
2
+ // (`Util_LogRetention`) to Lambdas. `RuntimeEnvironment_Lambda.makeFromCodeAsset`
3
+ // and the bespoke `Lambda.Function.make` builders (DeadLetterQueue, Upload,
4
+ // Geocoder, the platform UI Lambdas, the state-topic publisher) all route the
5
+ // `LOG_LEVEL` default and the managed log group through here, so a builder cannot
6
+ // silently miss the tier policy — the gap that left ~8 platform Lambdas on the
7
+ // logger's default and unmanaged, forever-retained log groups.
8
+ open PulumiAws
9
+
10
+ // Stack + prod allow-list + the unmanaged-groups escape hatch, resolved from
11
+ // config. Impure by necessity (reads the stack name and config keys); the tier
12
+ // decisions it feeds are the pure functions in `Util_LogRetention`.
13
+ let stackContext = () => {
14
+ let stack = Pulumi.Pulumi.getStackName()
15
+ let prodStacks = Util_HostUiDomain.resolveProdStacks()
16
+ let unmanagedStacks = Util_LogRetention.parseUnmanagedStacks(
17
+ Util_LocalConfig.get("unmanagedLogGroupStacks")->Option.getOr(""),
18
+ )
19
+ (stack, prodStacks, unmanagedStacks)
20
+ }
21
+
22
+ // The `("LOG_LEVEL", <tier default>)` env-var entry. For the bespoke builders
23
+ // that assemble their env with `Dict.fromArray([...])` and never pin LOG_LEVEL —
24
+ // they just append this entry.
25
+ let logLevelEntry = (): (string, Pulumi.Input.t<string>) => {
26
+ let (stack, prodStacks, _) = stackContext()
27
+ (
28
+ "LOG_LEVEL",
29
+ Util_LogRetention.logLevelFor(
30
+ ~stack,
31
+ ~prodStacks,
32
+ ~configOverride=?Util_LocalConfig.get("logLevel"),
33
+ )->Pulumi.Input.make,
34
+ )
35
+ }
36
+
37
+ // Default `LOG_LEVEL` to the environment tier when the caller has not pinned one.
38
+ // Mutates the given variables dict in place, so it must run after the caller's
39
+ // own env vars are set (theirs win). For `makeFromCodeAsset`, whose callers can
40
+ // pass LOG_LEVEL through `envVars`.
41
+ let applyLogLevelDefault = (variables: dict<Pulumi.Input.t<string>>) =>
42
+ if variables->Dict.get("LOG_LEVEL")->Option.isNone {
43
+ let (key, value) = logLevelEntry()
44
+ variables->Dict.set(key, value)
45
+ }
46
+
47
+ // Create a managed CloudWatch log group with tier retention for a Lambda when the
48
+ // stack manages its groups (`Util_LogRetention.managesLogGroup`). The group name
49
+ // derives from the function's own *physical* name output — never the logical
50
+ // name — so it matches the group Lambda would auto-create and carries Pulumi's
51
+ // uniqueness suffix. The caller supplies `~tags` (Logs-role, its own attribution
52
+ // convention) and `~opts` (so the group parents to the same component and is torn
53
+ // down with it — closing the orphan-group loop for the bespoke builders too). The
54
+ // trailing `()` terminates the optional `~opts`.
55
+ let makeManagedLogGroup = (
56
+ ~name: string,
57
+ ~lambdaName: Pulumi.Output.t<string>,
58
+ ~tags,
59
+ ~opts=?,
60
+ (),
61
+ ) => {
62
+ let (stack, prodStacks, unmanagedStacks) = stackContext()
63
+ if Util_LogRetention.managesLogGroup(~stack, ~unmanagedStacks) {
64
+ let days = Util_LogRetention.retentionDaysFor(
65
+ ~stack,
66
+ ~prodStacks,
67
+ ~configOverride=?Util_LocalConfig.get("logRetentionDays")->Option.flatMap(s =>
68
+ Int.fromString(s)
69
+ ),
70
+ )
71
+ let _ = Cloudwatch.LogGroup.make(
72
+ ~name=`${name}LogGroup`,
73
+ ~args={
74
+ name: lambdaName
75
+ ->Pulumi.Output.apply(n => `/aws/lambda/${n}`)
76
+ ->Pulumi.Output.asInput,
77
+ retentionInDays: days->Pulumi.Input.make,
78
+ tags,
79
+ },
80
+ ~opts?,
81
+ )
82
+ }
83
+ }
@@ -0,0 +1,59 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
4
+ import * as Aws from "@pulumi/aws";
5
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
6
+ import * as Pulumi from "@pulumi/pulumi";
7
+ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
8
+ import * as Util_LocalConfig$ReventlessAws from "./Util_LocalConfig.res.mjs";
9
+ import * as Util_HostUiDomain$ReventlessAws from "./Util_HostUiDomain.res.mjs";
10
+ import * as Util_LogRetention$ReventlessAws from "./Util_LogRetention.res.mjs";
11
+
12
+ function stackContext() {
13
+ let stack = Pulumi.getStack();
14
+ let prodStacks = Util_HostUiDomain$ReventlessAws.resolveProdStacks();
15
+ let unmanagedStacks = Util_LogRetention$ReventlessAws.parseUnmanagedStacks(Stdlib_Option.getOr(Util_LocalConfig$ReventlessAws.get("unmanagedLogGroupStacks"), ""));
16
+ return [
17
+ stack,
18
+ prodStacks,
19
+ unmanagedStacks
20
+ ];
21
+ }
22
+
23
+ function logLevelEntry() {
24
+ let match = stackContext();
25
+ return [
26
+ "LOG_LEVEL",
27
+ Util_LogRetention$ReventlessAws.logLevelFor(match[0], match[1], Util_LocalConfig$ReventlessAws.get("logLevel"))
28
+ ];
29
+ }
30
+
31
+ function applyLogLevelDefault(variables) {
32
+ if (!Stdlib_Option.isNone(variables["LOG_LEVEL"])) {
33
+ return;
34
+ }
35
+ let match = logLevelEntry();
36
+ variables[match[0]] = match[1];
37
+ }
38
+
39
+ function makeManagedLogGroup(name, lambdaName, tags, opts, param) {
40
+ let match = stackContext();
41
+ let stack = match[0];
42
+ if (!Util_LogRetention$ReventlessAws.managesLogGroup(stack, match[2])) {
43
+ return;
44
+ }
45
+ let days = Util_LogRetention$ReventlessAws.retentionDaysFor(stack, match[1], Stdlib_Option.flatMap(Util_LocalConfig$ReventlessAws.get("logRetentionDays"), s => Stdlib_Int.fromString(s, undefined)));
46
+ new (Aws.cloudwatch.LogGroup)(name + `LogGroup`, {
47
+ name: lambdaName.apply(n => `/aws/lambda/` + n),
48
+ retentionInDays: days,
49
+ tags: tags
50
+ }, opts !== undefined ? Primitive_option.valFromOption(opts) : undefined);
51
+ }
52
+
53
+ export {
54
+ stackContext,
55
+ logLevelEntry,
56
+ applyLogLevelDefault,
57
+ makeManagedLogGroup,
58
+ }
59
+ /* @pulumi/aws Not a pure module */