@composurecdk/lambda 0.11.2 → 0.12.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.
Files changed (70) hide show
  1. package/README.md +131 -23
  2. package/dist/commonjs/alarm-config.d.ts +1 -1
  3. package/dist/commonjs/event-sources/composure-event-source.d.ts +3 -3
  4. package/dist/commonjs/event-sources/composure-event-source.d.ts.map +1 -1
  5. package/dist/commonjs/event-sources/composure-event-source.js +5 -1
  6. package/dist/commonjs/event-sources/composure-event-source.js.map +1 -1
  7. package/dist/commonjs/event-sources/dynamodb-event-source.d.ts +2 -2
  8. package/dist/commonjs/event-sources/dynamodb-event-source.d.ts.map +1 -1
  9. package/dist/commonjs/event-sources/dynamodb-event-source.js +2 -26
  10. package/dist/commonjs/event-sources/dynamodb-event-source.js.map +1 -1
  11. package/dist/commonjs/event-sources/event-source-relationship-guards.d.ts +3 -2
  12. package/dist/commonjs/event-sources/event-source-relationship-guards.d.ts.map +1 -1
  13. package/dist/commonjs/event-sources/event-source-relationship-guards.js +9 -5
  14. package/dist/commonjs/event-sources/event-source-relationship-guards.js.map +1 -1
  15. package/dist/commonjs/event-sources/kinesis-event-source.d.ts +129 -0
  16. package/dist/commonjs/event-sources/kinesis-event-source.d.ts.map +1 -0
  17. package/dist/commonjs/event-sources/kinesis-event-source.js +102 -0
  18. package/dist/commonjs/event-sources/kinesis-event-source.js.map +1 -0
  19. package/dist/commonjs/event-sources/sqs-event-source.d.ts +2 -2
  20. package/dist/commonjs/event-sources/sqs-event-source.js +2 -2
  21. package/dist/commonjs/event-sources/stream-event-source-defaults.d.ts +1 -1
  22. package/dist/commonjs/event-sources/stream-event-source-defaults.d.ts.map +1 -1
  23. package/dist/commonjs/event-sources/stream-event-source-defaults.js +3 -1
  24. package/dist/commonjs/event-sources/stream-event-source-defaults.js.map +1 -1
  25. package/dist/commonjs/event-sources/stream-event-source.d.ts +32 -0
  26. package/dist/commonjs/event-sources/stream-event-source.d.ts.map +1 -0
  27. package/dist/commonjs/event-sources/stream-event-source.js +44 -0
  28. package/dist/commonjs/event-sources/stream-event-source.js.map +1 -0
  29. package/dist/commonjs/function-alarms.d.ts.map +1 -1
  30. package/dist/commonjs/function-alarms.js +7 -3
  31. package/dist/commonjs/function-alarms.js.map +1 -1
  32. package/dist/commonjs/index.d.ts +1 -0
  33. package/dist/commonjs/index.d.ts.map +1 -1
  34. package/dist/commonjs/index.js +5 -1
  35. package/dist/commonjs/index.js.map +1 -1
  36. package/dist/esm/alarm-config.d.ts +1 -1
  37. package/dist/esm/event-sources/composure-event-source.d.ts +3 -3
  38. package/dist/esm/event-sources/composure-event-source.d.ts.map +1 -1
  39. package/dist/esm/event-sources/composure-event-source.js +5 -1
  40. package/dist/esm/event-sources/composure-event-source.js.map +1 -1
  41. package/dist/esm/event-sources/dynamodb-event-source.d.ts +2 -2
  42. package/dist/esm/event-sources/dynamodb-event-source.d.ts.map +1 -1
  43. package/dist/esm/event-sources/dynamodb-event-source.js +3 -27
  44. package/dist/esm/event-sources/dynamodb-event-source.js.map +1 -1
  45. package/dist/esm/event-sources/event-source-relationship-guards.d.ts +3 -2
  46. package/dist/esm/event-sources/event-source-relationship-guards.d.ts.map +1 -1
  47. package/dist/esm/event-sources/event-source-relationship-guards.js +9 -5
  48. package/dist/esm/event-sources/event-source-relationship-guards.js.map +1 -1
  49. package/dist/esm/event-sources/kinesis-event-source.d.ts +129 -0
  50. package/dist/esm/event-sources/kinesis-event-source.d.ts.map +1 -0
  51. package/dist/esm/event-sources/kinesis-event-source.js +97 -0
  52. package/dist/esm/event-sources/kinesis-event-source.js.map +1 -0
  53. package/dist/esm/event-sources/sqs-event-source.d.ts +2 -2
  54. package/dist/esm/event-sources/sqs-event-source.js +2 -2
  55. package/dist/esm/event-sources/stream-event-source-defaults.d.ts +1 -1
  56. package/dist/esm/event-sources/stream-event-source-defaults.d.ts.map +1 -1
  57. package/dist/esm/event-sources/stream-event-source-defaults.js +3 -1
  58. package/dist/esm/event-sources/stream-event-source-defaults.js.map +1 -1
  59. package/dist/esm/event-sources/stream-event-source.d.ts +32 -0
  60. package/dist/esm/event-sources/stream-event-source.d.ts.map +1 -0
  61. package/dist/esm/event-sources/stream-event-source.js +41 -0
  62. package/dist/esm/event-sources/stream-event-source.js.map +1 -0
  63. package/dist/esm/function-alarms.d.ts.map +1 -1
  64. package/dist/esm/function-alarms.js +7 -3
  65. package/dist/esm/function-alarms.js.map +1 -1
  66. package/dist/esm/index.d.ts +1 -0
  67. package/dist/esm/index.d.ts.map +1 -1
  68. package/dist/esm/index.js +1 -0
  69. package/dist/esm/index.js.map +1 -1
  70. package/package.json +10 -10
package/README.md CHANGED
@@ -174,21 +174,21 @@ Opt back into CDK's auto-created role attached to `AWSLambdaBasicExecutionRole`.
174
174
 
