@composurecdk/lambda 0.7.0 → 0.8.1
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/README.md +138 -6
- package/dist/{alarm-config.d.ts → commonjs/alarm-config.d.ts} +30 -0
- package/dist/commonjs/alarm-config.d.ts.map +1 -0
- package/dist/commonjs/alarm-config.js +3 -0
- package/dist/{alarm-config.js.map → commonjs/alarm-config.js.map} +1 -1
- package/dist/{alarm-defaults.d.ts → commonjs/alarm-defaults.d.ts} +2 -0
- package/dist/commonjs/alarm-defaults.d.ts.map +1 -0
- package/dist/commonjs/alarm-defaults.js +61 -0
- package/dist/commonjs/alarm-defaults.js.map +1 -0
- package/dist/commonjs/defaults.d.ts.map +1 -0
- package/dist/commonjs/defaults.js +23 -0
- package/dist/commonjs/defaults.js.map +1 -0
- package/dist/commonjs/event-sources/composure-event-source.d.ts +76 -0
- package/dist/commonjs/event-sources/composure-event-source.d.ts.map +1 -0
- package/dist/commonjs/event-sources/composure-event-source.js +36 -0
- package/dist/commonjs/event-sources/composure-event-source.js.map +1 -0
- package/dist/commonjs/event-sources/sqs-event-source.d.ts +54 -0
- package/dist/commonjs/event-sources/sqs-event-source.d.ts.map +1 -0
- package/dist/commonjs/event-sources/sqs-event-source.js +80 -0
- package/dist/commonjs/event-sources/sqs-event-source.js.map +1 -0
- package/dist/{function-alarms.d.ts → commonjs/function-alarms.d.ts} +5 -2
- package/dist/commonjs/function-alarms.d.ts.map +1 -0
- package/dist/commonjs/function-alarms.js +191 -0
- package/dist/commonjs/function-alarms.js.map +1 -0
- package/dist/commonjs/function-builder.d.ts +252 -0
- package/dist/commonjs/function-builder.d.ts.map +1 -0
- package/dist/commonjs/function-builder.js +233 -0
- package/dist/commonjs/function-builder.js.map +1 -0
- package/dist/{index.d.ts → commonjs/index.d.ts} +2 -0
- package/dist/commonjs/index.d.ts.map +1 -0
- package/dist/commonjs/index.js +13 -0
- package/dist/commonjs/index.js.map +1 -0
- package/dist/commonjs/package.json +3 -0
- package/dist/esm/alarm-config.d.ts +114 -0
- package/dist/esm/alarm-config.d.ts.map +1 -0
- package/dist/esm/alarm-config.js.map +1 -0
- package/dist/esm/alarm-defaults.d.ts +19 -0
- package/dist/esm/alarm-defaults.d.ts.map +1 -0
- package/dist/{alarm-defaults.js → esm/alarm-defaults.js} +14 -0
- package/dist/esm/alarm-defaults.js.map +1 -0
- package/dist/esm/defaults.d.ts +8 -0
- package/dist/esm/defaults.d.ts.map +1 -0
- package/dist/esm/defaults.js.map +1 -0
- package/dist/esm/event-sources/composure-event-source.d.ts +76 -0
- package/dist/esm/event-sources/composure-event-source.d.ts.map +1 -0
- package/dist/esm/event-sources/composure-event-source.js +31 -0
- package/dist/esm/event-sources/composure-event-source.js.map +1 -0
- package/dist/esm/event-sources/sqs-event-source.d.ts +54 -0
- package/dist/esm/event-sources/sqs-event-source.d.ts.map +1 -0
- package/dist/esm/event-sources/sqs-event-source.js +76 -0
- package/dist/esm/event-sources/sqs-event-source.js.map +1 -0
- package/dist/esm/function-alarms.d.ts +31 -0
- package/dist/esm/function-alarms.d.ts.map +1 -0
- package/dist/{function-alarms.js → esm/function-alarms.js} +69 -4
- package/dist/esm/function-alarms.js.map +1 -0
- package/dist/esm/function-builder.d.ts +252 -0
- package/dist/esm/function-builder.d.ts.map +1 -0
- package/dist/esm/function-builder.js +230 -0
- package/dist/esm/function-builder.js.map +1 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/{index.js → esm/index.js} +1 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/package.json +39 -19
- package/dist/alarm-config.d.ts.map +0 -1
- package/dist/alarm-defaults.d.ts.map +0 -1
- package/dist/alarm-defaults.js.map +0 -1
- package/dist/defaults.d.ts.map +0 -1
- package/dist/defaults.js.map +0 -1
- package/dist/function-alarms.d.ts.map +0 -1
- package/dist/function-alarms.js.map +0 -1
- package/dist/function-builder.d.ts +0 -140
- package/dist/function-builder.d.ts.map +0 -1
- package/dist/function-builder.js +0 -67
- package/dist/function-builder.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- /package/dist/{defaults.d.ts → commonjs/defaults.d.ts} +0 -0
- /package/dist/{alarm-config.js → esm/alarm-config.js} +0 -0
- /package/dist/{defaults.js → esm/defaults.js} +0 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createFunctionBuilder = createFunctionBuilder;
|
|
4
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
5
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
6
|
+
const core_1 = require("@composurecdk/core");
|
|
7
|
+
const cloudformation_1 = require("@composurecdk/cloudformation");
|
|
8
|
+
const cloudwatch_1 = require("@composurecdk/cloudwatch");
|
|
9
|
+
const iam_1 = require("@composurecdk/iam");
|
|
10
|
+
const logs_1 = require("@composurecdk/logs");
|
|
11
|
+
const function_alarms_js_1 = require("./function-alarms.js");
|
|
12
|
+
const defaults_js_1 = require("./defaults.js");
|
|
13
|
+
const composure_event_source_js_1 = require("./event-sources/composure-event-source.js");
|
|
14
|
+
const LOGS_WRITER_POLICY_NAME = "LogsWriter";
|
|
15
|
+
class FunctionBuilder {
|
|
16
|
+
props = {};
|
|
17
|
+
#customAlarms = [];
|
|
18
|
+
#eventSources = [];
|
|
19
|
+
#configureRole;
|
|
20
|
+
#useCdkAutoRole = false;
|
|
21
|
+
addAlarm(key, configure) {
|
|
22
|
+
this.#customAlarms.push(configure(new cloudwatch_1.AlarmDefinitionBuilder(key)));
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Register an event source to be attached to the function at build time.
|
|
27
|
+
*
|
|
28
|
+
* A Lambda function can have many event sources of mixed types, so this
|
|
29
|
+
* hook is repeatable and typed to the common {@link IEventSource}. Pass a
|
|
30
|
+
* {@link ComposureEventSource} from a ComposureCDK factory (e.g. {@link sqsEventSource})
|
|
31
|
+
* or a bare concrete {@link IEventSource}.
|
|
32
|
+
*
|
|
33
|
+
* At build time the source is resolved and attached *after* the function
|
|
34
|
+
* (and its least-privilege execution role) exist, so the `source.bind(fn)`
|
|
35
|
+
* that `addEventSource` performs grants the consume permission onto the
|
|
36
|
+
* builder's role. The resolved source is exposed on
|
|
37
|
+
* {@link FunctionBuilderResult.eventSources} under `key`.
|
|
38
|
+
*
|
|
39
|
+
* Sources built by a recognised factory also enable contextual alarms —
|
|
40
|
+
* see {@link FunctionBuilderProps.recommendedAlarms}.
|
|
41
|
+
*
|
|
42
|
+
* @throws If `key` was already used by a previous `addEventSource` call.
|
|
43
|
+
*/
|
|
44
|
+
addEventSource(key, source) {
|
|
45
|
+
if (this.#eventSources.some((e) => e.key === key)) {
|
|
46
|
+
throw new Error(`FunctionBuilder.addEventSource: duplicate key "${key}". Each event source must use a unique key.`);
|
|
47
|
+
}
|
|
48
|
+
this.#eventSources.push({ key, source });
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Extend the default execution-role builder with additional configuration
|
|
53
|
+
* (inline policies, managed-policy attachments, description, etc.).
|
|
54
|
+
*
|
|
55
|
+
* The callback receives the internal {@link IRoleBuilder} that the function
|
|
56
|
+
* builder will use to construct the role. Calling `configureRole` more than
|
|
57
|
+
* once replaces the previous callback. The default `LogsWriter` inline
|
|
58
|
+
* policy is added before the callback runs; supplying another inline
|
|
59
|
+
* policy with the name `LogsWriter` throws at build time.
|
|
60
|
+
*
|
|
61
|
+
* Mutually exclusive with {@link role} and {@link useCdkAutoRole}.
|
|
62
|
+
*/
|
|
63
|
+
configureRole(fn) {
|
|
64
|
+
this.#configureRole = fn;
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Opt back into CDK's auto-created execution role attached to the
|
|
69
|
+
* `AWSLambdaBasicExecutionRole` managed policy.
|
|
70
|
+
*
|
|
71
|
+
* **Not the recommended path.** The default builder-created role grants
|
|
72
|
+
* `logs:CreateLogStream` and `logs:PutLogEvents` scoped to the function's
|
|
73
|
+
* own log group; CDK's auto-role grants those actions on `*` and also
|
|
74
|
+
* permits `logs:CreateLogGroup` arbitrarily. Use this escape hatch only
|
|
75
|
+
* when matching an existing stack's logical IDs during a phased migration
|
|
76
|
+
* or when the wildcard log surface is a deliberate trade-off.
|
|
77
|
+
*
|
|
78
|
+
* Mutually exclusive with {@link role} and {@link configureRole}.
|
|
79
|
+
*/
|
|
80
|
+
useCdkAutoRole() {
|
|
81
|
+
this.#useCdkAutoRole = true;
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
/** @internal — see ADR-0005. */
|
|
85
|
+
[core_1.COPY_STATE](target) {
|
|
86
|
+
target.#customAlarms.push(...this.#customAlarms);
|
|
87
|
+
target.#eventSources.push(...this.#eventSources);
|
|
88
|
+
target.#configureRole = this.#configureRole;
|
|
89
|
+
target.#useCdkAutoRole = this.#useCdkAutoRole;
|
|
90
|
+
}
|
|
91
|
+
build(scope, id, context = {}) {
|
|
92
|
+
const { role: roleResolvable, recommendedAlarms: alarmConfig, ...functionProps } = this.props;
|
|
93
|
+
const seamCount = (roleResolvable !== undefined ? 1 : 0) +
|
|
94
|
+
(this.#configureRole !== undefined ? 1 : 0) +
|
|
95
|
+
(this.#useCdkAutoRole ? 1 : 0);
|
|
96
|
+
if (seamCount > 1) {
|
|
97
|
+
throw new Error(`FunctionBuilder "${id}": .role(), .configureRole(), and .useCdkAutoRole() are mutually exclusive`);
|
|
98
|
+
}
|
|
99
|
+
let logGroup;
|
|
100
|
+
let logGroupProps = {};
|
|
101
|
+
if (!this.props.logGroup) {
|
|
102
|
+
logGroup = (0, logs_1.createLogGroupBuilder)().build(scope, `${id}LogGroup`).logGroup;
|
|
103
|
+
logGroupProps = { logGroup };
|
|
104
|
+
}
|
|
105
|
+
let role;
|
|
106
|
+
if (roleResolvable !== undefined) {
|
|
107
|
+
role = (0, core_1.resolve)(roleResolvable, context);
|
|
108
|
+
}
|
|
109
|
+
else if (!this.#useCdkAutoRole) {
|
|
110
|
+
role = this.#buildDefaultRole(scope, id, context, (logGroup ?? this.props.logGroup));
|
|
111
|
+
}
|
|
112
|
+
const mergedProps = {
|
|
113
|
+
...defaults_js_1.FUNCTION_DEFAULTS,
|
|
114
|
+
...logGroupProps,
|
|
115
|
+
...functionProps,
|
|
116
|
+
...(role ? { role } : {}),
|
|
117
|
+
};
|
|
118
|
+
const fn = new aws_lambda_1.Function(scope, id, mergedProps);
|
|
119
|
+
const eventSources = {};
|
|
120
|
+
const attachedEventSources = [];
|
|
121
|
+
for (const entry of this.#eventSources) {
|
|
122
|
+
const outer = (0, core_1.resolve)(entry.source, context);
|
|
123
|
+
let kind = "unknown";
|
|
124
|
+
let eventSource;
|
|
125
|
+
if ((0, composure_event_source_js_1.isComposureEventSource)(outer)) {
|
|
126
|
+
kind = outer.kind;
|
|
127
|
+
eventSource = (0, core_1.resolve)(outer.source, context);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
eventSource = outer;
|
|
131
|
+
}
|
|
132
|
+
// Attach after the function exists so the `source.bind(fn)` that
|
|
133
|
+
// `addEventSource` performs grants the consume permission onto the
|
|
134
|
+
// builder's least-privilege role; the mapping UUID is only readable
|
|
135
|
+
// once bound.
|
|
136
|
+
fn.addEventSource(eventSource);
|
|
137
|
+
eventSources[entry.key] = eventSource;
|
|
138
|
+
attachedEventSources.push({
|
|
139
|
+
key: entry.key,
|
|
140
|
+
kind,
|
|
141
|
+
eventSourceMappingId: composure_event_source_js_1.EVENT_SOURCE_MAPPING_ID_READERS[kind]?.(eventSource),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const alarms = (0, function_alarms_js_1.createFunctionAlarms)(scope, id, fn, alarmConfig, mergedProps, attachedEventSources, this.#customAlarms);
|
|
145
|
+
const resolvedRole = role ?? fn.role;
|
|
146
|
+
if (!resolvedRole) {
|
|
147
|
+
throw new Error(`FunctionBuilder "${id}": Lambda function has no execution role.`);
|
|
148
|
+
}
|
|
149
|
+
return { function: fn, role: resolvedRole, logGroup, alarms, eventSources };
|
|
150
|
+
}
|
|
151
|
+
#buildDefaultRole(scope, id, context, logGroup) {
|
|
152
|
+
if (!logGroup) {
|
|
153
|
+
throw new Error(`FunctionBuilder "${id}": cannot build the default execution role without a log group.`);
|
|
154
|
+
}
|
|
155
|
+
const logGroupArn = logGroup.logGroupArn;
|
|
156
|
+
const roleBuilder = (0, iam_1.createServiceRoleBuilder)("lambda.amazonaws.com").addInlinePolicyStatements(LOGS_WRITER_POLICY_NAME, [
|
|
157
|
+
(0, iam_1.createStatementBuilder)()
|
|
158
|
+
.allow()
|
|
159
|
+
.actions(["logs:CreateLogStream", "logs:PutLogEvents"])
|
|
160
|
+
.resources([logGroupArn, `${logGroupArn}:log-stream:*`]),
|
|
161
|
+
]);
|
|
162
|
+
// CDK attaches AWSLambdaVPCAccessExecutionRole only when it constructs
|
|
163
|
+
// the role itself; when we supply the role we must add it ourselves.
|
|
164
|
+
if (this.props.vpc) {
|
|
165
|
+
roleBuilder.managedPolicies([
|
|
166
|
+
...(roleBuilder.managedPolicies() ?? []),
|
|
167
|
+
aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaVPCAccessExecutionRole"),
|
|
168
|
+
]);
|
|
169
|
+
}
|
|
170
|
+
if (this.#configureRole) {
|
|
171
|
+
this.#configureRole(guardLogsWriter(roleBuilder, id));
|
|
172
|
+
}
|
|
173
|
+
return roleBuilder.build(scope, `${id}ExecutionRole`, context).role;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Creates a new {@link IFunctionBuilder} for configuring an AWS Lambda function.
|
|
178
|
+
*
|
|
179
|
+
* This is the entry point for defining a Lambda function component. The returned
|
|
180
|
+
* builder exposes every {@link FunctionBuilderProps} property as a fluent setter/getter
|
|
181
|
+
* and implements {@link Lifecycle} for use with {@link compose}.
|
|
182
|
+
*
|
|
183
|
+
* @returns A fluent builder for an AWS Lambda function.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* const handler = createFunctionBuilder()
|
|
188
|
+
* .runtime(Runtime.NODEJS_22_X)
|
|
189
|
+
* .handler("index.handler")
|
|
190
|
+
* .code(Code.fromAsset("lambda"))
|
|
191
|
+
* .timeout(Duration.seconds(30));
|
|
192
|
+
*
|
|
193
|
+
* // Use standalone:
|
|
194
|
+
* const result = handler.build(stack, "MyFunction");
|
|
195
|
+
*
|
|
196
|
+
* // Or compose into a system:
|
|
197
|
+
* const system = compose(
|
|
198
|
+
* { handler, table: createTableBuilder() },
|
|
199
|
+
* { handler: ["table"], table: [] },
|
|
200
|
+
* );
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
function createFunctionBuilder() {
|
|
204
|
+
return (0, cloudformation_1.taggedBuilder)(FunctionBuilder);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Wraps a role builder so a user configurator that calls
|
|
208
|
+
* `addInlinePolicyStatements("LogsWriter", ...)` fails loudly. RoleBuilder
|
|
209
|
+
* stores inline policies in an internal array and the resulting record uses
|
|
210
|
+
* the policy name as a key — a duplicate `LogsWriter` would silently
|
|
211
|
+
* overwrite the scoped log policy and re-introduce wildcard log access.
|
|
212
|
+
*/
|
|
213
|
+
function guardLogsWriter(rb, functionId) {
|
|
214
|
+
const original = rb.addInlinePolicyStatements.bind(rb);
|
|
215
|
+
return new Proxy(rb, {
|
|
216
|
+
get(target, prop, receiver) {
|
|
217
|
+
if (prop === "addInlinePolicyStatements") {
|
|
218
|
+
const guarded = (name, statements) => {
|
|
219
|
+
if (name === LOGS_WRITER_POLICY_NAME) {
|
|
220
|
+
throw new Error(`FunctionBuilder "${functionId}": cannot add an inline policy named ` +
|
|
221
|
+
`"${LOGS_WRITER_POLICY_NAME}" via .configureRole — the builder already ` +
|
|
222
|
+
`attaches one scoped to the function's log group. Use a different ` +
|
|
223
|
+
`name or call .role(...) to take full control of the role.`);
|
|
224
|
+
}
|
|
225
|
+
return original(name, statements);
|
|
226
|
+
};
|
|
227
|
+
return guarded;
|
|
228
|
+
}
|
|
229
|
+
return Reflect.get(target, prop, receiver);
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=function-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-builder.js","sourceRoot":"","sources":["../../src/function-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,4 +2,6 @@ export { createFunctionBuilder, type FunctionBuilderProps, type FunctionBuilderR
|
|
|
2
2
|
export { FUNCTION_DEFAULTS } from "./defaults.js";
|
|
3
3
|
export { type FunctionAlarmConfig, type PercentageAlarmConfig } from "./alarm-config.js";
|
|
4
4
|
export { FUNCTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
5
|
+
export { type ComposureEventSource, type EventSourceKind, } from "./event-sources/composure-event-source.js";
|
|
6
|
+
export { sqsEventSource, DEFAULT_SQS_EVENT_SOURCE_PROPS, } from "./event-sources/sqs-event-source.js";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EACL,cAAc,EACd,8BAA8B,GAC/B,MAAM,qCAAqC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_SQS_EVENT_SOURCE_PROPS = exports.sqsEventSource = exports.FUNCTION_ALARM_DEFAULTS = exports.FUNCTION_DEFAULTS = exports.createFunctionBuilder = void 0;
|
|
4
|
+
var function_builder_js_1 = require("./function-builder.js");
|
|
5
|
+
Object.defineProperty(exports, "createFunctionBuilder", { enumerable: true, get: function () { return function_builder_js_1.createFunctionBuilder; } });
|
|
6
|
+
var defaults_js_1 = require("./defaults.js");
|
|
7
|
+
Object.defineProperty(exports, "FUNCTION_DEFAULTS", { enumerable: true, get: function () { return defaults_js_1.FUNCTION_DEFAULTS; } });
|
|
8
|
+
var alarm_defaults_js_1 = require("./alarm-defaults.js");
|
|
9
|
+
Object.defineProperty(exports, "FUNCTION_ALARM_DEFAULTS", { enumerable: true, get: function () { return alarm_defaults_js_1.FUNCTION_ALARM_DEFAULTS; } });
|
|
10
|
+
var sqs_event_source_js_1 = require("./event-sources/sqs-event-source.js");
|
|
11
|
+
Object.defineProperty(exports, "sqsEventSource", { enumerable: true, get: function () { return sqs_event_source_js_1.sqsEventSource; } });
|
|
12
|
+
Object.defineProperty(exports, "DEFAULT_SQS_EVENT_SOURCE_PROPS", { enumerable: true, get: function () { return sqs_event_source_js_1.DEFAULT_SQS_EVENT_SOURCE_PROPS; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,6DAK+B;AAJ7B,4HAAA,qBAAqB,OAAA;AAKvB,6CAAkD;AAAzC,gHAAA,iBAAiB,OAAA;AAE1B,yDAA8D;AAArD,4HAAA,uBAAuB,OAAA;AAKhC,2EAG6C;AAF3C,qHAAA,cAAc,OAAA;AACd,qIAAA,8BAA8B,OAAA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { AlarmConfig } from "@composurecdk/cloudwatch";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for a percentage-based contextual alarm.
|
|
4
|
+
*
|
|
5
|
+
* Derived from {@link AlarmConfig} with `threshold` replaced by
|
|
6
|
+
* `thresholdPercent`. These alarms derive their threshold as a
|
|
7
|
+
* percentage of a function property (e.g., timeout or reserved
|
|
8
|
+
* concurrency). The threshold automatically adjusts when the base
|
|
9
|
+
* value changes, keeping the alarm true to its definition.
|
|
10
|
+
*
|
|
11
|
+
* For a fixed absolute threshold, disable the recommended alarm and
|
|
12
|
+
* add a custom one via {@link IFunctionBuilder.addAlarm}.
|
|
13
|
+
*/
|
|
14
|
+
export type PercentageAlarmConfig = Omit<AlarmConfig, "threshold"> & {
|
|
15
|
+
/**
|
|
16
|
+
* Threshold as a fraction of the base value (e.g., `0.9` = 90%).
|
|
17
|
+
* Must be between 0 and 1 (exclusive of 0).
|
|
18
|
+
*/
|
|
19
|
+
thresholdPercent?: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Type for percentage-based defaults. Mirrors {@link AlarmConfigDefaults}:
|
|
23
|
+
* every tunable field is required, but `alarmName` is intentionally not.
|
|
24
|
+
*/
|
|
25
|
+
export type PercentageAlarmConfigDefaults = Required<Omit<PercentageAlarmConfig, "alarmName">>;
|
|
26
|
+
/**
|
|
27
|
+
* Controls which recommended alarms are created for a Lambda function.
|
|
28
|
+
* All alarms are enabled by default with AWS-recommended thresholds.
|
|
29
|
+
* Set individual alarms to `false` to disable them, or provide an
|
|
30
|
+
* {@link AlarmConfig} or {@link PercentageAlarmConfig} to tune thresholds.
|
|
31
|
+
*
|
|
32
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#Lambda
|
|
33
|
+
*/
|
|
34
|
+
export interface FunctionAlarmConfig {
|
|
35
|
+
/**
|
|
36
|
+
* Master switch: set to `false` to disable all recommended alarms.
|
|
37
|
+
* Individual alarms can also be disabled via their own entry.
|
|
38
|
+
* @default true
|
|
39
|
+
*/
|
|
40
|
+
enabled?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Alarm when the function produces invocation errors.
|
|
43
|
+
*
|
|
44
|
+
* Metric: `AWS/Lambda Errors`, statistic Sum, period 1 minute.
|
|
45
|
+
* Default threshold: > 0 errors.
|
|
46
|
+
*
|
|
47
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#Lambda
|
|
48
|
+
*/
|
|
49
|
+
errors?: AlarmConfig | false;
|
|
50
|
+
/**
|
|
51
|
+
* Alarm when invocations are throttled.
|
|
52
|
+
*
|
|
53
|
+
* Metric: `AWS/Lambda Throttles`, statistic Sum, period 1 minute.
|
|
54
|
+
* Default threshold: > 0 throttles.
|
|
55
|
+
*
|
|
56
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#Lambda
|
|
57
|
+
*/
|
|
58
|
+
throttles?: AlarmConfig | false;
|
|
59
|
+
/**
|
|
60
|
+
* Alarm when p99 duration approaches the configured timeout.
|
|
61
|
+
*
|
|
62
|
+
* Only created when the function has a `timeout` configured, since
|
|
63
|
+
* the threshold is derived as a percentage of the timeout value.
|
|
64
|
+
*
|
|
65
|
+
* Metric: `AWS/Lambda Duration`, statistic p99, period 1 minute.
|
|
66
|
+
* Default: 90% of the function timeout (`thresholdPercent: 0.9`).
|
|
67
|
+
*
|
|
68
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#Lambda
|
|
69
|
+
*/
|
|
70
|
+
duration?: PercentageAlarmConfig | false;
|
|
71
|
+
/**
|
|
72
|
+
* Alarm when concurrent executions approach the reserved limit.
|
|
73
|
+
*
|
|
74
|
+
* Only created when `reservedConcurrentExecutions` is configured,
|
|
75
|
+
* since the threshold is derived as a percentage of the reserved limit.
|
|
76
|
+
*
|
|
77
|
+
* Metric: `AWS/Lambda ConcurrentExecutions`, statistic Maximum, period 1 minute.
|
|
78
|
+
* Default: 80% of reservedConcurrentExecutions (`thresholdPercent: 0.8`).
|
|
79
|
+
*
|
|
80
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#Lambda
|
|
81
|
+
*/
|
|
82
|
+
concurrentExecutions?: PercentageAlarmConfig | false;
|
|
83
|
+
/**
|
|
84
|
+
* Alarm when an event source fails to invoke the function.
|
|
85
|
+
*
|
|
86
|
+
* Contextual: one alarm is created per event source attached via
|
|
87
|
+
* {@link IFunctionBuilder.addEventSource} whose kind emits per-mapping ESM
|
|
88
|
+
* metrics (currently SQS). The created alarm's key is the event source's
|
|
89
|
+
* key suffixed with `FailedInvocations` (e.g. `ordersFailedInvocations`);
|
|
90
|
+
* this config tunes every such alarm.
|
|
91
|
+
*
|
|
92
|
+
* Metric: `AWS/Lambda FailedInvokeEventCount`, statistic Sum, period 1
|
|
93
|
+
* minute, dimensioned on the event source mapping. Default threshold: > 0.
|
|
94
|
+
*
|
|
95
|
+
* @see https://aws.amazon.com/blogs/compute/introducing-new-event-source-mapping-esm-metrics-for-aws-lambda/
|
|
96
|
+
*/
|
|
97
|
+
eventSourceFailedInvocations?: AlarmConfig | false;
|
|
98
|
+
/**
|
|
99
|
+
* Alarm when an event source drops events after exhausting retries or TTL.
|
|
100
|
+
*
|
|
101
|
+
* Contextual: one alarm is created per event source attached via
|
|
102
|
+
* {@link IFunctionBuilder.addEventSource} whose kind emits per-mapping ESM
|
|
103
|
+
* metrics (currently SQS). The created alarm's key is the event source's
|
|
104
|
+
* key suffixed with `DroppedEvents` (e.g. `ordersDroppedEvents`); this
|
|
105
|
+
* config tunes every such alarm.
|
|
106
|
+
*
|
|
107
|
+
* Metric: `AWS/Lambda DroppedEventCount`, statistic Sum, period 1 minute,
|
|
108
|
+
* dimensioned on the event source mapping. Default threshold: > 0.
|
|
109
|
+
*
|
|
110
|
+
* @see https://aws.amazon.com/blogs/compute/introducing-new-event-source-mapping-esm-metrics-for-aws-lambda/
|
|
111
|
+
*/
|
|
112
|
+
eventSourceDroppedEvents?: AlarmConfig | false;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=alarm-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-config.d.ts","sourceRoot":"","sources":["../../src/alarm-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG;IACnE;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG,QAAQ,CAAC,IAAI,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC,CAAC;AAE/F;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAE7B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAEhC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAC;IAEzC;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAC;IAErD;;;;;;;;;;;;;OAaG;IACH,4BAA4B,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAEnD;;;;;;;;;;;;;OAaG;IACH,wBAAwB,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;CAChD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-config.js","sourceRoot":"","sources":["../../src/alarm-config.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AlarmConfigDefaults } from "@composurecdk/cloudwatch";
|
|
2
|
+
import type { PercentageAlarmConfigDefaults } from "./alarm-config.js";
|
|
3
|
+
interface FunctionAlarmDefaults {
|
|
4
|
+
enabled: true;
|
|
5
|
+
errors: AlarmConfigDefaults;
|
|
6
|
+
throttles: AlarmConfigDefaults;
|
|
7
|
+
duration: PercentageAlarmConfigDefaults;
|
|
8
|
+
concurrentExecutions: PercentageAlarmConfigDefaults;
|
|
9
|
+
eventSourceFailedInvocations: AlarmConfigDefaults;
|
|
10
|
+
eventSourceDroppedEvents: AlarmConfigDefaults;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* AWS-recommended default alarm configuration for Lambda functions.
|
|
14
|
+
*
|
|
15
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#Lambda
|
|
16
|
+
*/
|
|
17
|
+
export declare const FUNCTION_ALARM_DEFAULTS: FunctionAlarmDefaults;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=alarm-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-defaults.d.ts","sourceRoot":"","sources":["../../src/alarm-defaults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAEvE,UAAU,qBAAqB;IAC7B,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,mBAAmB,CAAC;IAC5B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,QAAQ,EAAE,6BAA6B,CAAC;IACxC,oBAAoB,EAAE,6BAA6B,CAAC;IACpD,4BAA4B,EAAE,mBAAmB,CAAC;IAClD,wBAAwB,EAAE,mBAAmB,CAAC;CAC/C;AAED;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,qBAwDrC,CAAC"}
|
|
@@ -40,5 +40,19 @@ export const FUNCTION_ALARM_DEFAULTS = {
|
|
|
40
40
|
datapointsToAlarm: 3,
|
|
41
41
|
treatMissingData: TreatMissingData.NOT_BREACHING,
|
|
42
42
|
},
|
|
43
|
+
/** Any failed invocation from an event source is worth investigating; threshold 0. */
|
|
44
|
+
eventSourceFailedInvocations: {
|
|
45
|
+
threshold: 0,
|
|
46
|
+
evaluationPeriods: 1,
|
|
47
|
+
datapointsToAlarm: 1,
|
|
48
|
+
treatMissingData: TreatMissingData.NOT_BREACHING,
|
|
49
|
+
},
|
|
50
|
+
/** Any dropped event is lost work; threshold 0. */
|
|
51
|
+
eventSourceDroppedEvents: {
|
|
52
|
+
threshold: 0,
|
|
53
|
+
evaluationPeriods: 1,
|
|
54
|
+
datapointsToAlarm: 1,
|
|
55
|
+
treatMissingData: TreatMissingData.NOT_BREACHING,
|
|
56
|
+
},
|
|
43
57
|
};
|
|
44
58
|
//# sourceMappingURL=alarm-defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-defaults.js","sourceRoot":"","sources":["../../src/alarm-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAc9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA0B;IAC5D,OAAO,EAAE,IAAI;IAEb,qDAAqD;IACrD,MAAM,EAAE;QACN,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED,6DAA6D;IAC7D,SAAS,EAAE;QACT,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED;;;OAGG;IACH,QAAQ,EAAE;QACR,gBAAgB,EAAE,GAAG;QACrB,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED;;;OAGG;IACH,oBAAoB,EAAE;QACpB,gBAAgB,EAAE,GAAG;QACrB,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED,sFAAsF;IACtF,4BAA4B,EAAE;QAC5B,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED,mDAAmD;IACnD,wBAAwB,EAAE;QACxB,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;CACF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type FunctionProps } from "aws-cdk-lib/aws-lambda";
|
|
2
|
+
/**
|
|
3
|
+
* Secure, AWS-recommended defaults applied to every Lambda function built
|
|
4
|
+
* with {@link createFunctionBuilder}. Each property can be individually
|
|
5
|
+
* overridden via the builder's fluent API.
|
|
6
|
+
*/
|
|
7
|
+
export declare const FUNCTION_DEFAULTS: Partial<FunctionProps>;
|
|
8
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEpF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,OAAO,CAAC,aAAa,CAapD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAsB,MAAM,wBAAwB,CAAC;AAEpF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA2B;IACvD;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC,MAAM;IAEvB;;;;OAIG;IACH,aAAa,EAAE,aAAa,CAAC,IAAI;CAClC,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { IEventSource } from "aws-cdk-lib/aws-lambda";
|
|
2
|
+
import type { Resolvable } from "@composurecdk/core";
|
|
3
|
+
/**
|
|
4
|
+
* Discriminator for the kind of event source a {@link ComposureEventSource}
|
|
5
|
+
* wraps. `FunctionBuilder` keys its contextual alarms and invariant checks
|
|
6
|
+
* off this value so it never has to `instanceof` CDK internals.
|
|
7
|
+
*
|
|
8
|
+
* `"unknown"` is the kind assigned to a bare {@link IEventSource} passed
|
|
9
|
+
* straight to {@link IFunctionBuilder.addEventSource} as an escape hatch —
|
|
10
|
+
* the builder still attaches it, but cannot reason about it.
|
|
11
|
+
*/
|
|
12
|
+
export type EventSourceKind = "sqs" | "unknown";
|
|
13
|
+
/** @internal — brands {@link ComposureEventSource} so the guard is unambiguous. */
|
|
14
|
+
declare const COMPOSURE_EVENT_SOURCE: unique symbol;
|
|
15
|
+
/**
|
|
16
|
+
* A `Resolvable`-aware event source produced by a ComposureCDK factory
|
|
17
|
+
* (e.g. {@link sqsEventSource}).
|
|
18
|
+
*
|
|
19
|
+
* Follows the `events/targets` factory shape — the factory wraps the
|
|
20
|
+
* underlying CDK event source and resolves any `ref()` to a sibling
|
|
21
|
+
* component at build time — and additionally tags it with a
|
|
22
|
+
* {@link EventSourceKind} discriminator so `FunctionBuilder` can pick the
|
|
23
|
+
* right contextual alarms without inspecting CDK internals.
|
|
24
|
+
*
|
|
25
|
+
* Construct one via a factory rather than by hand; the brand is private.
|
|
26
|
+
*/
|
|
27
|
+
export interface ComposureEventSource {
|
|
28
|
+
/** @internal */
|
|
29
|
+
readonly [COMPOSURE_EVENT_SOURCE]: true;
|
|
30
|
+
/** The kind of source, used to dispatch contextual alarms and checks. */
|
|
31
|
+
readonly kind: EventSourceKind;
|
|
32
|
+
/**
|
|
33
|
+
* The wrapped CDK event source, deferred behind a {@link Resolvable} when
|
|
34
|
+
* the factory was handed a `ref()` to a sibling component's output.
|
|
35
|
+
*/
|
|
36
|
+
readonly source: Resolvable<IEventSource>;
|
|
37
|
+
}
|
|
38
|
+
/** @internal — assembles a branded {@link ComposureEventSource}. */
|
|
39
|
+
export declare function composureEventSource(kind: EventSourceKind, source: Resolvable<IEventSource>): ComposureEventSource;
|
|
40
|
+
/**
|
|
41
|
+
* Reads the event source mapping UUID off a bound CDK source, keyed by
|
|
42
|
+
* {@link EventSourceKind}. Defined only for kinds whose per-mapping ESM
|
|
43
|
+
* metrics back contextual alarms (currently SQS); `FunctionBuilder` invokes
|
|
44
|
+
* the reader after `addEventSource` so the binding exists. Keying off `kind`
|
|
45
|
+
* — like {@link EVENT_SOURCE_ALARM_SPECS} — keeps the builder from
|
|
46
|
+
* `instanceof`-ing CDK source classes.
|
|
47
|
+
*
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
export declare const EVENT_SOURCE_MAPPING_ID_READERS: Record<EventSourceKind, ((bound: IEventSource) => string) | undefined>;
|
|
51
|
+
/**
|
|
52
|
+
* Type guard distinguishing a {@link ComposureEventSource} from a bare
|
|
53
|
+
* {@link IEventSource} escape-hatch value.
|
|
54
|
+
*/
|
|
55
|
+
export declare function isComposureEventSource(value: ComposureEventSource | IEventSource): value is ComposureEventSource;
|
|
56
|
+
/**
|
|
57
|
+
* An event source resolved and attached to a function during build, carrying
|
|
58
|
+
* the metadata the alarm machinery needs to emit contextual alarms.
|
|
59
|
+
*
|
|
60
|
+
* @internal — the contract between `FunctionBuilder.build()` and the
|
|
61
|
+
* event-source alarm machinery in `function-alarms.ts`.
|
|
62
|
+
*/
|
|
63
|
+
export interface AttachedEventSource {
|
|
64
|
+
/** The key the source was registered under via `addEventSource`. */
|
|
65
|
+
key: string;
|
|
66
|
+
/** The kind of source, used to dispatch contextual alarms. */
|
|
67
|
+
kind: EventSourceKind;
|
|
68
|
+
/**
|
|
69
|
+
* The event source mapping UUID, populated for kinds whose per-mapping
|
|
70
|
+
* ESM metrics back contextual alarms (currently SQS only). The contextual
|
|
71
|
+
* alarms key off this dimension.
|
|
72
|
+
*/
|
|
73
|
+
eventSourceMappingId?: string;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=composure-event-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composure-event-source.d.ts","sourceRoot":"","sources":["../../../src/event-sources/composure-event-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,SAAS,CAAC;AAEhD,mFAAmF;AACnF,QAAA,MAAM,sBAAsB,eAAgD,CAAC;AAE7E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAoB;IACnC,gBAAgB;IAChB,QAAQ,CAAC,CAAC,sBAAsB,CAAC,EAAE,IAAI,CAAC;IAExC,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAE/B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;CAC3C;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,UAAU,CAAC,YAAY,CAAC,GAC/B,oBAAoB,CAEtB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,EAAE,MAAM,CAClD,eAAe,EACf,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,MAAM,CAAC,GAAG,SAAS,CAO9C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,GAAG,YAAY,GACzC,KAAK,IAAI,oBAAoB,CAE/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;IAEZ,8DAA8D;IAC9D,IAAI,EAAE,eAAe,CAAC;IAEtB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** @internal — brands {@link ComposureEventSource} so the guard is unambiguous. */
|
|
2
|
+
const COMPOSURE_EVENT_SOURCE = Symbol.for("composurecdk.lambda.eventSource");
|
|
3
|
+
/** @internal — assembles a branded {@link ComposureEventSource}. */
|
|
4
|
+
export function composureEventSource(kind, source) {
|
|
5
|
+
return { [COMPOSURE_EVENT_SOURCE]: true, kind, source };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Reads the event source mapping UUID off a bound CDK source, keyed by
|
|
9
|
+
* {@link EventSourceKind}. Defined only for kinds whose per-mapping ESM
|
|
10
|
+
* metrics back contextual alarms (currently SQS); `FunctionBuilder` invokes
|
|
11
|
+
* the reader after `addEventSource` so the binding exists. Keying off `kind`
|
|
12
|
+
* — like {@link EVENT_SOURCE_ALARM_SPECS} — keeps the builder from
|
|
13
|
+
* `instanceof`-ing CDK source classes.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export const EVENT_SOURCE_MAPPING_ID_READERS = {
|
|
18
|
+
// Safe: the `"sqs"` kind is only ever assigned by `sqsEventSource()`, which
|
|
19
|
+
// constructs the `SqsEventSource` in the same call — kind and concrete class
|
|
20
|
+
// move in lockstep.
|
|
21
|
+
sqs: (bound) => bound.eventSourceMappingId,
|
|
22
|
+
unknown: undefined,
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Type guard distinguishing a {@link ComposureEventSource} from a bare
|
|
26
|
+
* {@link IEventSource} escape-hatch value.
|
|
27
|
+
*/
|
|
28
|
+
export function isComposureEventSource(value) {
|
|
29
|
+
return COMPOSURE_EVENT_SOURCE in value;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=composure-event-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composure-event-source.js","sourceRoot":"","sources":["../../../src/event-sources/composure-event-source.ts"],"names":[],"mappings":"AAeA,mFAAmF;AACnF,MAAM,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AA4B7E,oEAAoE;AACpE,MAAM,UAAU,oBAAoB,CAClC,IAAqB,EACrB,MAAgC;IAEhC,OAAO,EAAE,CAAC,sBAAsB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAGxC;IACF,4EAA4E;IAC5E,6EAA6E;IAC7E,oBAAoB;IACpB,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAE,KAAwB,CAAC,oBAAoB;IAC9D,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAA0C;IAE1C,OAAO,sBAAsB,IAAI,KAAK,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type SqsEventSourceProps } from "aws-cdk-lib/aws-lambda-event-sources";
|
|
2
|
+
import type { IQueue } from "aws-cdk-lib/aws-sqs";
|
|
3
|
+
import { type Resolvable } from "@composurecdk/core";
|
|
4
|
+
import { type ComposureEventSource } from "./composure-event-source.js";
|
|
5
|
+
/**
|
|
6
|
+
* Secure, AWS-recommended defaults applied to every SQS event source built
|
|
7
|
+
* with {@link sqsEventSource}. Each property can be overridden via the
|
|
8
|
+
* factory's `props` argument.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_SQS_EVENT_SOURCE_PROPS: Pick<SqsEventSourceProps, "reportBatchItemFailures" | "metricsConfig">;
|
|
11
|
+
/**
|
|
12
|
+
* Wraps an SQS queue as a Lambda {@link IEventSource}, deferring resolution
|
|
13
|
+
* when the queue is a `ref()` to a sibling component's output.
|
|
14
|
+
*
|
|
15
|
+
* Follows the `events/targets` factory shape: register the result with
|
|
16
|
+
* {@link IFunctionBuilder.addEventSource} and the builder resolves the
|
|
17
|
+
* `ref()`, attaches the source, and (because `addEventSource` calls
|
|
18
|
+
* `source.bind(fn)`) grants the function's least-privilege execution role
|
|
19
|
+
* permission to consume the queue.
|
|
20
|
+
*
|
|
21
|
+
* Applies {@link DEFAULT_SQS_EVENT_SOURCE_PROPS}; pass `props` to override.
|
|
22
|
+
*
|
|
23
|
+
* ## Cross-component invariants (not enforced)
|
|
24
|
+
*
|
|
25
|
+
* AWS Well-Architected guidance spans the queue and the function:
|
|
26
|
+
* - the source queue's visibility timeout should be ≥ 6× the function
|
|
27
|
+
* timeout, leaving room for Lambda to retry a throttled batch;
|
|
28
|
+
* - the source queue's redrive `maxReceiveCount` should be ≥ 5 before the DLQ.
|
|
29
|
+
*
|
|
30
|
+
* These are not validated here — the queue often arrives as a `ref()` that is
|
|
31
|
+
* not resolvable at configuration time. Tracked in laazyj/composureCDK#123
|
|
32
|
+
* and #124.
|
|
33
|
+
*
|
|
34
|
+
* @param queue - The source queue, concrete or a `ref()` to a sibling.
|
|
35
|
+
* @param props - Overrides for {@link DEFAULT_SQS_EVENT_SOURCE_PROPS} and any
|
|
36
|
+
* other {@link SqsEventSourceProps}.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* compose(
|
|
41
|
+
* {
|
|
42
|
+
* orders: createQueueBuilder().queueName("orders"),
|
|
43
|
+
* processor: createFunctionBuilder()
|
|
44
|
+
* .runtime(Runtime.NODEJS_22_X)
|
|
45
|
+
* .handler("index.handler")
|
|
46
|
+
* .code(Code.fromAsset("lambda"))
|
|
47
|
+
* .addEventSource("orders", sqsEventSource(ref("orders", (r) => r.queue))),
|
|
48
|
+
* },
|
|
49
|
+
* { orders: [], processor: ["orders"] },
|
|
50
|
+
* );
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function sqsEventSource(queue: Resolvable<IQueue>, props?: SqsEventSourceProps): ComposureEventSource;
|
|
54
|
+
//# sourceMappingURL=sqs-event-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqs-event-source.d.ts","sourceRoot":"","sources":["../../../src/event-sources/sqs-event-source.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAChG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,KAAK,oBAAoB,EAAwB,MAAM,6BAA6B,CAAC;AAE9F;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,IAAI,CAC/C,mBAAmB,EACnB,yBAAyB,GAAG,eAAe,CAkB5C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EACzB,KAAK,CAAC,EAAE,mBAAmB,GAC1B,oBAAoB,CAMtB"}
|