@composurecdk/sqs 0.8.7 → 0.9.0

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 (94) hide show
  1. package/README.md +99 -13
  2. package/dist/commonjs/dlq-alarm-defaults.d.ts +53 -0
  3. package/dist/commonjs/dlq-alarm-defaults.d.ts.map +1 -0
  4. package/dist/commonjs/dlq-alarm-defaults.js +53 -0
  5. package/dist/commonjs/dlq-alarm-defaults.js.map +1 -0
  6. package/dist/commonjs/dlq-defaults.d.ts +19 -0
  7. package/dist/commonjs/dlq-defaults.d.ts.map +1 -0
  8. package/dist/commonjs/dlq-defaults.js +22 -0
  9. package/dist/commonjs/dlq-defaults.js.map +1 -0
  10. package/dist/commonjs/grants.d.ts +19 -0
  11. package/dist/commonjs/grants.d.ts.map +1 -0
  12. package/dist/commonjs/grants.js +28 -0
  13. package/dist/commonjs/grants.js.map +1 -0
  14. package/dist/commonjs/index.d.ts +6 -1
  15. package/dist/commonjs/index.d.ts.map +1 -1
  16. package/dist/commonjs/index.js +7 -1
  17. package/dist/commonjs/index.js.map +1 -1
  18. package/dist/commonjs/queue-alarm-config.d.ts +47 -11
  19. package/dist/commonjs/queue-alarm-config.d.ts.map +1 -1
  20. package/dist/commonjs/queue-alarm-defaults.d.ts +46 -11
  21. package/dist/commonjs/queue-alarm-defaults.d.ts.map +1 -1
  22. package/dist/commonjs/queue-alarm-defaults.js +11 -5
  23. package/dist/commonjs/queue-alarm-defaults.js.map +1 -1
  24. package/dist/commonjs/queue-alarm-profiles.d.ts +37 -0
  25. package/dist/commonjs/queue-alarm-profiles.d.ts.map +1 -0
  26. package/dist/commonjs/queue-alarm-profiles.js +96 -0
  27. package/dist/commonjs/queue-alarm-profiles.js.map +1 -0
  28. package/dist/commonjs/queue-alarms.d.ts +8 -2
  29. package/dist/commonjs/queue-alarms.d.ts.map +1 -1
  30. package/dist/commonjs/queue-alarms.js +49 -42
  31. package/dist/commonjs/queue-alarms.js.map +1 -1
  32. package/dist/commonjs/queue-builder.d.ts +70 -53
  33. package/dist/commonjs/queue-builder.d.ts.map +1 -1
  34. package/dist/commonjs/queue-builder.js +27 -68
  35. package/dist/commonjs/queue-builder.js.map +1 -1
  36. package/dist/commonjs/queue-props.d.ts +93 -0
  37. package/dist/commonjs/queue-props.d.ts.map +1 -0
  38. package/dist/commonjs/queue-props.js +16 -0
  39. package/dist/commonjs/queue-props.js.map +1 -0
  40. package/dist/commonjs/queue-role.d.ts +28 -0
  41. package/dist/commonjs/queue-role.d.ts.map +1 -0
  42. package/dist/commonjs/queue-role.js +13 -0
  43. package/dist/commonjs/queue-role.js.map +1 -0
  44. package/dist/commonjs/queue-validation.d.ts +12 -0
  45. package/dist/commonjs/queue-validation.d.ts.map +1 -0
  46. package/dist/commonjs/queue-validation.js +142 -0
  47. package/dist/commonjs/queue-validation.js.map +1 -0
  48. package/dist/esm/dlq-alarm-defaults.d.ts +53 -0
  49. package/dist/esm/dlq-alarm-defaults.d.ts.map +1 -0
  50. package/dist/esm/dlq-alarm-defaults.js +50 -0
  51. package/dist/esm/dlq-alarm-defaults.js.map +1 -0
  52. package/dist/esm/dlq-defaults.d.ts +19 -0
  53. package/dist/esm/dlq-defaults.d.ts.map +1 -0
  54. package/dist/esm/dlq-defaults.js +19 -0
  55. package/dist/esm/dlq-defaults.js.map +1 -0
  56. package/dist/esm/grants.d.ts +19 -0
  57. package/dist/esm/grants.d.ts.map +1 -0
  58. package/dist/esm/grants.js +25 -0
  59. package/dist/esm/grants.js.map +1 -0
  60. package/dist/esm/index.d.ts +6 -1
  61. package/dist/esm/index.d.ts.map +1 -1
  62. package/dist/esm/index.js +3 -0
  63. package/dist/esm/index.js.map +1 -1
  64. package/dist/esm/queue-alarm-config.d.ts +47 -11
  65. package/dist/esm/queue-alarm-config.d.ts.map +1 -1
  66. package/dist/esm/queue-alarm-defaults.d.ts +46 -11
  67. package/dist/esm/queue-alarm-defaults.d.ts.map +1 -1
  68. package/dist/esm/queue-alarm-defaults.js +11 -5
  69. package/dist/esm/queue-alarm-defaults.js.map +1 -1
  70. package/dist/esm/queue-alarm-profiles.d.ts +37 -0
  71. package/dist/esm/queue-alarm-profiles.d.ts.map +1 -0
  72. package/dist/esm/queue-alarm-profiles.js +92 -0
  73. package/dist/esm/queue-alarm-profiles.js.map +1 -0
  74. package/dist/esm/queue-alarms.d.ts +8 -2
  75. package/dist/esm/queue-alarms.d.ts.map +1 -1
  76. package/dist/esm/queue-alarms.js +50 -43
  77. package/dist/esm/queue-alarms.js.map +1 -1
  78. package/dist/esm/queue-builder.d.ts +70 -53
  79. package/dist/esm/queue-builder.d.ts.map +1 -1
  80. package/dist/esm/queue-builder.js +27 -68
  81. package/dist/esm/queue-builder.js.map +1 -1
  82. package/dist/esm/queue-props.d.ts +93 -0
  83. package/dist/esm/queue-props.d.ts.map +1 -0
  84. package/dist/esm/queue-props.js +13 -0
  85. package/dist/esm/queue-props.js.map +1 -0
  86. package/dist/esm/queue-role.d.ts +28 -0
  87. package/dist/esm/queue-role.d.ts.map +1 -0
  88. package/dist/esm/queue-role.js +9 -0
  89. package/dist/esm/queue-role.js.map +1 -0
  90. package/dist/esm/queue-validation.d.ts +12 -0
  91. package/dist/esm/queue-validation.d.ts.map +1 -0
  92. package/dist/esm/queue-validation.js +139 -0
  93. package/dist/esm/queue-validation.js.map +1 -0
  94. package/package.json +4 -4