175
175
  The builder creates [AWS-recommended CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#Lambda) by default. No alarm actions are configured — access alarms from the build result to add SNS topics or other actions.
176
176
 
177
- | Alarm | Metric | Default threshold | Created when |
178
- | ------------------------ | --------------------------------- | --------------------------- | -------------------------------------- |
179
- | `errors` | Errors (Sum, 1 min) | > 0 | Always |
180
- | `throttles` | Throttles (Sum, 1 min) | > 0 | Always |
181
- | `duration` | Duration (p99, 1 min) | > 90% of configured timeout | `timeout` is set |
182
- | `concurrentExecutions` | ConcurrentExecutions (Max, 1 min) | >= 80% of reserved limit | `reservedConcurrentExecutions` is set |
183
- | `<key>FailedInvocations` | FailedInvokeEventCount (Sum) | > 0 | An SQS or DynamoDB source is attached |
184
- | `<key>DroppedEvents` | DroppedEventCount (Sum) | > 0 | An SQS or DynamoDB source is attached |
185
- | `iteratorAge` | IteratorAge (Max, 1 min) | > 60000 ms for 3 min¹ | A stream source (DynamoDB) is attached |
177
+ | Alarm | Metric | Default threshold | Created when |
178
+ | ------------------------ | --------------------------------- | --------------------------- | ------------------------------------------------- |
179
+ | `errors` | Errors (Sum, 1 min) | > 0 | Always |
180
+ | `throttles` | Throttles (Sum, 1 min) | > 0 | Always |
181
+ | `duration` | Duration (p99, 1 min) | > 90% of configured timeout | `timeout` is set |
182
+ | `concurrentExecutions` | ConcurrentExecutions (Max, 1 min) | >= 80% of reserved limit | `reservedConcurrentExecutions` is set |
183
+ | `<key>FailedInvocations` | FailedInvokeEventCount (Sum) | > 0 | An SQS, DynamoDB or Kinesis source is attached |
184
+ | `<key>DroppedEvents` | DroppedEventCount (Sum) | > 0 | An SQS, DynamoDB or Kinesis source is attached |
185
+ | `iteratorAge` | IteratorAge (Max, 1 min) | > 60000 ms for 3 min¹ | A stream source (DynamoDB or Kinesis) is attached |
186
186
 
187
187
  ¹ AWS recommends alarming on `IteratorAge` for stream consumers but prescribes no fixed threshold — it is workload dependent. The 60s/3-minute default is deliberately conservative; tune it per workload via `eventSourceIteratorAge`.
188
188
 
189
189
  The per-mapping event-source alarms are contextual: one pair is created per event source attached via `addEventSource` (see [Event sources](#event-sources)) whose kind emits per-mapping ESM metrics. Each alarm's key is the event source's key suffixed with `FailedInvocations` / `DroppedEvents` — e.g. an event source added as `"orders"` produces `ordersFailedInvocations` and `ordersDroppedEvents`. The `eventSourceFailedInvocations` / `eventSourceDroppedEvents` fields on `recommendedAlarms` tune every such alarm.
190
190
 
191
- `iteratorAge` is different: `IteratorAge` is a function-level metric, so a single alarm (keyed `iteratorAge`) is created whenever at least one stream source (currently DynamoDB streams) is attached, regardless of how many. It warns when the consumer falls behind its stream. Tune or disable it via the `eventSourceIteratorAge` field on `recommendedAlarms`.
191
+ `iteratorAge` is different: `IteratorAge` is a function-level metric, so a single alarm (keyed `iteratorAge`) is created whenever at least one stream source (DynamoDB streams or Kinesis, shared-throughput or enhanced fan-out) is attached, regardless of how many. It warns when the consumer falls behind its stream. Tune or disable it via the `eventSourceIteratorAge` field on `recommendedAlarms`.
192
192
 
193
193
  The defaults are exported as `FUNCTION_ALARM_DEFAULTS` for visibility and testing:
194
194
 
@@ -305,7 +305,7 @@ const system = compose(
305
305
 
306
306
  The source is attached _after_ the function and its least-privilege execution
307
307
  role exist, so the `source.bind(fn)` that `addEventSource` performs grants the
308
- consume permission (SQS `ReceiveMessage`, or DynamoDB `grantStreamRead`) onto
308
+ consume permission (SQS `ReceiveMessage`, DynamoDB `grantStreamRead`, or Kinesis `grantRead`) onto
309
309
  the builder's role rather than CDK's auto-role.
310
310
 
311
311
  `dynamoEventSource(table, props?)` mirrors the SQS factory for DynamoDB streams.
@@ -356,7 +356,7 @@ second `props` argument and exported as `DEFAULT_SQS_EVENT_SOURCE_PROPS`:
356
356
 
357
357
  `dynamoEventSource` applies the same defaults plus `startingPosition` and
358
358
  `bisectBatchOnError`, exported as `DEFAULT_DYNAMO_EVENT_SOURCE_PROPS` (the shared
359
- `DEFAULT_STREAM_EVENT_SOURCE_PROPS`, which a future `kinesisEventSource` reuses):
359
+ `DEFAULT_STREAM_EVENT_SOURCE_PROPS`, which the [Kinesis helpers](#kinesis-data-streams) share):
360
360
 
361
361
  | Property | Default | Rationale |
362
362
  | ------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------- |
@@ -404,9 +404,10 @@ way:
404
404
  )
405
405
  ```
406
406
 
407
- An S3 destination on a **DynamoDB stream** mapping needs **aws-cdk-lib ≥ 2.184.0**,
408
- above this package's [floor](../../docs/adr/0008-aws-cdk-lib-version-floors.md) of
409
- 2.168.0. `DynamoEventSource` only opts into S3 destinations from that release;
407
+ An S3 destination on a **DynamoDB stream** (or [Kinesis](#kinesis-data-streams))
408
+ mapping needs **aws-cdk-lib ≥ 2.184.0**, above this package's
409
+ [floor](../../docs/adr/0008-aws-cdk-lib-version-floors.md) of 2.180.0.
410
+ `DynamoEventSource` only opts into S3 destinations from that release;
410
411
  below it CDK rejects the pairing at synth with `S3 onFailure Destination is not
411
412
  supported for this event source`. The limit is CDK's, not this package's — a
412
413
  queue destination works at the floor.
@@ -418,15 +419,122 @@ when dropping is intended — with
418
419
 
419
420
  ### Cross-component invariants
420
421
 
421
- AWS Well-Architected guidance spans the queue and the function — the source
422
- queue's visibility timeout should be ≥ 6× the function timeout, and its redrive
423
- `maxReceiveCount` should be ≥ 5 before the DLQ. These are **not** enforced
424
- today (the queue often arrives as an unresolved `ref()`); they are tracked in
425
- [#123](https://github.com/laazyj/composureCDK/issues/123) and
426
- [#124](https://github.com/laazyj/composureCDK/issues/124).
422
+ AWS Well-Architected guidance spans the queue and the function. Both rules are
423
+ suppressible synth-time warnings:
424
+
425
+ - **Visibility timeout ≥ 6× the function timeout** — a relationship guard in
426
+ this package, checked even when the queue arrives as a `ref()` (see
427
+ [ADR-0011](../../docs/adr/0011-cross-component-relationship-guards.md)). It
428
+ stays quiet for imported queues and token values. Silence it with
429
+ `Annotations.of(scope).acknowledgeWarning(SQS_VISIBILITY_TIMEOUT_WARNING_ID)`.
430
+ - **Redrive `maxReceiveCount` ≥ 5 before the DLQ** — checked by
431
+ `@composurecdk/sqs`'s `QueueBuilder`, so only for queues it builds. See
432
+ [its dead-letter docs](../sqs/README.md#dead-letter-queues-dlq-fifo-dlq) for
433
+ the warning id.
434
+
435
+ ### Kinesis Data Streams
436
+
437
+ `kinesisEventSource(stream, props?)` attaches a Kinesis data stream through
438
+ **shared-throughput** iterators; `kinesisConsumerEventSource(consumer, props?)`
439
+ attaches it through a registered **enhanced fan-out** (EFO) consumer
440
+ (`StreamConsumer`). Both take aws-cdk-lib types — concrete or a `ref()` to a
441
+ sibling's output — and bind with the stream's (or consumer's) `grantRead`,
442
+ which includes `kms:Decrypt` for a customer-managed key.
443
+
444
+ To build the stream and its consumer as composed components, with
445
+ well-architected defaults and recommended alarms, use `createStreamBuilder()`
446
+ and `createStreamConsumerBuilder()` from [`@composurecdk/kinesis`](../kinesis/README.md)
447
+ and pass `ref("stream", (r) => r.stream)` or `ref("consumer", (r) => r.consumer)`.
427
448
 
428
- `kinesisEventSource` is still deferred — see
429
- [#120](https://github.com/laazyj/composureCDK/issues/120).
449
+ ```ts
450
+ import { Duration } from "aws-cdk-lib";
451
+ import { Stream } from "aws-cdk-lib/aws-kinesis";
452
+ import { compose, ref } from "@composurecdk/core";
453
+ import { createFunctionBuilder, kinesisEventSource } from "@composurecdk/lambda";
454
+ import { createQueueBuilder } from "@composurecdk/sqs";
455
+
456
+ const telemetry = new Stream(stack, "Telemetry");
457
+
458
+ compose(
459
+ {
460
+ dlq: createQueueBuilder("dlq"),
461
+ processor: createFunctionBuilder()
462
+ .runtime(Runtime.NODEJS_22_X)
463
+ .handler("index.handler")
464
+ .code(Code.fromAsset("lambda"))
465
+ .addEventSource(
466
+ "telemetry",
467
+ kinesisEventSource(telemetry, {
468
+ retryAttempts: 3,
469
+ maxRecordAge: Duration.hours(1),
470
+ onFailure: ref("dlq", (r) => r.queue),
471
+ }),
472
+ ),
473
+ },
474
+ { dlq: [], processor: ["dlq"] },
475
+ );
476
+ ```
477
+
478
+ Both apply `DEFAULT_KINESIS_EVENT_SOURCE_PROPS` — the same
479
+ `DEFAULT_STREAM_EVENT_SOURCE_PROPS` as `dynamoEventSource`, each overridable via
480
+ `props`:
481
+
482
+ | Property | Default | Rationale |
483
+ | ------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------- |
484
+ | `startingPosition` | `LATEST` | A newly-attached consumer reads from the stream tip instead of replaying the whole retention window. |
485
+ | `reportBatchItemFailures` | `true` | A single poison record fails only its own record, not the whole batch. CDK defaults this `false`. |
486
+ | `bisectBatchOnError` | `true` | Split and retry a failing batch, isolating a poison record instead of blocking the shard. CDK defaults this `false`. |
487
+ | `metricsConfig` | `{ metrics: [EventCount] }` | Enables the per-mapping ESM metrics that back the event-source contextual alarms. |
488
+
489
+ `startingPosition` is optional (CDK's `KinesisEventSourceProps` requires it);
490
+ `AT_TIMESTAMP` also needs `startingPositionTimestamp`. Sources:
491
+ [Lambda Kinesis parameters](https://docs.aws.amazon.com/lambda/latest/dg/services-kinesis-parameters.html),
492
+ [batch item failures](https://docs.aws.amazon.com/lambda/latest/dg/services-kinesis-batchfailurereporting.html).
493
+
494
+ **Failure handling and retention.** Lambda processes each shard in order, so by
495
+ default a failing batch is retried until its records expire — blocking that
496
+ shard for up to the stream's **retention period**: 24 h with CDK's `Stream`
497
+ default, **7 days** with the `@composurecdk/kinesis` default. Bisecting isolates
498
+ the poison record but does not stop it being retried. Bound `retryAttempts`
499
+ and/or `maxRecordAge` **together with** `onFailure`, so a record that never
500
+ succeeds is moved aside and the shard keeps flowing. `onFailure` is widened
501
+ exactly as for `dynamoEventSource` — a queue (wrapped in `SqsDlq`), any
502
+ `IEventSourceDlq` such as `SnsDlq` or `S3OnFailureDestination`, or a `ref()` to
503
+ either — and the [`STREAM_DLQ_WARNING_ID`](#failure-handling-dead-letter-queue)
504
+ warning fires when retries are bounded without one. The bound is not defaulted:
505
+ bounding without a destination would drop records silently. A queue or topic
506
+ destination receives the batch's metadata (shard and sequence-number range),
507
+ not the records — read them back from the stream before they age out. An S3
508
+ destination captures the whole batch, and needs **aws-cdk-lib ≥ 2.184.0**
509
+ (below it CDK rejects it at synth, as for DynamoDB). See
510
+ [on-failure destinations](https://docs.aws.amazon.com/lambda/latest/dg/kinesis-on-failure-destination.html).
511
+
512
+ **Shared throughput or enhanced fan-out.** A shard's 2 MB/s of read throughput
513
+ is shared by every shared-throughput consumer. An EFO consumer gets a dedicated
514
+ 2 MB/s per shard, pushed over HTTP/2 with lower propagation delay, and is
515
+ billed per consumer-shard-hour and per GB retrieved. Use `kinesisEventSource`
516
+ for one or a few consumers; reach for `kinesisConsumerEventSource` when several
517
+ applications read the same stream or latency matters. See
518
+ [enhanced fan-out consumers](https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html).
519
+
520
+ ```ts
521
+ import { StreamConsumer } from "aws-cdk-lib/aws-kinesis";
522
+ import { kinesisConsumerEventSource } from "@composurecdk/lambda";
523
+
524
+ const consumer = new StreamConsumer(stack, "AlertsConsumer", {
525
+ streamConsumerName: "alerts",
526
+ stream: telemetry,
527
+ });
528
+
529
+ createFunctionBuilder()
530
+ // ...
531
+ .addEventSource("alerts", kinesisConsumerEventSource(consumer));
532
+ ```
533
+
534
+ `KinesisConsumerEventSource` arrived in aws-cdk-lib 2.180.0, which sets this
535
+ package's floor. Either helper adds the function-level `iteratorAge` alarm and
536
+ the per-mapping `<key>FailedInvocations` / `<key>DroppedEvents` alarms (see
537
+ [Recommended Alarms](#recommended-alarms)).
430
538
 
431
539
  ## Deploy-time invocation: `.invokeOnDeploy()`
432
540
 
@@ -114,7 +114,7 @@ export interface FunctionAlarmConfig {
114
114
  * Alarm when the function is falling behind a stream event source.
115
115
  *
116
116
  * Contextual: a single alarm is created when at least one stream event
117
- * source (currently DynamoDB streams) is attached via
117
+ * source (DynamoDB streams or Kinesis) is attached via
118
118
  * {@link IFunctionBuilder.addEventSource}. Unlike the per-mapping
119
119
  * {@link FunctionAlarmConfig.eventSourceFailedInvocations} /
120
120
  * {@link FunctionAlarmConfig.eventSourceDroppedEvents} alarms, `IteratorAge`
@@ -9,7 +9,7 @@ import type { Resolvable } from "@composurecdk/core";
9
9
  * straight to {@link IFunctionBuilder.addEventSource} as an escape hatch —
10
10
  * the builder still attaches it, but cannot reason about it.
11
11
  */
12
- export type EventSourceKind = "sqs" | "dynamodb" | "unknown";
12
+ export type EventSourceKind = "sqs" | "dynamodb" | "kinesis" | "unknown";
13
13
  /** @internal — brands {@link ComposureEventSource} so the guard is unambiguous. */
14
14
  declare const COMPOSURE_EVENT_SOURCE: unique symbol;
15
15
  /**
@@ -40,7 +40,7 @@ export declare function composureEventSource(kind: EventSourceKind, source: Reso
40
40
  /**
41
41
  * Reads the event source mapping UUID off a bound CDK source, keyed by
42
42
  * {@link EventSourceKind}. Defined only for kinds whose per-mapping ESM
43
- * metrics back contextual alarms (SQS and DynamoDB streams); `FunctionBuilder`
43
+ * metrics back contextual alarms (SQS, DynamoDB and Kinesis streams); `FunctionBuilder`
44
44
  * invokes the reader after `addEventSource` so the binding exists. Keying off
45
45
  * `kind` — like {@link EVENT_SOURCE_ALARM_SPECS} — keeps the builder from
46
46
  * `instanceof`-ing CDK source classes.
@@ -67,7 +67,7 @@ export interface AttachedEventSource {
67
67
  kind: EventSourceKind;
68
68
  /**
69
69
  * The event source mapping UUID, populated for kinds whose per-mapping
70
- * ESM metrics back contextual alarms (currently SQS only). The contextual
70
+ * ESM metrics back contextual alarms (SQS and the stream kinds). The contextual
71
71
  * alarms key off this dimension.
72
72
  */
73
73
  eventSourceMappingId?: string;
@@ -1 +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,UAAU,GAAG,SAAS,CAAC;AAE7D,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,CAW9C,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"}
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;AAO3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzE,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,CAgB9C,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"}
@@ -12,7 +12,7 @@ function composureEventSource(kind, source) {
12
12
  /**
13
13
  * Reads the event source mapping UUID off a bound CDK source, keyed by
14
14
  * {@link EventSourceKind}. Defined only for kinds whose per-mapping ESM
15
- * metrics back contextual alarms (SQS and DynamoDB streams); `FunctionBuilder`
15
+ * metrics back contextual alarms (SQS, DynamoDB and Kinesis streams); `FunctionBuilder`
16
16
  * invokes the reader after `addEventSource` so the binding exists. Keying off
17
17
  * `kind` — like {@link EVENT_SOURCE_ALARM_SPECS} — keeps the builder from
18
18
  * `instanceof`-ing CDK source classes.
@@ -28,6 +28,10 @@ exports.EVENT_SOURCE_MAPPING_ID_READERS = {
28
28
  // which constructs the `DynamoEventSource` in the same call — kind and
29
29
  // concrete class move in lockstep.
30
30
  dynamodb: (bound) => bound.eventSourceMappingId,
31
+ // Safe: the `"kinesis"` kind is only ever assigned by `kinesisEventSource()`
32
+ // and `kinesisConsumerEventSource()`, which construct the matching CDK
33
+ // source in the same call.
34
+ kinesis: (bound) => bound.eventSourceMappingId,
31
35
  unknown: undefined,
32
36
  };
33
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"composure-event-source.js","sourceRoot":"","sources":["../../../src/event-sources/composure-event-source.ts"],"names":[],"mappings":";;;AA6CA,oDAKC;AA+BD,wDAIC;AAtED,mFAAmF;AACnF,MAAM,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AA4B7E,oEAAoE;AACpE,SAAgB,oBAAoB,CAClC,IAAqB,EACrB,MAAgC;IAEhC,OAAO,EAAE,CAAC,sBAAsB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;;;;;GASG;AACU,QAAA,+BAA+B,GAGxC;IACF,4EAA4E;IAC5E,6EAA6E;IAC7E,oBAAoB;IACpB,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAE,KAAwB,CAAC,oBAAoB;IAC9D,8EAA8E;IAC9E,uEAAuE;IACvE,mCAAmC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAE,KAA2B,CAAC,oBAAoB;IACtE,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF;;;GAGG;AACH,SAAgB,sBAAsB,CACpC,KAA0C;IAE1C,OAAO,sBAAsB,IAAI,KAAK,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"composure-event-source.js","sourceRoot":"","sources":["../../../src/event-sources/composure-event-source.ts"],"names":[],"mappings":";;;AAkDA,oDAKC;AAoCD,wDAIC;AA3ED,mFAAmF;AACnF,MAAM,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AA4B7E,oEAAoE;AACpE,SAAgB,oBAAoB,CAClC,IAAqB,EACrB,MAAgC;IAEhC,OAAO,EAAE,CAAC,sBAAsB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;;;;;GASG;AACU,QAAA,+BAA+B,GAGxC;IACF,4EAA4E;IAC5E,6EAA6E;IAC7E,oBAAoB;IACpB,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAE,KAAwB,CAAC,oBAAoB;IAC9D,8EAA8E;IAC9E,uEAAuE;IACvE,mCAAmC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAE,KAA2B,CAAC,oBAAoB;IACtE,6EAA6E;IAC7E,uEAAuE;IACvE,2BAA2B;IAC3B,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAChB,KAAyD,CAAC,oBAAoB;IACjF,OAAO,EAAE,SAAS;CACnB,CAAC;AAEF;;;GAGG;AACH,SAAgB,sBAAsB,CACpC,KAA0C;IAE1C,OAAO,sBAAsB,IAAI,KAAK,CAAC;AACzC,CAAC"}
@@ -2,8 +2,8 @@ import type { ITable } from "aws-cdk-lib/aws-dynamodb";
2
2
  import type { StartingPosition } from "aws-cdk-lib/aws-lambda";
3
3
  import { type DynamoEventSourceProps } from "aws-cdk-lib/aws-lambda-event-sources";
4
4
  import type { IQueue } from "aws-cdk-lib/aws-sqs";
5
- import { type Resolvable } from "@composurecdk/core";
6
- import { type ComposureEventSource } from "./composure-event-source.js";
5
+ import type { Resolvable } from "@composurecdk/core";
6
+ import type { ComposureEventSource } from "./composure-event-source.js";
7
7
  /**
8
8
  * Secure, AWS-recommended defaults applied to every DynamoDB stream event
9
9
  * source built with {@link dynamoEventSource} — the shared
@@ -1 +1 @@
1
- {"version":3,"file":"dynamodb-event-source.d.ts","sourceRoot":"","sources":["../../../src/event-sources/dynamodb-event-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAEL,KAAK,sBAAsB,EAE5B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,KAAK,oBAAoB,EAAwB,MAAM,6BAA6B,CAAC;AAG9F;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,sKAAoC,CAAC;AAEnF;;;;;;;GAOG;AACH,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,sBAAsB,EACtB,WAAW,GAAG,kBAAkB,CACjC;IACC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CACnF;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EACzB,KAAK,CAAC,EAAE,4BAA4B,GACnC,oBAAoB,CAwBtB"}
1
+ {"version":3,"file":"dynamodb-event-source.d.ts","sourceRoot":"","sources":["../../../src/event-sources/dynamodb-event-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIxE;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,sKAAoC,CAAC;AAEnF;;;;;;;GAOG;AACH,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,sBAAsB,EACtB,WAAW,GAAG,kBAAkB,CACjC;IACC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CACnF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EACzB,KAAK,CAAC,EAAE,4BAA4B,GACnC,oBAAoB,CAOtB"}
@@ -3,8 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DEFAULT_DYNAMO_EVENT_SOURCE_PROPS = void 0;
4
4
  exports.dynamoEventSource = dynamoEventSource;
5
5
  const aws_lambda_event_sources_1 = require("aws-cdk-lib/aws-lambda-event-sources");
6
- const core_1 = require("@composurecdk/core");
7
- const composure_event_source_js_1 = require("./composure-event-source.js");
6
+ const stream_event_source_js_1 = require("./stream-event-source.js");
8
7
  const stream_event_source_defaults_js_1 = require("./stream-event-source-defaults.js");
9
8
  /**
10
9
  * Secure, AWS-recommended defaults applied to every DynamoDB stream event
@@ -14,12 +13,6 @@ const stream_event_source_defaults_js_1 = require("./stream-event-source-default
14
13
  * property can be overridden via the factory's `props` argument.
15
14
  */
16
15
  exports.DEFAULT_DYNAMO_EVENT_SOURCE_PROPS = stream_event_source_defaults_js_1.DEFAULT_STREAM_EVENT_SOURCE_PROPS;
17
- /** Wraps a raw queue in an {@link SqsDlq}; passes an existing destination through. */
18
- function toDlq(destination) {
19
- // Duck-type the queue rather than `instanceof` — the ESM and CommonJS copies
20
- // of a package can both load in one process (ADR-0007).
21
- return "queueArn" in destination ? new aws_lambda_event_sources_1.SqsDlq(destination) : destination;
22
- }
23
16
  /**
24
17
  * Wraps a DynamoDB table's change stream as a Lambda {@link IEventSource},
25
18
  * deferring resolution when the table (or the `onFailure` DLQ) is a `ref()` to
@@ -80,23 +73,6 @@ function toDlq(destination) {
80
73
  * ```
81
74
  */
82
75
  function dynamoEventSource(table, props) {
83
- const { onFailure, ...rest } = props ?? {};
84
- const merged = {
85
- ...exports.DEFAULT_DYNAMO_EVENT_SOURCE_PROPS,
86
- ...rest,
87
- };
88
- let source;
89
- if (onFailure === undefined) {
90
- // No DLQ: only the table can be lazy — preserve the single-ref fast path.
91
- source = (0, core_1.isRef)(table)
92
- ? table.map((resolved) => new aws_lambda_event_sources_1.DynamoEventSource(resolved, merged))
93
- : new aws_lambda_event_sources_1.DynamoEventSource(table, merged);
94
- }
95
- else {
96
- // Table and DLQ are two siblings feeding one source — combine both refs
97
- // (either may be concrete) into a single deferred value (ADR-0015).
98
- source = (0, core_1.combine)({ table, onFailure }, ({ table: resolvedTable, onFailure: resolvedDlq }) => new aws_lambda_event_sources_1.DynamoEventSource(resolvedTable, { ...merged, onFailure: toDlq(resolvedDlq) }));
99
- }
100
- return (0, composure_event_source_js_1.composureEventSource)("dynamodb", source);
76
+ return (0, stream_event_source_js_1.streamEventSource)("dynamodb", table, props, (resolved, merged) => new aws_lambda_event_sources_1.DynamoEventSource(resolved, merged));
101
77
  }
102
78
  //# sourceMappingURL=dynamodb-event-source.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dynamodb-event-source.js","sourceRoot":"","sources":["../../../src/event-sources/dynamodb-event-source.ts"],"names":[],"mappings":";;;AA4HA,8CA2BC;AArJD,mFAI8C;AAE9C,6CAAqE;AACrE,2EAA8F;AAC9F,uFAAsF;AAEtF;;;;;;GAMG;AACU,QAAA,iCAAiC,GAAG,mEAAiC,CAAC;AAqCnF,sFAAsF;AACtF,SAAS,KAAK,CACZ,WAAsE;IAEtE,6EAA6E;IAC7E,wDAAwD;IACxD,OAAO,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,iCAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;AAC3E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,SAAgB,iBAAiB,CAC/B,KAAyB,EACzB,KAAoC;IAEpC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC;IAC3C,MAAM,MAAM,GAA8C;QACxD,GAAG,yCAAiC;QACpC,GAAG,IAAI;KACR,CAAC;IAEF,IAAI,MAAgC,CAAC;IACrC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,0EAA0E;QAC1E,MAAM,GAAG,IAAA,YAAK,EAAC,KAAK,CAAC;YACnB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,4CAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAClE,CAAC,CAAC,IAAI,4CAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,wEAAwE;QACxE,oEAAoE;QACpE,MAAM,GAAG,IAAA,cAAO,EACd,EAAE,KAAK,EAAE,SAAS,EAAE,EACpB,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,EAAE,CACnD,IAAI,4CAAiB,CAAC,aAAa,EAAE,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CACrF,CAAC;IACJ,CAAC;IAED,OAAO,IAAA,gDAAoB,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"dynamodb-event-source.js","sourceRoot":"","sources":["../../../src/event-sources/dynamodb-event-source.ts"],"names":[],"mappings":";;;AAmHA,8CAUC;AA3HD,mFAG8C;AAI9C,qEAA6D;AAC7D,uFAAsF;AAEtF;;;;;;GAMG;AACU,QAAA,iCAAiC,GAAG,mEAAiC,CAAC;AAqCnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,SAAgB,iBAAiB,CAC/B,KAAyB,EACzB,KAAoC;IAEpC,OAAO,IAAA,0CAAiB,EACtB,UAAU,EACV,KAAK,EACL,KAAK,EACL,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,4CAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAC9D,CAAC;AACJ,CAAC"}
@@ -26,8 +26,9 @@ export type EventSourceRelationshipGuard = (fn: LambdaFunction, id: string, key:
26
26
  /**
27
27
  * Per-kind relationship guards, keyed by {@link EventSourceKind}. A kind maps to
28
28
  * the (possibly empty) list of relationships to guard for a source of that kind
29
- * — SQS gains a second entry for the `maxReceiveCount` floor (#124), and a bare
30
- * escape-hatch source attached as `"unknown"` has none.
29
+ * — a bare escape-hatch source attached as `"unknown"` has none. The SQS
30
+ * `maxReceiveCount` floor is not a relationship guard: it concerns the queue
31
+ * alone, so `@composurecdk/sqs`'s `QueueBuilder` checks it.
31
32
  *
32
33
  * @internal
33
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"event-source-relationship-guards.d.ts","sourceRoot":"","sources":["../../../src/event-sources/event-source-relationship-guards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,QAAQ,EAAS,MAAM,aAAa,CAAC;AACtF,OAAO,EAEL,KAAK,QAAQ,IAAI,cAAc,EAC/B,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAIhC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAiBnE;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,gDAAgD,CAAC;AAE/F;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,4CAA4C,CAAC;AAE/E;;;;;;GAMG;AACH,MAAM,MAAM,4BAA4B,GAAG,CACzC,EAAE,EAAE,cAAc,EAClB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,QAAQ,GAAG,SAAS,KAC1B,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC,EAAE,MAAM,CACnD,eAAe,EACf,4BAA4B,EAAE,CAO/B,CAAC"}
1
+ {"version":3,"file":"event-source-relationship-guards.d.ts","sourceRoot":"","sources":["../../../src/event-sources/event-source-relationship-guards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,QAAQ,EAAS,MAAM,aAAa,CAAC;AACtF,OAAO,EAEL,KAAK,QAAQ,IAAI,cAAc,EAC/B,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAIhC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAiBnE;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,gDAAgD,CAAC;AAE/F;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,4CAA4C,CAAC;AAE/E;;;;;;GAMG;AACH,MAAM,MAAM,4BAA4B,GAAG,CACzC,EAAE,EAAE,cAAc,EAClB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,QAAQ,GAAG,SAAS,KAC1B,IAAI,CAAC;AAEV;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,EAAE,MAAM,CACnD,eAAe,EACf,4BAA4B,EAAE,CAQ/B,CAAC"}
@@ -33,16 +33,18 @@ exports.STREAM_DLQ_WARNING_ID = "@composurecdk/lambda:stream-dlq-missing";
33
33
  /**
34
34
  * Per-kind relationship guards, keyed by {@link EventSourceKind}. A kind maps to
35
35
  * the (possibly empty) list of relationships to guard for a source of that kind
36
- * — SQS gains a second entry for the `maxReceiveCount` floor (#124), and a bare
37
- * escape-hatch source attached as `"unknown"` has none.
36
+ * — a bare escape-hatch source attached as `"unknown"` has none. The SQS
37
+ * `maxReceiveCount` floor is not a relationship guard: it concerns the queue
38
+ * alone, so `@composurecdk/sqs`'s `QueueBuilder` checks it.
38
39
  *
39
40
  * @internal
40
41
  */
41
42
  exports.EVENT_SOURCE_RELATIONSHIP_GUARDS = {
42
43
  sqs: [guardSqsVisibilityTimeout],
43
44
  // `guardStreamFailureDestination` is source-agnostic — it reads only the
44
- // mapping's own failure config — so a future `kinesis` kind reuses it as-is.
45
+ // mapping's own failure config — so every stream kind shares it.
45
46
  dynamodb: [guardStreamFailureDestination],
47
+ kinesis: [guardStreamFailureDestination],
46
48
  unknown: [],
47
49
  };
48
50
  /**
@@ -124,7 +126,7 @@ function isFiniteBound(value) {
124
126
  * source does not re-expose them), regardless of build order (ADR-0011).
125
127
  *
126
128
  * Source-agnostic: it inspects only the mapping's own failure config, so it
127
- * applies unchanged to any polling stream kind (DynamoDB now, Kinesis later).
129
+ * applies unchanged to every polling stream kind (DynamoDB and Kinesis).
128
130
  * SQS mappings never set these stream-only properties, so the guard stays
129
131
  * silent even though the Aspect visits them.
130
132
  */
@@ -149,7 +151,9 @@ function guardStreamFailureDestination(fn, id) {
149
151
  `retries/record-age but has no onFailure destination — records that exhaust the bound ` +
150
152
  `are dropped silently. Set onFailure to a dead-letter queue (e.g. the sqs "dlq" queue ` +
151
153
  `builder) or acknowledge "${exports.STREAM_DLQ_WARNING_ID}". ` +
152
- `See https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html#services-ddb-errors`);
154
+ `See https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html#services-ddb-errors ` +
155
+ `(DynamoDB) or https://docs.aws.amazon.com/lambda/latest/dg/kinesis-on-failure-destination.html ` +
156
+ `(Kinesis)`);
153
157
  },
154
158
  });
155
159
  }
