@composurecdk/cloudfront 0.7.0 → 0.8.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 (92) hide show
  1. package/dist/commonjs/alarm-config.d.ts.map +1 -0
  2. package/dist/commonjs/alarm-config.js +3 -0
  3. package/dist/{alarm-config.js.map → commonjs/alarm-config.js.map} +1 -1
  4. package/dist/commonjs/alarm-defaults.d.ts.map +1 -0
  5. package/dist/commonjs/alarm-defaults.js +65 -0
  6. package/dist/commonjs/alarm-defaults.js.map +1 -0
  7. package/dist/commonjs/behavior-function-alarms.d.ts.map +1 -0
  8. package/dist/commonjs/behavior-function-alarms.js +145 -0
  9. package/dist/commonjs/behavior-function-alarms.js.map +1 -0
  10. package/dist/commonjs/cloudfront-alarm-builder.d.ts.map +1 -0
  11. package/dist/commonjs/cloudfront-alarm-builder.js +141 -0
  12. package/dist/commonjs/cloudfront-alarm-builder.js.map +1 -0
  13. package/dist/commonjs/defaults.d.ts.map +1 -0
  14. package/dist/commonjs/defaults.js +72 -0
  15. package/dist/commonjs/defaults.js.map +1 -0
  16. package/dist/commonjs/distribution-alarms.d.ts.map +1 -0
  17. package/dist/commonjs/distribution-alarms.js +64 -0
  18. package/dist/commonjs/distribution-alarms.js.map +1 -0
  19. package/dist/commonjs/distribution-builder.d.ts.map +1 -0
  20. package/dist/commonjs/distribution-builder.js +191 -0
  21. package/dist/commonjs/distribution-builder.js.map +1 -0
  22. package/dist/commonjs/index.d.ts.map +1 -0
  23. package/dist/commonjs/index.js +14 -0
  24. package/dist/commonjs/index.js.map +1 -0
  25. package/dist/commonjs/package.json +3 -0
  26. package/dist/commonjs/resolve-behaviors.d.ts.map +1 -0
  27. package/dist/commonjs/resolve-behaviors.js +101 -0
  28. package/dist/commonjs/resolve-behaviors.js.map +1 -0
  29. package/dist/esm/alarm-config.d.ts +98 -0
  30. package/dist/esm/alarm-config.d.ts.map +1 -0
  31. package/dist/esm/alarm-config.js.map +1 -0
  32. package/dist/esm/alarm-defaults.d.ts +28 -0
  33. package/dist/esm/alarm-defaults.d.ts.map +1 -0
  34. package/dist/esm/alarm-defaults.js.map +1 -0
  35. package/dist/esm/behavior-function-alarms.d.ts +44 -0
  36. package/dist/esm/behavior-function-alarms.d.ts.map +1 -0
  37. package/dist/esm/behavior-function-alarms.js.map +1 -0
  38. package/dist/esm/cloudfront-alarm-builder.d.ts +136 -0
  39. package/dist/esm/cloudfront-alarm-builder.d.ts.map +1 -0
  40. package/dist/esm/cloudfront-alarm-builder.js.map +1 -0
  41. package/dist/esm/defaults.d.ts +17 -0
  42. package/dist/esm/defaults.d.ts.map +1 -0
  43. package/dist/esm/defaults.js.map +1 -0
  44. package/dist/esm/distribution-alarms.d.ts +9 -0
  45. package/dist/esm/distribution-alarms.d.ts.map +1 -0
  46. package/dist/esm/distribution-alarms.js.map +1 -0
  47. package/dist/esm/distribution-builder.d.ts +345 -0
  48. package/dist/esm/distribution-builder.d.ts.map +1 -0
  49. package/dist/esm/distribution-builder.js.map +1 -0
  50. package/dist/esm/index.d.ts +6 -0
  51. package/dist/esm/index.d.ts.map +1 -0
  52. package/dist/esm/index.js.map +1 -0
  53. package/dist/esm/package.json +3 -0
  54. package/dist/esm/resolve-behaviors.d.ts +56 -0
  55. package/dist/esm/resolve-behaviors.d.ts.map +1 -0
  56. package/dist/esm/resolve-behaviors.js.map +1 -0
  57. package/package.json +36 -18
  58. package/dist/alarm-config.d.ts.map +0 -1
  59. package/dist/alarm-defaults.d.ts.map +0 -1
  60. package/dist/alarm-defaults.js.map +0 -1
  61. package/dist/behavior-function-alarms.d.ts.map +0 -1
  62. package/dist/behavior-function-alarms.js.map +0 -1
  63. package/dist/cloudfront-alarm-builder.d.ts.map +0 -1
  64. package/dist/cloudfront-alarm-builder.js.map +0 -1
  65. package/dist/defaults.d.ts.map +0 -1
  66. package/dist/defaults.js.map +0 -1
  67. package/dist/distribution-alarms.d.ts.map +0 -1
  68. package/dist/distribution-alarms.js.map +0 -1
  69. package/dist/distribution-builder.d.ts.map +0 -1
  70. package/dist/distribution-builder.js.map +0 -1
  71. package/dist/index.d.ts.map +0 -1
  72. package/dist/index.js.map +0 -1
  73. package/dist/resolve-behaviors.d.ts.map +0 -1
  74. package/dist/resolve-behaviors.js.map +0 -1
  75. /package/dist/{alarm-config.d.ts → commonjs/alarm-config.d.ts} +0 -0
  76. /package/dist/{alarm-defaults.d.ts → commonjs/alarm-defaults.d.ts} +0 -0
  77. /package/dist/{behavior-function-alarms.d.ts → commonjs/behavior-function-alarms.d.ts} +0 -0
  78. /package/dist/{cloudfront-alarm-builder.d.ts → commonjs/cloudfront-alarm-builder.d.ts} +0 -0
  79. /package/dist/{defaults.d.ts → commonjs/defaults.d.ts} +0 -0
  80. /package/dist/{distribution-alarms.d.ts → commonjs/distribution-alarms.d.ts} +0 -0
  81. /package/dist/{distribution-builder.d.ts → commonjs/distribution-builder.d.ts} +0 -0
  82. /package/dist/{index.d.ts → commonjs/index.d.ts} +0 -0
  83. /package/dist/{resolve-behaviors.d.ts → commonjs/resolve-behaviors.d.ts} +0 -0
  84. /package/dist/{alarm-config.js → esm/alarm-config.js} +0 -0
  85. /package/dist/{alarm-defaults.js → esm/alarm-defaults.js} +0 -0
  86. /package/dist/{behavior-function-alarms.js → esm/behavior-function-alarms.js} +0 -0
  87. /package/dist/{cloudfront-alarm-builder.js → esm/cloudfront-alarm-builder.js} +0 -0
  88. /package/dist/{defaults.js → esm/defaults.js} +0 -0
  89. /package/dist/{distribution-alarms.js → esm/distribution-alarms.js} +0 -0
  90. /package/dist/{distribution-builder.js → esm/distribution-builder.js} +0 -0
  91. /package/dist/{index.js → esm/index.js} +0 -0
  92. /package/dist/{resolve-behaviors.js → esm/resolve-behaviors.js} +0 -0