@@ -1,23 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createQueueBuilder = createQueueBuilder;
4
- const aws_cdk_lib_1 = require("aws-cdk-lib");
5
4
  const aws_sqs_1 = require("aws-cdk-lib/aws-sqs");
6
5
  const core_1 = require("@composurecdk/core");
7
6
  const cloudformation_1 = require("@composurecdk/cloudformation");
8
7
  const cloudwatch_1 = require("@composurecdk/cloudwatch");
9
- const queue_alarms_js_1 = require("./queue-alarms.js");
8
+ const queue_role_js_1 = require("./queue-role.js");
10
9
  const defaults_js_1 = require("./defaults.js");
11
- /**
12
- * AWS-recommended minimum for `maxReceiveCount` on an SQS redrive
13
- * policy. A consumer needs a few retries before SQS gives up and
14
- * forwards the message to the dead-letter queue; anything below this
15
- * tends to surface as a flood of "poison" messages from transient
16
- * errors that would have succeeded on retry.
17
- *
18
- * @see https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html
19
- */
20
- const RECOMMENDED_MIN_MAX_RECEIVE_COUNT = 5;
10
+ const dlq_defaults_js_1 = require("./dlq-defaults.js");
11
+ const queue_alarm_profiles_js_1 = require("./queue-alarm-profiles.js");
12
+ const queue_alarms_js_1 = require("./queue-alarms.js");
13
+ const queue_validation_js_1 = require("./queue-validation.js");
21
14
  class QueueBuilder {
22
15
  props = {};
23
16
  #customAlarms = [];
@@ -30,67 +23,33 @@ class QueueBuilder {
30
23
  target.#customAlarms.push(...this.#customAlarms);
31
24
  }
32
25
  build(scope, id) {
33
- const { recommendedAlarms: alarmConfig, ...queueProps } = this.props;
26
+ const { queueRole: role = "standard", ...configured } = this.props;
27
+ const fifo = (0, queue_role_js_1.isFifoRole)(role);
28
+ const dlq = (0, queue_role_js_1.isDlqRole)(role);
34
29
  const mergedProps = {
35
30
  ...defaults_js_1.QUEUE_DEFAULTS,
36
- ...queueProps,
31
+ ...(dlq ? dlq_defaults_js_1.DLQ_QUEUE_DEFAULTS : {}),
32
+ ...configured,
33
+ ...(fifo ? { fifo: true } : {}),
37
34
  };
38
- warnIfLowMaxReceiveCount(scope, id, mergedProps);
39
- const queue = new aws_sqs_1.Queue(scope, id, mergedProps);
40
- const alarms = (0, queue_alarms_js_1.createQueueAlarms)(scope, id, queue, alarmConfig, this.#customAlarms);
35
+ (0, queue_validation_js_1.validateQueueProps)(scope, id, role, mergedProps);
36
+ const { recommendedAlarms, ...queueProps } = mergedProps;
37
+ const queue = new aws_sqs_1.Queue(scope, id, queueProps);
38
+ const profile = dlq
39
+ ? (0, queue_alarm_profiles_js_1.dlqAlarmProfile)(scope, mergedProps.retentionPeriod)
40
+ : queue_alarm_profiles_js_1.PRIMARY_ALARM_PROFILE;
41
+ const alarms = (0, queue_alarms_js_1.createQueueAlarms)(scope, id, queue, recommendedAlarms, this.#customAlarms, profile);
41
42
  return { queue, alarms };
42
43
  }
43
44
  }
44
- /**
45
- * Creates a new {@link IQueueBuilder} for configuring an AWS SQS queue.
46
- *
47
- * This is the entry point for defining an SQS queue component. The returned
48
- * builder exposes every {@link QueueBuilderProps} property as a fluent setter/getter
49
- * and implements {@link Lifecycle} for use with {@link compose}.
50
- *
51
- * @returns A fluent builder for an AWS SQS queue.
52
- *
53
- * @example
54
- * ```ts
55
- * const orders = createQueueBuilder()
56
- * .queueName("orders")
57
- * .visibilityTimeout(Duration.seconds(60));
58
- *
59
- * // Use standalone:
60
- * const result = orders.build(stack, "Orders");
61
- *
62
- * // Or compose into a system:
63
- * const system = compose(
64
- * { orders, alerts: createTopicBuilder() },
65
- * { orders: [], alerts: [] },
66
- * );
67
- * ```
68
- */
69
- function createQueueBuilder() {
70
- return (0, cloudformation_1.taggedBuilder)(QueueBuilder);
71
- }
72
- /**
73
- * Annotates `scope` with a non-fatal warning when a redrive policy is
74
- * configured with `maxReceiveCount` below the AWS-recommended floor
75
- * of {@link RECOMMENDED_MIN_MAX_RECEIVE_COUNT}.
76
- *
77
- * The builder owns the redrive policy directly, so this is a true
78
- * check rather than a contextual reminder — the actual configured
79
- * value is compared. Short-circuits on unresolved tokens so stacks
80
- * that thread `maxReceiveCount` through CFN parameters aren't spammed.
81
- */
82
- function warnIfLowMaxReceiveCount(scope, id, props) {
83
- const dlq = props.deadLetterQueue;
84
- if (!dlq)
85
- return;
86
- const maxReceiveCount = dlq.maxReceiveCount;
87
- if (aws_cdk_lib_1.Token.isUnresolved(maxReceiveCount))
88
- return;
89
- if (maxReceiveCount >= RECOMMENDED_MIN_MAX_RECEIVE_COUNT)
90
- return;
91
- aws_cdk_lib_1.Annotations.of(scope).addWarningV2("@composurecdk/sqs:redrive-low-max-receive-count", `QueueBuilder "${id}": redrive policy maxReceiveCount is ${String(maxReceiveCount)}; ` +
92
- `AWS recommends >= ${String(RECOMMENDED_MIN_MAX_RECEIVE_COUNT)} so the consumer ` +
93
- `has room to retry before messages hit the dead-letter queue. ` +
94
- `See https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html`);
45
+ // Callers only ever see the overloads above, which return the exact
46
+ // per-role `IQueueBuilder<R>`. The `unknown` here types the implementation
47
+ // body alone (the internal builder carries the full prop surface, not the
48
+ // narrowed per-role one) and is never observed at a call site — so it does
49
+ // not weaken the type of a builder passed to `compose`.
50
+ function createQueueBuilder(role = "standard") {
51
+ const builder = (0, cloudformation_1.taggedBuilder)(QueueBuilder);
52
+ builder.queueRole(role);
53
+ return builder;
95
54
  }
96
55
  //# sourceMappingURL=queue-builder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queue-builder.js","sourceRoot":"","sources":["../../src/queue-builder.ts"],"names":[],"mappings":";;AA0JA,gDAEC;AA5JD,6CAAiD;AAEjD,iDAA0E;AAE1E,6CAAgE;AAChE,iEAAkF;AAClF,yDAAkE;AAElE,uDAAsD;AACtD,+CAA+C;AAE/C;;;;;;;;GAQG;AACH,MAAM,iCAAiC,GAAG,CAAC,CAAC;AA0E5C,MAAM,YAAY;IAChB,KAAK,GAA+B,EAAE,CAAC;IAC9B,aAAa,GAAqC,EAAE,CAAC;IAE9D,QAAQ,CACN,GAAW,EACX,SAAoF;QAEpF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,mCAAsB,CAAS,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gCAAgC;IAChC,CAAC,iBAAU,CAAC,CAAC,MAAoB;QAC/B,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,KAAiB,EAAE,EAAU;QACjC,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,GAAG,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAErE,MAAM,WAAW,GAAG;YAClB,GAAG,4BAAc;YACjB,GAAG,UAAU;SACO,CAAC;QAEvB,wBAAwB,CAAC,KAAK,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAEjD,MAAM,KAAK,GAAG,IAAI,eAAK,CAAC,KAAK,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAG,IAAA,mCAAiB,EAAC,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEpF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAgB,kBAAkB;IAChC,OAAO,IAAA,8BAAa,EAAkC,YAAY,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,wBAAwB,CAC/B,KAAiB,EACjB,EAAU,EACV,KAAiC;IAEjC,MAAM,GAAG,GAAG,KAAK,CAAC,eAAe,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,OAAO;IACjB,MAAM,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;IAC5C,IAAI,mBAAK,CAAC,YAAY,CAAC,eAAe,CAAC;QAAE,OAAO;IAChD,IAAI,eAAe,IAAI,iCAAiC;QAAE,OAAO;IACjE,yBAAW,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,CAChC,iDAAiD,EACjD,iBAAiB,EAAE,wCAAwC,MAAM,CAAC,eAAe,CAAC,IAAI;QACpF,qBAAqB,MAAM,CAAC,iCAAiC,CAAC,mBAAmB;QACjF,+DAA+D;QAC/D,gEAAgE,CACnE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"queue-builder.js","sourceRoot":"","sources":["../../src/queue-builder.ts"],"names":[],"mappings":";;AA0LA,gDAIC;AA7LD,iDAA0E;AAE1E,6CAAgE;AAChE,iEAAkF;AAClF,yDAAkE;AAElE,mDAAwE;AACxE,+CAA+C;AAC/C,uDAAuD;AACvD,uEAAmF;AACnF,uDAAsD;AACtD,+DAA2D;AA+E3D,MAAM,YAAY;IAChB,KAAK,GAAuC,EAAE,CAAC;IACtC,aAAa,GAAqC,EAAE,CAAC;IAE9D,QAAQ,CACN,GAAW,EACX,SAAoF;QAEpF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,mCAAsB,CAAS,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gCAAgC;IAChC,CAAC,iBAAU,CAAC,CAAC,MAAoB;QAC/B,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,KAAiB,EAAE,EAAU;QACjC,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,UAAU,EAAE,GAAG,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACnE,MAAM,IAAI,GAAG,IAAA,0BAAU,EAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAA,yBAAS,EAAC,IAAI,CAAC,CAAC;QAE5B,MAAM,WAAW,GAAG;YAClB,GAAG,4BAAc;YACjB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,oCAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,GAAG,UAAU;YACb,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC,CAAC;QAEF,IAAA,wCAAkB,EAAC,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;QAEjD,MAAM,EAAE,iBAAiB,EAAE,GAAG,UAAU,EAAE,GAAG,WAAW,CAAC;QACzD,MAAM,KAAK,GAAG,IAAI,eAAK,CAAC,KAAK,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAG,GAAG;YACjB,CAAC,CAAC,IAAA,yCAAe,EAAC,KAAK,EAAE,WAAW,CAAC,eAAe,CAAC;YACrD,CAAC,CAAC,+CAAqB,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAA,mCAAiB,EAC9B,KAAK,EACL,EAAE,EACF,KAAK,EACL,iBAAiB,EACjB,IAAI,CAAC,aAAa,EAClB,OAAO,CACR,CAAC;QAEF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;CACF;AA0CD,oEAAoE;AACpE,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,wDAAwD;AACxD,SAAgB,kBAAkB,CAAC,OAAkB,UAAU;IAC7D,MAAM,OAAO,GAAG,IAAA,8BAAa,EAA0C,YAAY,CAAC,CAAC;IACpF,OAA8D,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAChF,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,93 @@
1
+ import type { QueueProps } from "aws-cdk-lib/aws-sqs";
2
+ import type { QueueAlarmConfig } from "./queue-alarm-config.js";
3
+ /**
4
+ * A queue name for a FIFO queue. AWS requires the name of a FIFO queue to
5
+ * end in `.fifo`, so the constraint is expressed in the type — a
6
+ * non-conforming literal is a compile error at the call site rather than
7
+ * a synth failure. (Unresolved tokens are not supported as FIFO queue
8
+ * names by the CDK `Queue` construct itself.)
9
+ *
10
+ * @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html
11
+ */
12
+ export type FifoQueueName = `${string}.fifo`;
13
+ /**
14
+ * The {@link QueueProps} keys that only have meaning on a FIFO queue.
15
+ * These are omitted from the standard queue builder's prop surface and
16
+ * guarded at build time, so a queue with FIFO behaviour is always an
17
+ * explicit choice of the FIFO-aware entry points.
18
+ */
19
+ export declare const FIFO_ONLY_PROP_KEYS: readonly ["fifo", "contentBasedDeduplication", "deduplicationScope", "fifoThroughputLimit"];
20
+ /** Union of the FIFO-only {@link QueueProps} keys. */
21
+ export type FifoOnlyPropKey = (typeof FIFO_ONLY_PROP_KEYS)[number];
22
+ /**
23
+ * Builder-only props every queue builder in this package layers on top
24
+ * of the CDK {@link QueueProps}. Defined once so the builders and the
25
+ * shared build core agree on what must be stripped before the props
26
+ * reach the `Queue` construct.
27
+ */
28
+ export interface QueueBuilderExtensionProps {
29
+ /**
30
+ * Configuration for AWS-recommended CloudWatch alarms.
31
+ *
32
+ * By default, the builder creates recommended alarms with sensible
33
+ * thresholds for every applicable metric — which alarms apply depends
34
+ * on the queue's role (primary vs. dead-letter). Individual alarms can
35
+ * be customized or disabled. Set to `false` to disable all alarms.
36
+ *
37
+ * No alarm actions are configured by default since notification
38
+ * methods are user-specific. Access alarms from the build result
39
+ * or use an `afterBuild` hook to apply actions.
40
+ *
41
+ * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#SQS
42
+ */
43
+ recommendedAlarms?: QueueAlarmConfig | false;
44
+ }
45
+ /**
46
+ * Prop surface of `createQueueBuilder()` / `createQueueBuilder("standard")`:
47
+ * every CDK {@link QueueProps} property except the FIFO-only ones — a
48
+ * queue with FIFO behaviour is an explicit role choice
49
+ * (`createQueueBuilder("fifo")`), not a prop.
50
+ */
51
+ export interface QueueBuilderProps extends Omit<QueueProps, FifoOnlyPropKey>, QueueBuilderExtensionProps {
52
+ }
53
+ /**
54
+ * Prop surface of `createQueueBuilder("fifo")`. `fifo` itself is not
55
+ * settable — the role is the switch — and `queueName` is typed as
56
+ * {@link FifoQueueName}, so a name missing the AWS-required `.fifo`
57
+ * suffix is a compile error rather than a synth failure.
58
+ */
59
+ export interface FifoQueueBuilderProps extends Omit<QueueProps, "fifo" | "queueName">, QueueBuilderExtensionProps {
60
+ /**
61
+ * Physical name of the FIFO queue. Must end in `.fifo` (AWS
62
+ * requirement, enforced by the type and validated at build for
63
+ * untyped callers). Omit to let CloudFormation generate a valid name.
64
+ */
65
+ queueName?: FifoQueueName;
66
+ }
67
+ /**
68
+ * Prop surface of `createQueueBuilder("dlq")`: the standard surface (no
69
+ * FIFO-only props — a FIFO dead-letter queue is its own role,
70
+ * `"fifo-dlq"`) minus `deadLetterQueue`, because a dead-letter queue is
71
+ * the terminal destination for failed messages and must not carry its
72
+ * own redrive policy.
73
+ */
74
+ export type DlqQueueBuilderProps = Omit<QueueBuilderProps, "deadLetterQueue">;
75
+ /**
76
+ * Prop surface of `createQueueBuilder("fifo-dlq")`: the FIFO surface
77
+ * (suffix-typed `queueName`, no settable `fifo`) minus
78
+ * `deadLetterQueue`, for the dead-letter queue of a FIFO source — AWS
79
+ * requires it to itself be FIFO.
80
+ */
81
+ export type FifoDlqQueueBuilderProps = Omit<FifoQueueBuilderProps, "deadLetterQueue">;
82
+ /**
83
+ * Maps each {@link QueueRole} to its prop surface. `createQueueBuilder`
84
+ * uses this to give every role an exact fluent API — props that don't
85
+ * apply to a role simply don't exist on its builder type.
86
+ */
87
+ export interface QueueBuilderPropsByRole {
88
+ standard: QueueBuilderProps;
89
+ fifo: FifoQueueBuilderProps;
90
+ dlq: DlqQueueBuilderProps;
91
+ "fifo-dlq": FifoDlqQueueBuilderProps;
92
+ }
93
+ //# sourceMappingURL=queue-props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-props.d.ts","sourceRoot":"","sources":["../../src/queue-props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,GAAG,MAAM,OAAO,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,6FAKkB,CAAC;AAEnD,sDAAsD;AACtD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;;;;;;;;;;;OAaG;IACH,iBAAiB,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;CAC9C;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,EAAE,0BAA0B;CAAG;AAE1E;;;;;GAKG;AACH,MAAM,WAAW,qBACf,SAAQ,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC,EAAE,0BAA0B;IAC1E;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,CAAC;AAEtF;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,GAAG,EAAE,oBAAoB,CAAC;IAC1B,UAAU,EAAE,wBAAwB,CAAC;CACtC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FIFO_ONLY_PROP_KEYS = void 0;
4
+ /**
5
+ * The {@link QueueProps} keys that only have meaning on a FIFO queue.
6
+ * These are omitted from the standard queue builder's prop surface and
7
+ * guarded at build time, so a queue with FIFO behaviour is always an
8
+ * explicit choice of the FIFO-aware entry points.
9
+ */
10
+ exports.FIFO_ONLY_PROP_KEYS = [
11
+ "fifo",
12
+ "contentBasedDeduplication",
13
+ "deduplicationScope",
14
+ "fifoThroughputLimit",
15
+ ];
16
+ //# sourceMappingURL=queue-props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-props.js","sourceRoot":"","sources":["../../src/queue-props.ts"],"names":[],"mappings":";;;AAcA;;;;;GAKG;AACU,QAAA,mBAAmB,GAAG;IACjC,MAAM;IACN,2BAA2B;IAC3B,oBAAoB;IACpB,qBAAqB;CAC2B,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The role a queue plays in its system, chosen at the factory:
3
+ * `createQueueBuilder(role)`. The role selects the builder's prop
4
+ * surface (each role exposes only the props that apply to it), its
5
+ * defaults, its recommended-alarm profile, and its validation:
6
+ *
7
+ * - `"standard"` — a primary, consumer-fed standard queue (the
8
+ * default). FIFO-only props are excluded.
9
+ * - `"fifo"` — a primary FIFO queue: `fifo: true` always, `queueName`
10
+ * typed to require the `.fifo` suffix, high-throughput coherence
11
+ * validated.
12
+ * - `"dlq"` — a standard dead-letter queue: 14-day retention, inverted
13
+ * alarm set (any visible message alerts), no `deadLetterQueue` — a
14
+ * DLQ is a terminal destination.
15
+ * - `"fifo-dlq"` — a FIFO dead-letter queue for a FIFO source (AWS
16
+ * requires the DLQ of a FIFO queue to be FIFO): combines the FIFO
17
+ * surface with the DLQ defaults and alarms.
18
+ *
19
+ * Modeled as data rather than separate factories so that roles compose
20
+ * (`"fifo-dlq"` is a role, not a fourth entry point) and the choice is
21
+ * copy-safe, inspectable state on the builder.
22
+ */
23
+ export type QueueRole = "standard" | "fifo" | "dlq" | "fifo-dlq";
24
+ /** Whether the role builds a FIFO queue. */
25
+ export declare function isFifoRole(role: QueueRole): boolean;
26
+ /** Whether the role builds a dead-letter queue. */
27
+ export declare function isDlqRole(role: QueueRole): boolean;
28
+ //# sourceMappingURL=queue-role.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-role.d.ts","sourceRoot":"","sources":["../../src/queue-role.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;AAEjE,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAEnD;AAED,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAElD"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFifoRole = isFifoRole;
4
+ exports.isDlqRole = isDlqRole;
5
+ /** Whether the role builds a FIFO queue. */
6
+ function isFifoRole(role) {
7
+ return role === "fifo" || role === "fifo-dlq";
8
+ }
9
+ /** Whether the role builds a dead-letter queue. */
10
+ function isDlqRole(role) {
11
+ return role === "dlq" || role === "fifo-dlq";
12
+ }
13
+ //# sourceMappingURL=queue-role.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-role.js","sourceRoot":"","sources":["../../src/queue-role.ts"],"names":[],"mappings":";;AAyBA,gCAEC;AAGD,8BAEC;AARD,4CAA4C;AAC5C,SAAgB,UAAU,CAAC,IAAe;IACxC,OAAO,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU,CAAC;AAChD,CAAC;AAED,mDAAmD;AACnD,SAAgB,SAAS,CAAC,IAAe;IACvC,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { QueueProps } from "aws-cdk-lib/aws-sqs";
2
+ import type { IConstruct } from "constructs";
3
+ import { type QueueRole } from "./queue-role.js";
4
+ /**
5
+ * Runs every build-time check for a queue in the given role against its
6
+ * merged props. This is the single validation entry point — each guard
7
+ * owns its own applicability (self-gating on the role or on the props),
8
+ * so a new role or a new invariant is entirely a change to this module,
9
+ * never new branching in the builder.
10
+ */
11
+ export declare function validateQueueProps(scope: IConstruct, id: string, role: QueueRole, props: Partial<QueueProps>): void;
12
+ //# sourceMappingURL=queue-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-validation.d.ts","sourceRoot":"","sources":["../../src/queue-validation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAExE;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,GACzB,IAAI,CASN"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateQueueProps = validateQueueProps;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_sqs_1 = require("aws-cdk-lib/aws-sqs");
6
+ const queue_props_js_1 = require("./queue-props.js");
7
+ const queue_role_js_1 = require("./queue-role.js");
8
+ /**
9
+ * Runs every build-time check for a queue in the given role against its
10
+ * merged props. This is the single validation entry point — each guard
11
+ * owns its own applicability (self-gating on the role or on the props),
12
+ * so a new role or a new invariant is entirely a change to this module,
13
+ * never new branching in the builder.
14
+ */
15
+ function validateQueueProps(scope, id, role, props) {
16
+ if (!(0, queue_role_js_1.isFifoRole)(role))
17
+ throwIfFifoPropsOnNonFifoRole(id, role, props);
18
+ validateFifoQueueProps(id, props);
19
+ if ((0, queue_role_js_1.isDlqRole)(role)) {
20
+ throwIfRedriveOnDlqRole(id, role, props);
21
+ }
22
+ else {
23
+ throwIfRedriveTargetFifoMismatch(id, (0, queue_role_js_1.isFifoRole)(role), props.deadLetterQueue);
24
+ warnIfLowMaxReceiveCount(scope, id, props);
25
+ }
26
+ }
27
+ /**
28
+ * AWS-recommended minimum for `maxReceiveCount` on an SQS redrive
29
+ * policy. A consumer needs a few retries before SQS gives up and
30
+ * forwards the message to the dead-letter queue; anything below this
31
+ * tends to surface as a flood of "poison" messages from transient
32
+ * errors that would have succeeded on retry.
33
+ *
34
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html
35
+ */
36
+ const RECOMMENDED_MIN_MAX_RECEIVE_COUNT = 5;
37
+ /**
38
+ * Annotates `scope` with a non-fatal warning when a redrive policy is
39
+ * configured with `maxReceiveCount` below the AWS-recommended floor
40
+ * of {@link RECOMMENDED_MIN_MAX_RECEIVE_COUNT}.
41
+ *
42
+ * The builder owns the redrive policy directly, so this is a true
43
+ * check rather than a contextual reminder — the actual configured
44
+ * value is compared. Short-circuits on unresolved tokens so stacks
45
+ * that thread `maxReceiveCount` through CFN parameters aren't spammed.
46
+ */
47
+ function warnIfLowMaxReceiveCount(scope, id, props) {
48
+ const dlq = props.deadLetterQueue;
49
+ if (!dlq)
50
+ return;
51
+ const maxReceiveCount = dlq.maxReceiveCount;
52
+ if (aws_cdk_lib_1.Token.isUnresolved(maxReceiveCount))
53
+ return;
54
+ if (maxReceiveCount >= RECOMMENDED_MIN_MAX_RECEIVE_COUNT)
55
+ return;
56
+ aws_cdk_lib_1.Annotations.of(scope).addWarningV2("@composurecdk/sqs:redrive-low-max-receive-count", `QueueBuilder "${id}": redrive policy maxReceiveCount is ${String(maxReceiveCount)}; ` +
57
+ `AWS recommends >= ${String(RECOMMENDED_MIN_MAX_RECEIVE_COUNT)} so the consumer ` +
58
+ `has room to retry before messages hit the dead-letter queue. ` +
59
+ `See https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html`);
60
+ }
61
+ /**
62
+ * Throws when a FIFO-only prop reaches a non-FIFO role — the role's
63
+ * typed surface omits them, so this catches untyped (JavaScript)
64
+ * callers and points them at the FIFO roles instead of letting the
65
+ * queue synth with primary-queue alarm defaults that don't fit a FIFO
66
+ * queue.
67
+ */
68
+ function throwIfFifoPropsOnNonFifoRole(id, role, props) {
69
+ for (const key of queue_props_js_1.FIFO_ONLY_PROP_KEYS) {
70
+ if (props[key] === undefined)
71
+ continue;
72
+ throw new Error(`QueueBuilder "${id}": "${key}" is FIFO-specific and not supported on role ` +
73
+ `"${role}". Create the builder with ` +
74
+ `createQueueBuilder("${(0, queue_role_js_1.isDlqRole)(role) ? "fifo-dlq" : "fifo"}") instead.`);
75
+ }
76
+ }
77
+ /**
78
+ * Validates the FIFO-specific configuration invariants that would
79
+ * otherwise surface as a synth or deploy failure:
80
+ *
81
+ * - A non-token `queueName` must end in `.fifo` (AWS requirement).
82
+ * - High-throughput mode (`fifoThroughputLimit: PER_MESSAGE_GROUP_ID`)
83
+ * requires `deduplicationScope: MESSAGE_GROUP`.
84
+ *
85
+ * No-op unless `props.fifo` is set (the FIFO roles merge `fifo: true`
86
+ * before calling), so every role calls it unconditionally — the
87
+ * validator owns both the invariants and their applicability.
88
+ *
89
+ * These are configuration errors, not advisory best practice, so they
90
+ * throw (unlike the `maxReceiveCount` warning).
91
+ *
92
+ * @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/high-throughput-fifo.html
93
+ */
94
+ function validateFifoQueueProps(id, props) {
95
+ const { fifo, queueName, fifoThroughputLimit, deduplicationScope } = props;
96
+ if (!fifo)
97
+ return;
98
+ if (queueName !== undefined && !aws_cdk_lib_1.Token.isUnresolved(queueName) && !queueName.endsWith(".fifo")) {
99
+ throw new Error(`QueueBuilder "${id}": FIFO queues require a queueName ending in ".fifo"; ` +
100
+ `got "${queueName}". Omit queueName to let CloudFormation generate one.`);
101
+ }
102
+ if (fifoThroughputLimit === aws_sqs_1.FifoThroughputLimit.PER_MESSAGE_GROUP_ID &&
103
+ deduplicationScope !== aws_sqs_1.DeduplicationScope.MESSAGE_GROUP) {
104
+ throw new Error(`QueueBuilder "${id}": fifoThroughputLimit=PER_MESSAGE_GROUP_ID (high-throughput ` +
105
+ `FIFO) requires deduplicationScope=MESSAGE_GROUP. ` +
106
+ `See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/high-throughput-fifo.html`);
107
+ }
108
+ }
109
+ /**
110
+ * Throws when a queue's redrive target does not match its own FIFO-ness.
111
+ * AWS requires the dead-letter queue of a FIFO queue to be FIFO and the
112
+ * dead-letter queue of a standard queue to be standard; the mismatch
113
+ * otherwise fails at deploy time, after a successful synth.
114
+ *
115
+ * @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html
116
+ */
117
+ function throwIfRedriveTargetFifoMismatch(id, fifo, deadLetterQueue) {
118
+ if (!deadLetterQueue)
119
+ return;
120
+ if (deadLetterQueue.queue.fifo === fifo)
121
+ return;
122
+ const [queueKind, targetKind] = fifo ? ["FIFO", "standard"] : ["standard", "FIFO"];
123
+ throw new Error(`QueueBuilder "${id}": a ${queueKind} queue cannot redrive to the ${targetKind} ` +
124
+ `dead-letter queue "${deadLetterQueue.queue.node.id}" — AWS requires the ` +
125
+ `dead-letter queue to match the source queue's type. ` +
126
+ `See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html`);
127
+ }
128
+ /**
129
+ * Throws when a dead-letter-role queue is given its own
130
+ * `deadLetterQueue` redrive policy — a DLQ is the terminal destination
131
+ * for failed messages; a queue that redrives elsewhere is a primary
132
+ * queue and belongs to the `"standard"` or `"fifo"` role.
133
+ */
134
+ function throwIfRedriveOnDlqRole(id, role, props) {
135
+ if (!props.deadLetterQueue)
136
+ return;
137
+ throw new Error(`QueueBuilder "${id}": deadLetterQueue is not supported on role "${role}" — a ` +
138
+ `dead-letter queue is the terminal destination for failed messages. If this queue ` +
139
+ `needs its own redrive policy it is a primary queue: create the builder with ` +
140
+ `createQueueBuilder("${(0, queue_role_js_1.isFifoRole)(role) ? "fifo" : "standard"}").`);
141
+ }
142
+ //# sourceMappingURL=queue-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-validation.js","sourceRoot":"","sources":["../../src/queue-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
2
+ /**
3
+ * Fraction of a dead-letter queue's `retentionPeriod` at which the
4
+ * `approximateAgeOfOldestMessage` alarm fires by default. Messages older
5
+ * than this have sat unattended for most of their retention window and
6
+ * are approaching silent deletion by SQS — the alarm is the last call to
7
+ * investigate and redrive them.
8
+ */
9
+ export declare const DLQ_AGE_ALARM_RETENTION_RATIO = 0.75;
10
+ /**
11
+ * AWS-recommended default alarm configuration for dead-letter queues
12
+ * built in a dead-letter role (`createQueueBuilder("dlq")` /
13
+ * `createQueueBuilder("fifo-dlq")`).
14
+ *
15
+ * The enabled set inverts relative to a primary queue:
16
+ *
17
+ * - `approximateNumberOfMessagesVisible` (> 0) is **on** — any message
18
+ * on a DLQ indicates a delivery failure that needs investigation.
19
+ * - `approximateAgeOfOldestMessage` is **on**, re-framed: nothing
20
+ * consumes a DLQ, so instead of "consumers falling behind" it fires
21
+ * when the oldest message has used {@link DLQ_AGE_ALARM_RETENTION_RATIO}
22
+ * of the queue's `retentionPeriod` — the threshold below is derived
23
+ * from the default 14-day retention, and the builder scales it to the
24
+ * actual retention period at build time.
25
+ * - `approximateNumberOfMessagesNotVisible` is **off** — nothing is
26
+ * normally in flight on a DLQ. The baseline (shared with
27
+ * {@link QUEUE_ALARM_DEFAULTS} via spread) applies if explicitly
28
+ * re-enabled.
29
+ *
30
+ * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#SQS
31
+ */
32
+ export declare const DLQ_ALARM_DEFAULTS: {
33
+ approximateAgeOfOldestMessage: {
34
+ threshold: number;
35
+ evaluationPeriods: number;
36
+ datapointsToAlarm: number;
37
+ treatMissingData: TreatMissingData.NOT_BREACHING;
38
+ };
39
+ /** 0 — any message on a dead-letter queue is itself the alert. */
40
+ approximateNumberOfMessagesVisible: {
41
+ threshold: number;
42
+ evaluationPeriods: number;
43
+ datapointsToAlarm: number;
44
+ treatMissingData: TreatMissingData.NOT_BREACHING;
45
+ };
46
+ approximateNumberOfMessagesNotVisible: {
47
+ threshold: number;
48
+ evaluationPeriods: number;
49
+ datapointsToAlarm: number;
50
+ treatMissingData: TreatMissingData.NOT_BREACHING;
51
+ };
52
+ };
53
+ //# sourceMappingURL=dlq-alarm-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlq-alarm-defaults.d.ts","sourceRoot":"","sources":["../../src/dlq-alarm-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAK9D;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,kBAAkB;;;;;;;IAU7B,kEAAkE;;;;;;;;;;;;;CAOtC,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
2
+ import { QUEUE_ALARM_DEFAULTS } from "./queue-alarm-defaults.js";
3
+ import { DLQ_QUEUE_DEFAULTS } from "./dlq-defaults.js";
4
+ /**
5
+ * Fraction of a dead-letter queue's `retentionPeriod` at which the
6
+ * `approximateAgeOfOldestMessage` alarm fires by default. Messages older
7
+ * than this have sat unattended for most of their retention window and
8
+ * are approaching silent deletion by SQS — the alarm is the last call to
9
+ * investigate and redrive them.
10
+ */
11
+ export const DLQ_AGE_ALARM_RETENTION_RATIO = 0.75;
12
+ /**
13
+ * AWS-recommended default alarm configuration for dead-letter queues
14
+ * built in a dead-letter role (`createQueueBuilder("dlq")` /
15
+ * `createQueueBuilder("fifo-dlq")`).
16
+ *
17
+ * The enabled set inverts relative to a primary queue:
18
+ *
19
+ * - `approximateNumberOfMessagesVisible` (> 0) is **on** — any message
20
+ * on a DLQ indicates a delivery failure that needs investigation.
21
+ * - `approximateAgeOfOldestMessage` is **on**, re-framed: nothing
22
+ * consumes a DLQ, so instead of "consumers falling behind" it fires
23
+ * when the oldest message has used {@link DLQ_AGE_ALARM_RETENTION_RATIO}
24
+ * of the queue's `retentionPeriod` — the threshold below is derived
25
+ * from the default 14-day retention, and the builder scales it to the
26
+ * actual retention period at build time.
27
+ * - `approximateNumberOfMessagesNotVisible` is **off** — nothing is
28
+ * normally in flight on a DLQ. The baseline (shared with
29
+ * {@link QUEUE_ALARM_DEFAULTS} via spread) applies if explicitly
30
+ * re-enabled.
31
+ *
32
+ * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#SQS
33
+ */
34
+ export const DLQ_ALARM_DEFAULTS = {
35
+ ...QUEUE_ALARM_DEFAULTS,
36
+ approximateAgeOfOldestMessage: {
37
+ threshold: DLQ_QUEUE_DEFAULTS.retentionPeriod.toSeconds() * DLQ_AGE_ALARM_RETENTION_RATIO,
38
+ evaluationPeriods: 1,
39
+ datapointsToAlarm: 1,
40
+ treatMissingData: TreatMissingData.NOT_BREACHING,
41
+ },
42
+ /** 0 — any message on a dead-letter queue is itself the alert. */
43
+ approximateNumberOfMessagesVisible: {
44
+ threshold: 0,
45
+ evaluationPeriods: 1,
46
+ datapointsToAlarm: 1,
47
+ treatMissingData: TreatMissingData.NOT_BREACHING,
48
+ },
49
+ };
50
+ //# sourceMappingURL=dlq-alarm-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlq-alarm-defaults.js","sourceRoot":"","sources":["../../src/dlq-alarm-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,GAAG,oBAAoB;IAEvB,6BAA6B,EAAE;QAC7B,SAAS,EAAE,kBAAkB,CAAC,eAAe,CAAC,SAAS,EAAE,GAAG,6BAA6B;QACzF,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED,kEAAkE;IAClE,kCAAkC,EAAE;QAClC,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;CAC2B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Duration } from "aws-cdk-lib";
2
+ /**
3
+ * AWS-recommended defaults layered on top of {@link QUEUE_DEFAULTS} for
4
+ * queues built in a dead-letter role (`createQueueBuilder("dlq")` /
5
+ * `createQueueBuilder("fifo-dlq")`).
6
+ */
7
+ export declare const DLQ_QUEUE_DEFAULTS: {
8
+ /**
9
+ * 14 days — the SQS maximum. A dead-letter queue exists to give
10
+ * operators a window to investigate and redrive failed messages, so
11
+ * maximizing that window is the point; the 4-day CDK default would let
12
+ * messages expire before anyone notices them. The Well-Architected
13
+ * Reliability Pillar calls for retaining failed messages long enough
14
+ * to analyse and reprocess them.
15
+ * @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html
16
+ */
17
+ retentionPeriod: Duration;
18
+ };
19
+ //# sourceMappingURL=dlq-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlq-defaults.d.ts","sourceRoot":"","sources":["../../src/dlq-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;IAC7B;;;;;;;;OAQG;;CAE0B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Duration } from "aws-cdk-lib";
2
+ /**
3
+ * AWS-recommended defaults layered on top of {@link QUEUE_DEFAULTS} for
4
+ * queues built in a dead-letter role (`createQueueBuilder("dlq")` /
5
+ * `createQueueBuilder("fifo-dlq")`).
6
+ */
7
+ export const DLQ_QUEUE_DEFAULTS = {
8
+ /**
9
+ * 14 days — the SQS maximum. A dead-letter queue exists to give
10
+ * operators a window to investigate and redrive failed messages, so
11
+ * maximizing that window is the point; the 4-day CDK default would let
12
+ * messages expire before anyone notices them. The Well-Architected
13
+ * Reliability Pillar calls for retaining failed messages long enough
14
+ * to analyse and reprocess them.
15
+ * @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html
16
+ */
17
+ retentionPeriod: Duration.days(14),
18
+ };
19
+ //# sourceMappingURL=dlq-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlq-defaults.js","sourceRoot":"","sources":["../../src/dlq-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC;;;;;;;;OAQG;IACH,eAAe,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;CACL,CAAC"}