@@ -1 +1 @@
1
- {"version":3,"file":"event-source-relationship-guards.js","sourceRoot":"","sources":["../../../src/event-sources/event-source-relationship-guards.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"event-source-relationship-guards.js","sourceRoot":"","sources":["../../../src/event-sources/event-source-relationship-guards.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ import type { IStream, IStreamConsumer } from "aws-cdk-lib/aws-kinesis";
2
+ import type { StartingPosition } from "aws-cdk-lib/aws-lambda";
3
+ import { type KinesisEventSourceProps } from "aws-cdk-lib/aws-lambda-event-sources";
4
+ import type { IQueue } from "aws-cdk-lib/aws-sqs";
5
+ import type { Resolvable } from "@composurecdk/core";
6
+ import type { ComposureEventSource } from "./composure-event-source.js";
7
+ /**
8
+ * Secure, AWS-recommended defaults applied to every Kinesis event source built
9
+ * with {@link kinesisEventSource} or {@link kinesisConsumerEventSource} — the
10
+ * shared {@link DEFAULT_STREAM_EVENT_SOURCE_PROPS} (start at the stream tip,
11
+ * report partial batch failures, bisect a failing batch, emit ESM metrics).
12
+ * Each property can be overridden via the factory's `props` argument.
13
+ *
14
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/services-kinesis-parameters.html
15
+ */
16
+ export declare const DEFAULT_KINESIS_EVENT_SOURCE_PROPS: Pick<import("aws-cdk-lib/aws-lambda-event-sources").StreamEventSourceProps, "reportBatchItemFailures" | "metricsConfig" | "startingPosition" | "bisectBatchOnError">;
17
+ /**
18
+ * Props for {@link kinesisEventSource} and {@link kinesisConsumerEventSource}.
19
+ * Identical to CDK's {@link KinesisEventSourceProps} except that
20
+ * `startingPosition` is optional and `onFailure` is widened to a
21
+ * {@link Resolvable} that additionally accepts a bare {@link IQueue} (or a
22
+ * `ref()` to one), wrapped in an `SqsDlq` for you — so a dead-letter queue
23
+ * built by a sibling component wires up declaratively:
24
+ * `onFailure: ref("dlq", (r) => r.queue)`.
25
+ */
26
+ export interface KinesisStreamEventSourceProps extends Omit<KinesisEventSourceProps, "onFailure" | "startingPosition"> {
27
+ /**
28
+ * Where to start reading the stream. Optional here — unlike CDK's
29
+ * {@link KinesisEventSourceProps} — because
30
+ * {@link DEFAULT_KINESIS_EVENT_SOURCE_PROPS} supplies
31
+ * {@link StartingPosition.LATEST} when omitted. `AT_TIMESTAMP` also needs
32
+ * `startingPositionTimestamp`.
33
+ */
34
+ startingPosition?: StartingPosition;
35
+ /**
36
+ * Destination for records that exhaust `retryAttempts` or exceed
37
+ * `maxRecordAge`. Pass an {@link IQueue} (wrapped in an `SqsDlq`
38
+ * automatically), a concrete destination, or a `ref()` to a sibling that
39
+ * produces either.
40
+ *
41
+ * The destination arm is read from CDK's own prop rather than named as
42
+ * `IEventSourceDlq`, so it keeps tracking that type as CDK moves it
43
+ * (ADR-0018). The `IQueue` arm is the builder's own convenience and has no
44
+ * CDK prop to read from.
45
+ *
46
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/kinesis-on-failure-destination.html
47
+ */
48
+ onFailure?: Resolvable<IQueue | NonNullable<KinesisEventSourceProps["onFailure"]>>;
49
+ }
50
+ /**
51
+ * Wraps a Kinesis data stream as a Lambda {@link IEventSource} using
52
+ * **shared-throughput** (standard) iterators, deferring resolution when the
53
+ * stream (or the `onFailure` destination) is a `ref()` to a sibling
54
+ * component's output.
55
+ *
56
+ * Register the result with {@link IFunctionBuilder.addEventSource}: the
57
+ * builder resolves the `ref()`, attaches the source, and (because
58
+ * `addEventSource` calls `source.bind(fn)`) grants the function's
59
+ * least-privilege execution role permission to read the stream — including
60
+ * `kms:Decrypt` when the stream is encrypted with a customer-managed key.
61
+ *
62
+ * Applies {@link DEFAULT_KINESIS_EVENT_SOURCE_PROPS}; pass `props` to override.
63
+ * For a dedicated 2 MB/s-per-shard read pipe instead of sharing the shard's
64
+ * read throughput with other consumers, use {@link kinesisConsumerEventSource}.
65
+ *
66
+ * ## Failure handling (AWS Well-Architected)
67
+ *
68
+ * By default Lambda retries a failing batch until its records expire from the
69
+ * stream, blocking the shard for up to the stream's retention period (24 h by
70
+ * CDK's default, 7 days with `@composurecdk/kinesis`). `bisectBatchOnError` is
71
+ * on by default to isolate a poison record; for durable failure handling also
72
+ * bound `retryAttempts` / `maxRecordAge` **and** set `onFailure` so exhausted
73
+ * records land in a dead-letter destination instead of being dropped —
74
+ * bounding retries without one triggers a suppressible synth-time warning (see
75
+ * {@link STREAM_DLQ_WARNING_ID}).
76
+ *
77
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/services-kinesis-parameters.html
78
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/services-kinesis-batchfailurereporting.html
79
+ *
80
+ * @param stream - The source stream, concrete or a `ref()` to a sibling.
81
+ * @param props - Overrides for {@link DEFAULT_KINESIS_EVENT_SOURCE_PROPS} and
82
+ * any other {@link KinesisStreamEventSourceProps}.
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * compose(
87
+ * {
88
+ * telemetry: createStreamBuilder(),
89
+ * dlq: createQueueBuilder("dlq"),
90
+ * processor: createFunctionBuilder()
91
+ * .runtime(Runtime.NODEJS_22_X)
92
+ * .handler("index.handler")
93
+ * .code(Code.fromAsset("lambda"))
94
+ * .addEventSource(
95
+ * "telemetry",
96
+ * kinesisEventSource(ref("telemetry", (r) => r.stream), {
97
+ * retryAttempts: 3,
98
+ * onFailure: ref("dlq", (r) => r.queue),
99
+ * }),
100
+ * ),
101
+ * },
102
+ * { telemetry: [], dlq: [], processor: ["telemetry", "dlq"] },
103
+ * );
104
+ * ```
105
+ */
106
+ export declare function kinesisEventSource(stream: Resolvable<IStream>, props?: KinesisStreamEventSourceProps): ComposureEventSource;
107
+ /**
108
+ * Wraps a Kinesis **enhanced fan-out** consumer as a Lambda
109
+ * {@link IEventSource}. Same defaults, `onFailure` handling and `ref()`
110
+ * resolution as {@link kinesisEventSource}; the function reads through the
111
+ * registered consumer, which gets its own 2 MB/s per shard of read
112
+ * throughput pushed over HTTP/2 rather than sharing the shard's 2 MB/s with
113
+ * every other polling consumer.
114
+ *
115
+ * Use it when several applications read the same stream, or when the
116
+ * function needs the lowest propagation delay; enhanced fan-out is billed
117
+ * per consumer-shard-hour and per GB retrieved, so a single consumer is
118
+ * usually cheaper on shared throughput.
119
+ *
120
+ * @see https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html
121
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/services-kinesis-parameters.html
122
+ *
123
+ * @param consumer - The registered stream consumer, concrete or a `ref()` to
124
+ * a sibling.
125
+ * @param props - Overrides for {@link DEFAULT_KINESIS_EVENT_SOURCE_PROPS} and
126
+ * any other {@link KinesisStreamEventSourceProps}.
127
+ */
128
+ export declare function kinesisConsumerEventSource(consumer: Resolvable<IStreamConsumer>, props?: KinesisStreamEventSourceProps): ComposureEventSource;
129
+ //# sourceMappingURL=kinesis-event-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kinesis-event-source.d.ts","sourceRoot":"","sources":["../../../src/event-sources/kinesis-event-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIxE;;;;;;;;GAQG;AACH,eAAO,MAAM,kCAAkC,sKAAoC,CAAC;AAEpF;;;;;;;;GAQG;AACH,MAAM,WAAW,6BAA8B,SAAQ,IAAI,CACzD,uBAAuB,EACvB,WAAW,GAAG,kBAAkB,CACjC;IACC;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CACpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,EAC3B,KAAK,CAAC,EAAE,6BAA6B,GACpC,oBAAoB,CAOtB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,UAAU,CAAC,eAAe,CAAC,EACrC,KAAK,CAAC,EAAE,6BAA6B,GACpC,oBAAoB,CAOtB"}