@@ -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;;;;;;;;;;GAUG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;CACrC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAEtC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAEvC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;CACjC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=alarm-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alarm-config.js","sourceRoot":"","sources":["../src/alarm-config.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"alarm-config.js","sourceRoot":"","sources":["../../src/alarm-config.ts"],"names":[],"mappings":""}
@@ -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;AAEpE,UAAU,yBAAyB;IACjC,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,mBAAmB,CAAC;IAC/B,aAAa,EAAE,mBAAmB,CAAC;CACpC;AAED,UAAU,qBAAqB;IAC7B,OAAO,EAAE,IAAI,CAAC;IACd,eAAe,EAAE,mBAAmB,CAAC;IACrC,gBAAgB,EAAE,mBAAmB,CAAC;IACtC,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,yBAyBzC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,qBA0BrC,CAAC"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FUNCTION_ALARM_DEFAULTS = exports.DISTRIBUTION_ALARM_DEFAULTS = void 0;
4
+ const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
5
+ /**
6
+ * AWS-recommended default alarm configuration for CloudFront distributions.
7
+ *
8
+ * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
9
+ */
10
+ exports.DISTRIBUTION_ALARM_DEFAULTS = {
11
+ enabled: true,
12
+ /**
13
+ * Elevated 5xx error rate indicates origin or CloudFront issues.
14
+ * Threshold set above 0 to avoid excessive sensitivity from transient errors.
15
+ */
16
+ errorRate: {
17
+ threshold: 5,
18
+ evaluationPeriods: 5,
19
+ datapointsToAlarm: 5,
20
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
21
+ },
22
+ /**
23
+ * Origin taking too long to respond can lead to 504 errors.
24
+ * Default 5000ms threshold provides a reasonable starting point;
25
+ * ideally set to ~80% of your origin response timeout.
26
+ */
27
+ originLatency: {
28
+ threshold: 5000,
29
+ evaluationPeriods: 5,
30
+ datapointsToAlarm: 5,
31
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
32
+ },
33
+ };
34
+ /**
35
+ * Default alarm configuration for CloudFront Functions declared inline on
36
+ * a cache behavior. Any non-zero count of errors or throttles is worth
37
+ * investigating since a function executes on every viewer request/response.
38
+ *
39
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
40
+ */
41
+ exports.FUNCTION_ALARM_DEFAULTS = {
42
+ enabled: true,
43
+ /** Any execution error indicates a runtime fault on the edge; threshold 0. */
44
+ executionErrors: {
45
+ threshold: 0,
46
+ evaluationPeriods: 1,
47
+ datapointsToAlarm: 1,
48
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
49
+ },
50
+ /** Any validation error indicates the function returned a bad event; threshold 0. */
51
+ validationErrors: {
52
+ threshold: 0,
53
+ evaluationPeriods: 1,
54
+ datapointsToAlarm: 1,
55
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
56
+ },
57
+ /** Any throttle indicates the function exceeded its 1ms compute budget; threshold 0. */
58
+ throttles: {
59
+ threshold: 0,
60
+ evaluationPeriods: 1,
61
+ datapointsToAlarm: 1,
62
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
63
+ },
64
+ };
65
+ //# sourceMappingURL=alarm-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alarm-defaults.js","sourceRoot":"","sources":["../../src/alarm-defaults.ts"],"names":[],"mappings":";;;AAAA,+DAA8D;AAgB9D;;;;GAIG;AACU,QAAA,2BAA2B,GAA8B;IACpE,OAAO,EAAE,IAAI;IAEb;;;OAGG;IACH,SAAS,EAAE;QACT,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;KACjD;IAED;;;;OAIG;IACH,aAAa,EAAE;QACb,SAAS,EAAE,IAAI;QACf,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;KACjD;CACF,CAAC;AAEF;;;;;;GAMG;AACU,QAAA,uBAAuB,GAA0B;IAC5D,OAAO,EAAE,IAAI;IAEb,8EAA8E;IAC9E,eAAe,EAAE;QACf,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;KACjD;IAED,qFAAqF;IACrF,gBAAgB,EAAE;QAChB,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;KACjD;IAED,wFAAwF;IACxF,SAAS,EAAE;QACT,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;KACjD;CACF,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavior-function-alarms.d.ts","sourceRoot":"","sources":["../../src/behavior-function-alarms.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,IAAI,UAAU,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AA0B7D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,iBAAiB,GAAG,MAAM,CAKpE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,SAAS,EAAE,iBAAiB,GAC3B,MAAM,CAIR;AAUD;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CACrD,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,SAAS,EAAE,iBAAiB,EAC5B,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,mBAAmB,GAAG,KAAK,GAAG,SAAS,GAC9C,eAAe,EAAE,CA4DnB"}
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pathPatternSlug = pathPatternSlug;
4
+ exports.eventTypePascal = eventTypePascal;
5
+ exports.behaviorFunctionKeyPrefix = behaviorFunctionKeyPrefix;
6
+ exports.resolveBehaviorFunctionAlarmDefinitions = resolveBehaviorFunctionAlarmDefinitions;
7
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
8
+ const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
9
+ const cloudwatch_1 = require("@composurecdk/cloudwatch");
10
+ const alarm_defaults_js_1 = require("./alarm-defaults.js");
11
+ const METRIC_PERIOD = aws_cdk_lib_1.Duration.minutes(1);
12
+ const METRIC_PERIOD_LABEL = `${String(METRIC_PERIOD.toMinutes())} minute`;
13
+ /**
14
+ * CloudFront Function metrics are emitted in the `us-east-1` region only
15
+ * (CloudFront is a global service). Metric dimensions are
16
+ * `FunctionName` + `Region=Global`.
17
+ *
18
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
19
+ */
20
+ function functionMetric(fn, metricName) {
21
+ return new aws_cloudwatch_1.Metric({
22
+ namespace: "AWS/CloudFront",
23
+ metricName,
24
+ dimensionsMap: {
25
+ FunctionName: fn.functionName,
26
+ Region: "Global",
27
+ },
28
+ statistic: aws_cloudwatch_1.Stats.SUM,
29
+ period: METRIC_PERIOD,
30
+ });
31
+ }
32
+ /**
33
+ * Converts a CloudFront cache-behavior path pattern into a PascalCase slug
34
+ * suitable for alarm keys and CDK construct ids. A single leading `/` is
35
+ * dropped (the common case), interior `/` becomes `Slash` so sibling patterns
36
+ * don't collide, `*` becomes `Star`, and `?` becomes `Q`. Other
37
+ * non-alphanumeric characters are stripped.
38
+ *
39
+ * Examples:
40
+ * - `/api/*` → `ApiSlashStar`
41
+ * - `/api*` → `ApiStar` (distinct from `/api/*`)
42
+ * - `*.html` → `StarHtml`
43
+ * - `images/*` → `ImagesSlashStar`
44
+ *
45
+ * @internal
46
+ */
47
+ function pathPatternSlug(pattern) {
48
+ const stripped = pattern.startsWith("/") ? pattern.slice(1) : pattern;
49
+ return stripped
50
+ .replace(/\//g, " Slash ")
51
+ .replace(/\*/g, " Star ")
52
+ .replace(/\?/g, " Q ")
53
+ .split(/[^A-Za-z0-9]+/)
54
+ .filter(Boolean)
55
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
56
+ .join("");
57
+ }
58
+ /**
59
+ * Converts a {@link FunctionEventType} value (e.g. `"viewer-request"`) into
60
+ * PascalCase (e.g. `"ViewerRequest"`) for use in alarm keys and construct ids.
61
+ *
62
+ * @internal
63
+ */
64
+ function eventTypePascal(eventType) {
65
+ return eventType
66
+ .split("-")
67
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
68
+ .join("");
69
+ }
70
+ /**
71
+ * Builds the prefix used for every alarm key produced for a given inline
72
+ * function — e.g. `defaultBehaviorViewerRequest` or `behaviorApiStarViewerRequest`.
73
+ * Pass `null` for the default behavior.
74
+ *
75
+ * @internal
76
+ */
77
+ function behaviorFunctionKeyPrefix(pathPattern, eventType) {
78
+ const scope = pathPattern === null ? "defaultBehavior" : `behavior${pathPatternSlug(pathPattern)}`;
79
+ return `${scope}${eventTypePascal(eventType)}`;
80
+ }
81
+ function behaviorFunctionScopeLabel(pathPattern, eventType) {
82
+ const scope = pathPattern === null ? "default behavior" : `behavior "${pathPattern}"`;
83
+ return `${scope} (${eventType})`;
84
+ }
85
+ /**
86
+ * Produces fully-resolved {@link AlarmDefinition}s for the three AWS-recommended
87
+ * CloudFront Function alarms — execution errors, validation errors, throttles —
88
+ * scoped to a single behavior + event type so the keys and descriptions stay
89
+ * actionable when the same underlying function is used on multiple behaviors.
90
+ *
91
+ * @internal
92
+ */
93
+ function resolveBehaviorFunctionAlarmDefinitions(pathPattern, eventType, fn, config) {
94
+ if (config === false)
95
+ return [];
96
+ if (config?.enabled === false)
97
+ return [];
98
+ const keyPrefix = behaviorFunctionKeyPrefix(pathPattern, eventType);
99
+ const scopeLabel = behaviorFunctionScopeLabel(pathPattern, eventType);
100
+ const definitions = [];
101
+ if (config?.executionErrors !== false) {
102
+ const cfg = (0, cloudwatch_1.resolveAlarmConfig)(config?.executionErrors, alarm_defaults_js_1.FUNCTION_ALARM_DEFAULTS.executionErrors);
103
+ definitions.push({
104
+ key: `${keyPrefix}ExecutionErrors`,
105
+ alarmName: cfg.alarmName,
106
+ metric: functionMetric(fn, "FunctionExecutionErrors"),
107
+ threshold: cfg.threshold,
108
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
109
+ evaluationPeriods: cfg.evaluationPeriods,
110
+ datapointsToAlarm: cfg.datapointsToAlarm,
111
+ treatMissingData: cfg.treatMissingData,
112
+ description: `CloudFront Function on ${scopeLabel} is raising execution errors. Threshold: > ${String(cfg.threshold)} errors in ${METRIC_PERIOD_LABEL}.`,
113
+ });
114
+ }
115
+ if (config?.validationErrors !== false) {
116
+ const cfg = (0, cloudwatch_1.resolveAlarmConfig)(config?.validationErrors, alarm_defaults_js_1.FUNCTION_ALARM_DEFAULTS.validationErrors);
117
+ definitions.push({
118
+ key: `${keyPrefix}ValidationErrors`,
119
+ alarmName: cfg.alarmName,
120
+ metric: functionMetric(fn, "FunctionValidationErrors"),
121
+ threshold: cfg.threshold,
122
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
123
+ evaluationPeriods: cfg.evaluationPeriods,
124
+ datapointsToAlarm: cfg.datapointsToAlarm,
125
+ treatMissingData: cfg.treatMissingData,
126
+ description: `CloudFront Function on ${scopeLabel} is producing validation errors. Threshold: > ${String(cfg.threshold)} errors in ${METRIC_PERIOD_LABEL}.`,
127
+ });
128
+ }
129
+ if (config?.throttles !== false) {
130
+ const cfg = (0, cloudwatch_1.resolveAlarmConfig)(config?.throttles, alarm_defaults_js_1.FUNCTION_ALARM_DEFAULTS.throttles);
131
+ definitions.push({
132
+ key: `${keyPrefix}Throttles`,
133
+ alarmName: cfg.alarmName,
134
+ metric: functionMetric(fn, "FunctionThrottles"),
135
+ threshold: cfg.threshold,
136
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
137
+ evaluationPeriods: cfg.evaluationPeriods,
138
+ datapointsToAlarm: cfg.datapointsToAlarm,
139
+ treatMissingData: cfg.treatMissingData,
140
+ description: `CloudFront Function on ${scopeLabel} is being throttled — likely exceeding its 1ms compute budget. Threshold: > ${String(cfg.threshold)} throttles in ${METRIC_PERIOD_LABEL}.`,
141
+ });
142
+ }
143
+ return definitions;
144
+ }
145
+ //# sourceMappingURL=behavior-function-alarms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavior-function-alarms.js","sourceRoot":"","sources":["../../src/behavior-function-alarms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudfront-alarm-builder.d.ts","sourceRoot":"","sources":["../../src/cloudfront-alarm-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAW,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,KAAK,cAAc,EAAiB,MAAM,8BAA8B,CAAC;AAElF,OAAO,EAAE,sBAAsB,EAAgB,MAAM,0BAA0B,CAAC;AAChF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;;;;;;GAQG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;;;;;;;;;;;;;;OAgBG;IACH,iBAAiB,CAAC,EAAE,uBAAuB,GAAG,KAAK,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAClD,2BAA2B,EAC3B,sBAAsB,CACvB,CAAC;AAsBF;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,IAAI,CAAC,yBAAyB,EAAE,cAAc,GAAG,WAAW,CAAC,EACrE,OAAO,GAAE;IACP,iBAAiB,CAAC,EAAE,uBAAuB,GAAG,KAAK,CAAC;IACpD,YAAY,CAAC,EAAE,sBAAsB,CAAC,YAAY,CAAC,EAAE,CAAC;CAClD,GACL,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAyBvB;AAED,cAAM,sBAAuB,YAAW,SAAS,CAAC,4BAA4B,CAAC;;IAC7E,KAAK,EAAE,OAAO,CAAC,2BAA2B,CAAC,CAAM;IAIjD;;;;;;;;;OASG;IACH,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,yBAAyB,CAAC,GAAG,IAAI;IAKvE;;;;;;;;OAQG;IACH,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CACT,KAAK,EAAE,sBAAsB,CAAC,YAAY,CAAC,KACxC,sBAAsB,CAAC,YAAY,CAAC,GACxC,IAAI;IAKP,gCAAgC;IAChC,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI;IAKlD,KAAK,CACH,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,4BAA4B;CAehC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,4BAA4B,IAAI,uBAAuB,CAEtE"}
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildCloudFrontAlarms = buildCloudFrontAlarms;
4
+ exports.createCloudFrontAlarmBuilder = createCloudFrontAlarmBuilder;
5
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
6
+ const core_1 = require("@composurecdk/core");
7
+ const cloudformation_1 = require("@composurecdk/cloudformation");
8
+ const cloudwatch_1 = require("@composurecdk/cloudwatch");
9
+ const distribution_alarms_js_1 = require("./distribution-alarms.js");
10
+ const behavior_function_alarms_js_1 = require("./behavior-function-alarms.js");
11
+ /**
12
+ * CloudFront metrics are emitted in `us-east-1` only. CloudWatch alarms are
13
+ * regional, so alarms created in any other region will never receive data.
14
+ * Warn (don't error) when alarms are being created outside `us-east-1`,
15
+ * unless the region is an unresolved token (env-agnostic stack — user knows
16
+ * best).
17
+ */
18
+ function warnIfNotUsEast1(scope) {
19
+ const region = aws_cdk_lib_1.Stack.of(scope).region;
20
+ if (aws_cdk_lib_1.Token.isUnresolved(region))
21
+ return;
22
+ if (region === "us-east-1")
23
+ return;
24
+ aws_cdk_lib_1.Annotations.of(scope).addWarningV2("@composurecdk/cloudfront:alarm-region", `CloudFront metrics are emitted in us-east-1 only, but this stack is deployed ` +
25
+ `in "${region}". CloudWatch alarms created here will not fire. Deploy the ` +
26
+ `stack in us-east-1, or use createCloudFrontAlarmBuilder() routed to a ` +
27
+ `us-east-1 stack via compose().withStacks().`);
28
+ }
29
+ /**
30
+ * Shared alarm-assembly used by both {@link createDistributionBuilder} (in its
31
+ * own stack) and {@link createCloudFrontAlarmBuilder} (typically in a separate
32
+ * `us-east-1` stack). Materializes the recommended distribution-level alarms,
33
+ * the recommended per-function alarms, and any user-supplied custom alarms,
34
+ * emits the region warning if the resulting scope is not in `us-east-1`, and
35
+ * creates the alarm constructs.
36
+ *
37
+ * @internal
38
+ */
39
+ function buildCloudFrontAlarms(scope, id, target, options = {}) {
40
+ const recommended = options.recommendedAlarms;
41
+ const recommendedDefs = recommended === false || recommended?.enabled === false
42
+ ? []
43
+ : [
44
+ ...(0, distribution_alarms_js_1.resolveDistributionAlarmDefinitions)(target.distribution, recommended),
45
+ ...Object.values(target.functions).flatMap((entry) => (0, behavior_function_alarms_js_1.resolveBehaviorFunctionAlarmDefinitions)(entry.pathPattern, entry.eventType, entry.function, entry.recommendedAlarms)),
46
+ ];
47
+ const customAlarmDefs = options.customAlarms?.map((b) => b.resolve(target.distribution)) ?? [];
48
+ const allAlarmDefs = [...recommendedDefs, ...customAlarmDefs];
49
+ if (allAlarmDefs.length > 0) {
50
+ warnIfNotUsEast1(scope);
51
+ }
52
+ return (0, cloudwatch_1.createAlarms)(scope, id, allAlarmDefs);
53
+ }
54
+ class CloudFrontAlarmBuilder {
55
+ props = {};
56
+ #distribution;
57
+ #customAlarms = [];
58
+ /**
59
+ * Sets the distribution to alarm on. Pass the result of
60
+ * {@link createDistributionBuilder} (or a {@link Ref} to it). The builder
61
+ * reads the distribution and any inline-function metadata from the result.
62
+ *
63
+ * Pair with `compose().withStacks()` to route this component into a
64
+ * `us-east-1` stack while the distribution itself lives elsewhere — set
65
+ * `crossRegionReferences: true` on both stacks so CDK can wire the
66
+ * `DistributionId` reference automatically.
67
+ */
68
+ distribution(distribution) {
69
+ this.#distribution = distribution;
70
+ return this;
71
+ }
72
+ /**
73
+ * Adds a custom alarm against the distribution. The configure callback
74
+ * receives a fresh {@link AlarmDefinitionBuilder} pre-set with the alarm's
75
+ * key; configure metric, threshold, comparison and any other options.
76
+ *
77
+ * The created alarm is materialized in this builder's stack — useful for
78
+ * cross-region setups where you want all CloudFront alarms to live with the
79
+ * recommended ones.
80
+ */
81
+ addAlarm(key, configure) {
82
+ this.#customAlarms.push(configure(new cloudwatch_1.AlarmDefinitionBuilder(key)));
83
+ return this;
84
+ }
85
+ /** @internal — see ADR-0005. */
86
+ [core_1.COPY_STATE](target) {
87
+ target.#distribution = this.#distribution;
88
+ target.#customAlarms.push(...this.#customAlarms);
89
+ }
90
+ build(scope, id, context) {
91
+ if (!this.#distribution) {
92
+ throw new Error(`CloudFrontAlarmBuilder "${id}" requires a distribution. ` +
93
+ `Call .distribution() with a DistributionBuilderResult or a Ref to one.`);
94
+ }
95
+ const distribution = (0, core_1.resolve)(this.#distribution, context ?? {});
96
+ return {
97
+ alarms: buildCloudFrontAlarms(scope, id, distribution, {
98
+ recommendedAlarms: this.props.recommendedAlarms,
99
+ customAlarms: this.#customAlarms,
100
+ }),
101
+ };
102
+ }
103
+ }
104
+ /**
105
+ * Creates a new {@link ICloudFrontAlarmBuilder} for materializing CloudFront
106
+ * alarms in a stack separate from the distribution itself.
107
+ *
108
+ * The recommended use is multi-region deployments: the distribution lives in
109
+ * the site's stack (often outside `us-east-1` for latency or compliance
110
+ * reasons), and CloudFront alarms must live in a `us-east-1` stack so they
111
+ * can read the metrics CloudFront emits there.
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * compose(
116
+ * {
117
+ * cdn: createDistributionBuilder()
118
+ * .origin(...)
119
+ * .defaultBehavior({ functions: [{ eventType, code }] })
120
+ * .recommendedAlarms(false), // suppress alarms in the dist's own stack
121
+ *
122
+ * cdnAlarms: createCloudFrontAlarmBuilder()
123
+ * .distribution(ref<DistributionBuilderResult>("cdn"))
124
+ * .recommendedAlarms({ errorRate: { threshold: 2 } }),
125
+ * },
126
+ * { cdn: [], cdnAlarms: ["cdn"] },
127
+ * )
128
+ * .withStacks({
129
+ * cdn: siteStack, // eu-west-2
130
+ * cdnAlarms: certStack, // us-east-1 (existing ACM stack)
131
+ * })
132
+ * .build(app, "App");
133
+ * ```
134
+ *
135
+ * Set `crossRegionReferences: true` on both stacks so CDK can export the
136
+ * `DistributionId` from the site stack and import it in the alarm stack.
137
+ */
138
+ function createCloudFrontAlarmBuilder() {
139
+ return (0, cloudformation_1.taggedBuilder)(CloudFrontAlarmBuilder);
140
+ }
141
+ //# sourceMappingURL=cloudfront-alarm-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudfront-alarm-builder.js","sourceRoot":"","sources":["../../src/cloudfront-alarm-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAEpG;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,OAAO,CAAC,wBAAwB,CAmDnE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,OAAO,CAAC,wBAAwB,CAOtE,CAAC"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INLINE_FUNCTION_DEFAULTS = exports.DISTRIBUTION_DEFAULTS = void 0;
4
+ const aws_cloudfront_1 = require("aws-cdk-lib/aws-cloudfront");
5
+ /**
6
+ * Secure, AWS-recommended defaults applied to every CloudFront distribution
7
+ * built with {@link createDistributionBuilder}. Each property can be individually
8
+ * overridden via the builder's fluent API.
9
+ *
10
+ * The `defaultBehavior` defaults (viewer protocol policy, response headers
11
+ * policy) are deep-merged with user-provided behavior options in `build()`,
12
+ * then the resolved origin is injected.
13
+ */
14
+ exports.DISTRIBUTION_DEFAULTS = {
15
+ /**
16
+ * Auto-create a dedicated logging bucket and write CloudFront standard
17
+ * access logs to it under the `logs/` prefix. Access logging provides an
18
+ * audit trail of all viewer requests for security monitoring and
19
+ * troubleshooting.
20
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_detect_investigate_events_app_service_logging.html
21
+ */
22
+ accessLogs: { prefix: "logs/" },
23
+ /**
24
+ * Use the cheapest price class — edge locations in North America and Europe.
25
+ * Sufficient for most small websites and avoids costs from global edge locations.
26
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PriceClass.html
27
+ */
28
+ priceClass: aws_cloudfront_1.PriceClass.PRICE_CLASS_100,
29
+ /**
30
+ * Enable HTTP/2 and HTTP/3 (QUIC) for improved performance. HTTP/3 is
31
+ * backwards-compatible — viewers that don't support it fall back to HTTP/2.
32
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesSupportedHTTPVersions
33
+ */
34
+ httpVersion: aws_cloudfront_1.HttpVersion.HTTP2_AND_3,
35
+ /**
36
+ * Serve index.html for the root path.
37
+ * Standard for static website hosting.
38
+ */
39
+ defaultRootObject: "index.html",
40
+ /**
41
+ * Require TLS 1.2 (2021 policy) as the minimum protocol version.
42
+ * Prevents negotiation of older, less secure TLS versions.
43
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/protecting-data-in-transit.html
44
+ */
45
+ minimumProtocolVersion: aws_cloudfront_1.SecurityPolicyProtocol.TLS_V1_2_2021,
46
+ defaultBehavior: {
47
+ /**
48
+ * Redirect HTTP to HTTPS — ensures all viewer traffic is encrypted in transit.
49
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/protecting-data-in-transit.html
50
+ */
51
+ viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
52
+ /**
53
+ * Apply the managed security headers policy (HSTS, X-Content-Type-Options,
54
+ * X-Frame-Options, etc.).
55
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-response-headers-policies.html
56
+ */
57
+ responseHeadersPolicy: aws_cloudfront_1.ResponseHeadersPolicy.SECURITY_HEADERS,
58
+ },
59
+ };
60
+ /**
61
+ * Defaults applied to every inline CloudFront Function declared on a cache
62
+ * behavior. User-provided properties take precedence.
63
+ */
64
+ exports.INLINE_FUNCTION_DEFAULTS = {
65
+ /**
66
+ * Use the `cloudfront-js-2.0` runtime by default. It is a superset of
67
+ * `cloudfront-js-1.0` (async/await, `crypto.subtle`, KeyValueStore support).
68
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/functions-javascript-runtime-20.html
69
+ */
70
+ runtime: aws_cloudfront_1.FunctionRuntime.JS_2_0,
71
+ };
72
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/defaults.ts"],"names":[],"mappings":";;;AAAA,+DAOoC;AAGpC;;;;;;;;GAQG;AACU,QAAA,qBAAqB,GAAsC;IACtE;;;;;;OAMG;IACH,UAAU,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;IAE/B;;;;OAIG;IACH,UAAU,EAAE,2BAAU,CAAC,eAAe;IAEtC;;;;OAIG;IACH,WAAW,EAAE,4BAAW,CAAC,WAAW;IAEpC;;;OAGG;IACH,iBAAiB,EAAE,YAAY;IAE/B;;;;OAIG;IACH,sBAAsB,EAAE,uCAAsB,CAAC,aAAa;IAE5D,eAAe,EAAE;QACf;;;WAGG;QACH,oBAAoB,EAAE,qCAAoB,CAAC,iBAAiB;QAE5D;;;;WAIG;QACH,qBAAqB,EAAE,sCAAqB,CAAC,gBAAgB;KAC9D;CACF,CAAC;AAEF;;;GAGG;AACU,QAAA,wBAAwB,GAAsC;IACzE;;;;OAIG;IACH,OAAO,EAAE,gCAAe,CAAC,MAAM;CAChC,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribution-alarms.d.ts","sourceRoot":"","sources":["../../src/distribution-alarms.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AA2BjE;;;GAGG;AACH,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,uBAAuB,GAAG,SAAS,GAC1C,eAAe,EAAE,CAuCnB"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveDistributionAlarmDefinitions = resolveDistributionAlarmDefinitions;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
6
+ const cloudwatch_1 = require("@composurecdk/cloudwatch");
7
+ const alarm_defaults_js_1 = require("./alarm-defaults.js");
8
+ const METRIC_PERIOD = aws_cdk_lib_1.Duration.minutes(1);
9
+ const METRIC_PERIOD_LABEL = `${String(METRIC_PERIOD.toMinutes())} minute`;
10
+ /**
11
+ * Creates a CloudFront distribution metric with the correct namespace and
12
+ * dimensions (DistributionId + Region=Global).
13
+ */
14
+ function distributionMetric(distribution, metricName, statistic) {
15
+ return new aws_cloudwatch_1.Metric({
16
+ namespace: "AWS/CloudFront",
17
+ metricName,
18
+ dimensionsMap: {
19
+ DistributionId: distribution.distributionId,
20
+ Region: "Global",
21
+ },
22
+ statistic,
23
+ period: METRIC_PERIOD,
24
+ });
25
+ }
26
+ /**
27
+ * Resolves the recommended alarm configuration into fully-resolved
28
+ * {@link AlarmDefinition}s for a CloudFront distribution.
29
+ */
30
+ function resolveDistributionAlarmDefinitions(distribution, config) {
31
+ if (config?.enabled === false)
32
+ return [];
33
+ const definitions = [];
34
+ if (config?.errorRate !== false) {
35
+ const cfg = (0, cloudwatch_1.resolveAlarmConfig)(config?.errorRate, alarm_defaults_js_1.DISTRIBUTION_ALARM_DEFAULTS.errorRate);
36
+ definitions.push({
37
+ key: "errorRate",
38
+ alarmName: cfg.alarmName,
39
+ metric: distributionMetric(distribution, "5xxErrorRate", aws_cloudwatch_1.Stats.AVERAGE),
40
+ threshold: cfg.threshold,
41
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
42
+ evaluationPeriods: cfg.evaluationPeriods,
43
+ datapointsToAlarm: cfg.datapointsToAlarm,
44
+ treatMissingData: cfg.treatMissingData,
45
+ description: `CloudFront distribution 5xx error rate is elevated. Threshold: > ${String(cfg.threshold)}% in ${METRIC_PERIOD_LABEL}.`,
46
+ });
47
+ }
48
+ if (config?.originLatency !== false) {
49
+ const cfg = (0, cloudwatch_1.resolveAlarmConfig)(config?.originLatency, alarm_defaults_js_1.DISTRIBUTION_ALARM_DEFAULTS.originLatency);
50
+ definitions.push({
51
+ key: "originLatency",
52
+ alarmName: cfg.alarmName,
53
+ metric: distributionMetric(distribution, "OriginLatency", aws_cloudwatch_1.Stats.percentile(90)),
54
+ threshold: cfg.threshold,
55
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
56
+ evaluationPeriods: cfg.evaluationPeriods,
57
+ datapointsToAlarm: cfg.datapointsToAlarm,
58
+ treatMissingData: cfg.treatMissingData,
59
+ description: `CloudFront origin latency is elevated. Threshold: > ${String(cfg.threshold)}ms p90 in ${METRIC_PERIOD_LABEL}.`,
60
+ });
61
+ }
62
+ return definitions;
63
+ }
64
+ //# sourceMappingURL=distribution-alarms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribution-alarms.js","sourceRoot":"","sources":["../../src/distribution-alarms.ts"],"names":[],"mappings":";;AAoCA,kFA0CC;AA9ED,6CAAuC;AACvC,+DAA+E;AAG/E,yDAA8D;AAE9D,2DAAkE;AAElE,MAAM,aAAa,GAAG,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1C,MAAM,mBAAmB,GAAG,GAAG,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC;AAE1E;;;GAGG;AACH,SAAS,kBAAkB,CACzB,YAA0B,EAC1B,UAAkB,EAClB,SAAiB;IAEjB,OAAO,IAAI,uBAAM,CAAC;QAChB,SAAS,EAAE,gBAAgB;QAC3B,UAAU;QACV,aAAa,EAAE;YACb,cAAc,EAAE,YAAY,CAAC,cAAc;YAC3C,MAAM,EAAE,QAAQ;SACjB;QACD,SAAS;QACT,MAAM,EAAE,aAAa;KACtB,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAgB,mCAAmC,CACjD,YAA0B,EAC1B,MAA2C;IAE3C,IAAI,MAAM,EAAE,OAAO,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IAEzC,MAAM,WAAW,GAAsB,EAAE,CAAC;IAE1C,IAAI,MAAM,EAAE,SAAS,KAAK,KAAK,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,IAAA,+BAAkB,EAAC,MAAM,EAAE,SAAS,EAAE,+CAA2B,CAAC,SAAS,CAAC,CAAC;QACzF,WAAW,CAAC,IAAI,CAAC;YACf,GAAG,EAAE,WAAW;YAChB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,MAAM,EAAE,kBAAkB,CAAC,YAAY,EAAE,cAAc,EAAE,sBAAK,CAAC,OAAO,CAAC;YACvE,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;YACxC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;YACxC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,WAAW,EAAE,oEAAoE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,mBAAmB,GAAG;SACrI,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,EAAE,aAAa,KAAK,KAAK,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,IAAA,+BAAkB,EAC5B,MAAM,EAAE,aAAa,EACrB,+CAA2B,CAAC,aAAa,CAC1C,CAAC;QACF,WAAW,CAAC,IAAI,CAAC;YACf,GAAG,EAAE,eAAe;YACpB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,MAAM,EAAE,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,sBAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC/E,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;YACxC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;YACxC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,WAAW,EAAE,uDAAuD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,mBAAmB,GAAG;SAC7H,CAAC,CAAC;IACL,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distribution-builder.d.ts","sourceRoot":"","sources":["../../src/distribution-builder.ts"],"names":[],"mappings":"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"}