@composurecdk/cloudfront 0.4.2 → 0.4.4

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.
@@ -5,9 +5,8 @@ import type { AlarmConfig } from "@composurecdk/cloudwatch";
5
5
  * Set individual alarms to `false` to disable them, or provide an
6
6
  * {@link AlarmConfig} to tune thresholds.
7
7
  *
8
- * Function-level alarms (FunctionValidationErrors, FunctionExecutionErrors,
9
- * FunctionThrottles) require per-function dimensions and are not created
10
- * automatically. Use {@link IDistributionBuilder.addAlarm} to add them.
8
+ * Function-level alarms are created automatically for every inline function
9
+ * declared on a behavior see {@link FunctionAlarmConfig} to tune them.
11
10
  *
12
11
  * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
13
12
  */
@@ -42,4 +41,54 @@ export interface DistributionAlarmConfig {
42
41
  */
43
42
  originLatency?: AlarmConfig | false;
44
43
  }
44
+ /**
45
+ * Controls which recommended alarms are created for a CloudFront Function
46
+ * declared inline on a cache behavior. All alarms are enabled by default
47
+ * with AWS-recommended thresholds. Set individual alarms to `false` to
48
+ * disable them, or provide an {@link AlarmConfig} to tune thresholds.
49
+ *
50
+ * CloudFront Function metrics are emitted in the `us-east-1` region only
51
+ * (CloudFront is a global service). The alarms live in the stack's region —
52
+ * if that is not `us-east-1`, the alarms will not receive data.
53
+ *
54
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
55
+ */
56
+ export interface FunctionAlarmConfig {
57
+ /**
58
+ * Master switch: set to `false` to disable all recommended alarms for
59
+ * this function. Individual alarms can also be disabled via their own entry.
60
+ * @default true
61
+ */
62
+ enabled?: boolean;
63
+ /**
64
+ * Alarm when the function raises runtime exceptions while processing a
65
+ * viewer request or response.
66
+ *
67
+ * Metric: `AWS/CloudFront FunctionExecutionErrors`, statistic Sum,
68
+ * period 1 minute. Default threshold: > 0 errors.
69
+ *
70
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
71
+ */
72
+ executionErrors?: AlarmConfig | false;
73
+ /**
74
+ * Alarm when the function returns an event object that fails validation
75
+ * (e.g. malformed headers, unsupported response shape).
76
+ *
77
+ * Metric: `AWS/CloudFront FunctionValidationErrors`, statistic Sum,
78
+ * period 1 minute. Default threshold: > 0 errors.
79
+ *
80
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
81
+ */
82
+ validationErrors?: AlarmConfig | false;
83
+ /**
84
+ * Alarm when the function is throttled — typically because it exceeded
85
+ * the 1ms compute-utilization budget.
86
+ *
87
+ * Metric: `AWS/CloudFront FunctionThrottles`, statistic Sum,
88
+ * period 1 minute. Default threshold: > 0 throttles.
89
+ *
90
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-function-restrictions.html
91
+ */
92
+ throttles?: AlarmConfig | false;
93
+ }
45
94
  //# sourceMappingURL=alarm-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"alarm-config.d.ts","sourceRoot":"","sources":["../src/alarm-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,MAAM,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"}
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;;;;OAIG;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"}
@@ -4,11 +4,25 @@ interface DistributionAlarmDefaults {
4
4
  errorRate: Required<AlarmConfig>;
5
5
  originLatency: Required<AlarmConfig>;
6
6
  }
7
+ interface FunctionAlarmDefaults {
8
+ enabled: true;
9
+ executionErrors: Required<AlarmConfig>;
10
+ validationErrors: Required<AlarmConfig>;
11
+ throttles: Required<AlarmConfig>;
12
+ }
7
13
  /**
8
14
  * AWS-recommended default alarm configuration for CloudFront distributions.
9
15
  *
10
16
  * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
11
17
  */
12
18
  export declare const DISTRIBUTION_ALARM_DEFAULTS: DistributionAlarmDefaults;
19
+ /**
20
+ * Default alarm configuration for CloudFront Functions declared inline on
21
+ * a cache behavior. Any non-zero count of errors or throttles is worth
22
+ * investigating since a function executes on every viewer request/response.
23
+ *
24
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
25
+ */
26
+ export declare const FUNCTION_ALARM_DEFAULTS: FunctionAlarmDefaults;
13
27
  export {};
14
28
  //# sourceMappingURL=alarm-defaults.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"alarm-defaults.d.ts","sourceRoot":"","sources":["../src/alarm-defaults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,UAAU,yBAAyB;IACjC,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACjC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,yBAyBzC,CAAC"}
1
+ {"version":3,"file":"alarm-defaults.d.ts","sourceRoot":"","sources":["../src/alarm-defaults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,UAAU,yBAAyB;IACjC,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACjC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CACtC;AAED,UAAU,qBAAqB;IAC7B,OAAO,EAAE,IAAI,CAAC;IACd,eAAe,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACvC,gBAAgB,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACxC,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,yBAyBzC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,qBA0BrC,CAAC"}
@@ -28,4 +28,35 @@ export const DISTRIBUTION_ALARM_DEFAULTS = {
28
28
  treatMissingData: TreatMissingData.NOT_BREACHING,
29
29
  },
30
30
  };
31
+ /**
32
+ * Default alarm configuration for CloudFront Functions declared inline on
33
+ * a cache behavior. Any non-zero count of errors or throttles is worth
34
+ * investigating since a function executes on every viewer request/response.
35
+ *
36
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
37
+ */
38
+ export const FUNCTION_ALARM_DEFAULTS = {
39
+ enabled: true,
40
+ /** Any execution error indicates a runtime fault on the edge; threshold 0. */
41
+ executionErrors: {
42
+ threshold: 0,
43
+ evaluationPeriods: 1,
44
+ datapointsToAlarm: 1,
45
+ treatMissingData: TreatMissingData.NOT_BREACHING,
46
+ },
47
+ /** Any validation error indicates the function returned a bad event; threshold 0. */
48
+ validationErrors: {
49
+ threshold: 0,
50
+ evaluationPeriods: 1,
51
+ datapointsToAlarm: 1,
52
+ treatMissingData: TreatMissingData.NOT_BREACHING,
53
+ },
54
+ /** Any throttle indicates the function exceeded its 1ms compute budget; threshold 0. */
55
+ throttles: {
56
+ threshold: 0,
57
+ evaluationPeriods: 1,
58
+ datapointsToAlarm: 1,
59
+ treatMissingData: TreatMissingData.NOT_BREACHING,
60
+ },
61
+ };
31
62
  //# sourceMappingURL=alarm-defaults.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alarm-defaults.js","sourceRoot":"","sources":["../src/alarm-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAS9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,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,gBAAgB,CAAC,aAAa;KACjD;IAED;;;;OAIG;IACH,aAAa,EAAE;QACb,SAAS,EAAE,IAAI;QACf,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;CACF,CAAC"}
1
+ {"version":3,"file":"alarm-defaults.js","sourceRoot":"","sources":["../src/alarm-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAgB9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,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,gBAAgB,CAAC,aAAa;KACjD;IAED;;;;OAIG;IACH,aAAa,EAAE;QACb,SAAS,EAAE,IAAI;QACf,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,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,gBAAgB,CAAC,aAAa;KACjD;IAED,qFAAqF;IACrF,gBAAgB,EAAE;QAChB,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED,wFAAwF;IACxF,SAAS,EAAE;QACT,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;CACF,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { Function as CfFunction, FunctionEventType } from "aws-cdk-lib/aws-cloudfront";
2
+ import type { AlarmDefinition } from "@composurecdk/cloudwatch";
3
+ import type { FunctionAlarmConfig } from "./alarm-config.js";
4
+ /**
5
+ * Converts a CloudFront cache-behavior path pattern into a PascalCase slug
6
+ * suitable for alarm keys and CDK construct ids. A single leading `/` is
7
+ * dropped (the common case), interior `/` becomes `Slash` so sibling patterns
8
+ * don't collide, `*` becomes `Star`, and `?` becomes `Q`. Other
9
+ * non-alphanumeric characters are stripped.
10
+ *
11
+ * Examples:
12
+ * - `/api/*` → `ApiSlashStar`
13
+ * - `/api*` → `ApiStar` (distinct from `/api/*`)
14
+ * - `*.html` → `StarHtml`
15
+ * - `images/*` → `ImagesSlashStar`
16
+ *
17
+ * @internal
18
+ */
19
+ export declare function pathPatternSlug(pattern: string): string;
20
+ /**
21
+ * Converts a {@link FunctionEventType} value (e.g. `"viewer-request"`) into
22
+ * PascalCase (e.g. `"ViewerRequest"`) for use in alarm keys and construct ids.
23
+ *
24
+ * @internal
25
+ */
26
+ export declare function eventTypePascal(eventType: FunctionEventType): string;
27
+ /**
28
+ * Builds the prefix used for every alarm key produced for a given inline
29
+ * function — e.g. `defaultBehaviorViewerRequest` or `behaviorApiStarViewerRequest`.
30
+ * Pass `null` for the default behavior.
31
+ *
32
+ * @internal
33
+ */
34
+ export declare function behaviorFunctionKeyPrefix(pathPattern: string | null, eventType: FunctionEventType): string;
35
+ /**
36
+ * Produces fully-resolved {@link AlarmDefinition}s for the three AWS-recommended
37
+ * CloudFront Function alarms — execution errors, validation errors, throttles —
38
+ * scoped to a single behavior + event type so the keys and descriptions stay
39
+ * actionable when the same underlying function is used on multiple behaviors.
40
+ *
41
+ * @internal
42
+ */
43
+ export declare function resolveBehaviorFunctionAlarmDefinitions(pathPattern: string | null, eventType: FunctionEventType, fn: CfFunction, config: FunctionAlarmConfig | false | undefined): AlarmDefinition[];
44
+ //# sourceMappingURL=behavior-function-alarms.d.ts.map
@@ -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,CAyDnB"}
@@ -0,0 +1,136 @@
1
+ import { Duration } from "aws-cdk-lib";
2
+ import { ComparisonOperator, Metric, Stats } from "aws-cdk-lib/aws-cloudwatch";
3
+ import { resolveAlarmConfig } from "@composurecdk/cloudwatch";
4
+ import { FUNCTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
5
+ const METRIC_PERIOD = Duration.minutes(1);
6
+ const METRIC_PERIOD_LABEL = `${String(METRIC_PERIOD.toMinutes())} minute`;
7
+ /**
8
+ * CloudFront Function metrics are emitted in the `us-east-1` region only
9
+ * (CloudFront is a global service). Metric dimensions are
10
+ * `FunctionName` + `Region=Global`.
11
+ *
12
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
13
+ */
14
+ function functionMetric(fn, metricName) {
15
+ return new Metric({
16
+ namespace: "AWS/CloudFront",
17
+ metricName,
18
+ dimensionsMap: {
19
+ FunctionName: fn.functionName,
20
+ Region: "Global",
21
+ },
22
+ statistic: Stats.SUM,
23
+ period: METRIC_PERIOD,
24
+ });
25
+ }
26
+ /**
27
+ * Converts a CloudFront cache-behavior path pattern into a PascalCase slug
28
+ * suitable for alarm keys and CDK construct ids. A single leading `/` is
29
+ * dropped (the common case), interior `/` becomes `Slash` so sibling patterns
30
+ * don't collide, `*` becomes `Star`, and `?` becomes `Q`. Other
31
+ * non-alphanumeric characters are stripped.
32
+ *
33
+ * Examples:
34
+ * - `/api/*` → `ApiSlashStar`
35
+ * - `/api*` → `ApiStar` (distinct from `/api/*`)
36
+ * - `*.html` → `StarHtml`
37
+ * - `images/*` → `ImagesSlashStar`
38
+ *
39
+ * @internal
40
+ */
41
+ export function pathPatternSlug(pattern) {
42
+ const stripped = pattern.startsWith("/") ? pattern.slice(1) : pattern;
43
+ return stripped
44
+ .replace(/\//g, " Slash ")
45
+ .replace(/\*/g, " Star ")
46
+ .replace(/\?/g, " Q ")
47
+ .split(/[^A-Za-z0-9]+/)
48
+ .filter(Boolean)
49
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
50
+ .join("");
51
+ }
52
+ /**
53
+ * Converts a {@link FunctionEventType} value (e.g. `"viewer-request"`) into
54
+ * PascalCase (e.g. `"ViewerRequest"`) for use in alarm keys and construct ids.
55
+ *
56
+ * @internal
57
+ */
58
+ export function eventTypePascal(eventType) {
59
+ return eventType
60
+ .split("-")
61
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
62
+ .join("");
63
+ }
64
+ /**
65
+ * Builds the prefix used for every alarm key produced for a given inline
66
+ * function — e.g. `defaultBehaviorViewerRequest` or `behaviorApiStarViewerRequest`.
67
+ * Pass `null` for the default behavior.
68
+ *
69
+ * @internal
70
+ */
71
+ export function behaviorFunctionKeyPrefix(pathPattern, eventType) {
72
+ const scope = pathPattern === null ? "defaultBehavior" : `behavior${pathPatternSlug(pathPattern)}`;
73
+ return `${scope}${eventTypePascal(eventType)}`;
74
+ }
75
+ function behaviorFunctionScopeLabel(pathPattern, eventType) {
76
+ const scope = pathPattern === null ? "default behavior" : `behavior "${pathPattern}"`;
77
+ return `${scope} (${eventType})`;
78
+ }
79
+ /**
80
+ * Produces fully-resolved {@link AlarmDefinition}s for the three AWS-recommended
81
+ * CloudFront Function alarms — execution errors, validation errors, throttles —
82
+ * scoped to a single behavior + event type so the keys and descriptions stay
83
+ * actionable when the same underlying function is used on multiple behaviors.
84
+ *
85
+ * @internal
86
+ */
87
+ export function resolveBehaviorFunctionAlarmDefinitions(pathPattern, eventType, fn, config) {
88
+ if (config === false)
89
+ return [];
90
+ if (config?.enabled === false)
91
+ return [];
92
+ const keyPrefix = behaviorFunctionKeyPrefix(pathPattern, eventType);
93
+ const scopeLabel = behaviorFunctionScopeLabel(pathPattern, eventType);
94
+ const definitions = [];
95
+ if (config?.executionErrors !== false) {
96
+ const cfg = resolveAlarmConfig(config?.executionErrors, FUNCTION_ALARM_DEFAULTS.executionErrors);
97
+ definitions.push({
98
+ key: `${keyPrefix}ExecutionErrors`,
99
+ metric: functionMetric(fn, "FunctionExecutionErrors"),
100
+ threshold: cfg.threshold,
101
+ comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
102
+ evaluationPeriods: cfg.evaluationPeriods,
103
+ datapointsToAlarm: cfg.datapointsToAlarm,
104
+ treatMissingData: cfg.treatMissingData,
105
+ description: `CloudFront Function on ${scopeLabel} is raising execution errors. Threshold: > ${String(cfg.threshold)} errors in ${METRIC_PERIOD_LABEL}.`,
106
+ });
107
+ }
108
+ if (config?.validationErrors !== false) {
109
+ const cfg = resolveAlarmConfig(config?.validationErrors, FUNCTION_ALARM_DEFAULTS.validationErrors);
110
+ definitions.push({
111
+ key: `${keyPrefix}ValidationErrors`,
112
+ metric: functionMetric(fn, "FunctionValidationErrors"),
113
+ threshold: cfg.threshold,
114
+ comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
115
+ evaluationPeriods: cfg.evaluationPeriods,
116
+ datapointsToAlarm: cfg.datapointsToAlarm,
117
+ treatMissingData: cfg.treatMissingData,
118
+ description: `CloudFront Function on ${scopeLabel} is producing validation errors. Threshold: > ${String(cfg.threshold)} errors in ${METRIC_PERIOD_LABEL}.`,
119
+ });
120
+ }
121
+ if (config?.throttles !== false) {
122
+ const cfg = resolveAlarmConfig(config?.throttles, FUNCTION_ALARM_DEFAULTS.throttles);
123
+ definitions.push({
124
+ key: `${keyPrefix}Throttles`,
125
+ metric: functionMetric(fn, "FunctionThrottles"),
126
+ threshold: cfg.threshold,
127
+ comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
128
+ evaluationPeriods: cfg.evaluationPeriods,
129
+ datapointsToAlarm: cfg.datapointsToAlarm,
130
+ treatMissingData: cfg.treatMissingData,
131
+ description: `CloudFront Function on ${scopeLabel} is being throttled — likely exceeding its 1ms compute budget. Threshold: > ${String(cfg.threshold)} throttles in ${METRIC_PERIOD_LABEL}.`,
132
+ });
133
+ }
134
+ return definitions;
135
+ }
136
+ //# 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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"}
@@ -1,4 +1,4 @@
1
- import type { DistributionBuilderProps } from "./distribution-builder.js";
1
+ import type { DistributionBuilderProps, InlineFunctionDefinition } from "./distribution-builder.js";
2
2
  /**
3
3
  * Secure, AWS-recommended defaults applied to every CloudFront distribution
4
4
  * built with {@link createDistributionBuilder}. Each property can be individually
@@ -9,4 +9,9 @@ import type { DistributionBuilderProps } from "./distribution-builder.js";
9
9
  * then the resolved origin is injected.
10
10
  */
11
11
  export declare const DISTRIBUTION_DEFAULTS: Partial<DistributionBuilderProps>;
12
+ /**
13
+ * Defaults applied to every inline CloudFront Function declared on a cache
14
+ * behavior. User-provided properties take precedence.
15
+ */
16
+ export declare const INLINE_FUNCTION_DEFAULTS: Partial<InlineFunctionDefinition>;
12
17
  //# sourceMappingURL=defaults.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAE1E;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,OAAO,CAAC,wBAAwB,CAkDnE,CAAC"}
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,CAkDnE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,OAAO,CAAC,wBAAwB,CAOtE,CAAC"}
package/dist/defaults.js CHANGED
@@ -1,4 +1,4 @@
1
- import { HttpVersion, PriceClass, ResponseHeadersPolicy, SecurityPolicyProtocol, ViewerProtocolPolicy, } from "aws-cdk-lib/aws-cloudfront";
1
+ import { FunctionRuntime, HttpVersion, PriceClass, ResponseHeadersPolicy, SecurityPolicyProtocol, ViewerProtocolPolicy, } from "aws-cdk-lib/aws-cloudfront";
2
2
  /**
3
3
  * Secure, AWS-recommended defaults applied to every CloudFront distribution
4
4
  * built with {@link createDistributionBuilder}. Each property can be individually
@@ -53,4 +53,16 @@ export const DISTRIBUTION_DEFAULTS = {
53
53
  responseHeadersPolicy: ResponseHeadersPolicy.SECURITY_HEADERS,
54
54
  },
55
55
  };
56
+ /**
57
+ * Defaults applied to every inline CloudFront Function declared on a cache
58
+ * behavior. User-provided properties take precedence.
59
+ */
60
+ export const INLINE_FUNCTION_DEFAULTS = {
61
+ /**
62
+ * Use the `cloudfront-js-2.0` runtime by default. It is a superset of
63
+ * `cloudfront-js-1.0` (async/await, `crypto.subtle`, KeyValueStore support).
64
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/functions-javascript-runtime-20.html
65
+ */
66
+ runtime: FunctionRuntime.JS_2_0,
67
+ };
56
68
  //# sourceMappingURL=defaults.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,UAAU,EACV,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAsC;IACtE;;;;;OAKG;IACH,aAAa,EAAE,IAAI;IAEnB;;;;OAIG;IACH,UAAU,EAAE,UAAU,CAAC,eAAe;IAEtC;;;;OAIG;IACH,WAAW,EAAE,WAAW,CAAC,WAAW;IAEpC;;;OAGG;IACH,iBAAiB,EAAE,YAAY;IAE/B;;;;OAIG;IACH,sBAAsB,EAAE,sBAAsB,CAAC,aAAa;IAE5D,eAAe,EAAE;QACf;;;WAGG;QACH,oBAAoB,EAAE,oBAAoB,CAAC,iBAAiB;QAE5D;;;;WAIG;QACH,qBAAqB,EAAE,qBAAqB,CAAC,gBAAgB;KAC9D;CACF,CAAC"}
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,WAAW,EACX,UAAU,EACV,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAsC;IACtE;;;;;OAKG;IACH,aAAa,EAAE,IAAI;IAEnB;;;;OAIG;IACH,UAAU,EAAE,UAAU,CAAC,eAAe;IAEtC;;;;OAIG;IACH,WAAW,EAAE,WAAW,CAAC,WAAW;IAEpC;;;OAGG;IACH,iBAAiB,EAAE,YAAY;IAE/B;;;;OAIG;IACH,sBAAsB,EAAE,sBAAsB,CAAC,aAAa;IAE5D,eAAe,EAAE;QACf;;;WAGG;QACH,oBAAoB,EAAE,oBAAoB,CAAC,iBAAiB;QAE5D;;;;WAIG;QACH,qBAAqB,EAAE,qBAAqB,CAAC,gBAAgB;KAC9D;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAsC;IACzE;;;;OAIG;IACH,OAAO,EAAE,eAAe,CAAC,MAAM;CAChC,CAAC"}
@@ -1,26 +1,9 @@
1
- import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
2
1
  import type { Distribution } from "aws-cdk-lib/aws-cloudfront";
3
- import type { IConstruct } from "constructs";
4
2
  import type { AlarmDefinition } from "@composurecdk/cloudwatch";
5
- import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
6
3
  import type { DistributionAlarmConfig } from "./alarm-config.js";
7
4
  /**
8
5
  * Resolves the recommended alarm configuration into fully-resolved
9
6
  * {@link AlarmDefinition}s for a CloudFront distribution.
10
7
  */
11
8
  export declare function resolveDistributionAlarmDefinitions(distribution: Distribution, config: DistributionAlarmConfig | undefined): AlarmDefinition[];
12
- /**
13
- * Creates AWS-recommended CloudWatch alarms for a CloudFront distribution,
14
- * merging recommended definitions with any custom alarm builders.
15
- *
16
- * @param scope - CDK construct scope for creating alarm constructs.
17
- * @param id - Base identifier for alarm construct ids.
18
- * @param distribution - The CloudFront distribution to create alarms for.
19
- * @param config - User-provided alarm configuration, or `false` to disable all.
20
- * @param customAlarms - Custom alarm builders added via `addAlarm()`.
21
- * @returns A record mapping alarm keys to their created Alarm constructs.
22
- *
23
- * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
24
- */
25
- export declare function createDistributionAlarms(scope: IConstruct, id: string, distribution: Distribution, config: DistributionAlarmConfig | false | undefined, customAlarms?: AlarmDefinitionBuilder<Distribution>[]): Record<string, Alarm>;
26
9
  //# sourceMappingURL=distribution-alarms.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"distribution-alarms.d.ts","sourceRoot":"","sources":["../src/distribution-alarms.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,KAAK,EAAqC,MAAM,4BAA4B,CAAC;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAoC,MAAM,0BAA0B,CAAC;AACpG,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,CAqCnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,uBAAuB,GAAG,KAAK,GAAG,SAAS,EACnD,YAAY,GAAE,sBAAsB,CAAC,YAAY,CAAC,EAAO,GACxD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAUvB"}
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,CAqCnB"}
@@ -1,6 +1,6 @@
1
1
  import { Duration } from "aws-cdk-lib";
2
2
  import { ComparisonOperator, Metric, Stats } from "aws-cdk-lib/aws-cloudwatch";
3
- import { createAlarms, resolveAlarmConfig } from "@composurecdk/cloudwatch";
3
+ import { resolveAlarmConfig } from "@composurecdk/cloudwatch";
4
4
  import { DISTRIBUTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
5
5
  const METRIC_PERIOD = Duration.minutes(1);
6
6
  const METRIC_PERIOD_LABEL = `${String(METRIC_PERIOD.toMinutes())} minute`;
@@ -56,27 +56,4 @@ export function resolveDistributionAlarmDefinitions(distribution, config) {
56
56
  }
57
57
  return definitions;
58
58
  }
59
- /**
60
- * Creates AWS-recommended CloudWatch alarms for a CloudFront distribution,
61
- * merging recommended definitions with any custom alarm builders.
62
- *
63
- * @param scope - CDK construct scope for creating alarm constructs.
64
- * @param id - Base identifier for alarm construct ids.
65
- * @param distribution - The CloudFront distribution to create alarms for.
66
- * @param config - User-provided alarm configuration, or `false` to disable all.
67
- * @param customAlarms - Custom alarm builders added via `addAlarm()`.
68
- * @returns A record mapping alarm keys to their created Alarm constructs.
69
- *
70
- * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
71
- */
72
- export function createDistributionAlarms(scope, id, distribution, config, customAlarms = []) {
73
- if (config === false)
74
- return {};
75
- const enabled = config?.enabled ?? DISTRIBUTION_ALARM_DEFAULTS.enabled;
76
- if (!enabled)
77
- return {};
78
- const recommended = resolveDistributionAlarmDefinitions(distribution, config);
79
- const custom = customAlarms.map((b) => b.resolve(distribution));
80
- return createAlarms(scope, id, [...recommended, ...custom]);
81
- }
82
59
  //# sourceMappingURL=distribution-alarms.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"distribution-alarms.js","sourceRoot":"","sources":["../src/distribution-alarms.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"distribution-alarms.js","sourceRoot":"","sources":["../src/distribution-alarms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAG/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,aAAa,GAAG,QAAQ,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,MAAM,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,MAAM,UAAU,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,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,2BAA2B,CAAC,SAAS,CAAC,CAAC;QACzF,WAAW,CAAC,IAAI,CAAC;YACf,GAAG,EAAE,WAAW;YAChB,MAAM,EAAE,kBAAkB,CAAC,YAAY,EAAE,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC;YACvE,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,kBAAkB,EAAE,kBAAkB,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,kBAAkB,CAC5B,MAAM,EAAE,aAAa,EACrB,2BAA2B,CAAC,aAAa,CAC1C,CAAC;QACF,WAAW,CAAC,IAAI,CAAC;YACf,GAAG,EAAE,eAAe;YACpB,MAAM,EAAE,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC/E,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,kBAAkB,EAAE,kBAAkB,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"}
@@ -1,24 +1,109 @@
1
- import { Distribution, type DistributionProps, type IOrigin, type AddBehaviorOptions } from "aws-cdk-lib/aws-cloudfront";
1
+ import { Distribution, type DistributionProps, type IOrigin, type AddBehaviorOptions, type BehaviorOptions, type Function as CfFunction, type FunctionCode, type FunctionEventType, type FunctionRuntime, type IKeyValueStore } from "aws-cdk-lib/aws-cloudfront";
2
2
  import { type ICertificate } from "aws-cdk-lib/aws-certificatemanager";
3
3
  import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
4
4
  import { type Bucket } from "aws-cdk-lib/aws-s3";
5
5
  import { type IConstruct } from "constructs";
6
6
  import { type IBuilder, type Lifecycle, type Resolvable } from "@composurecdk/core";
7
7
  import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
8
- import type { DistributionAlarmConfig } from "./alarm-config.js";
8
+ import type { DistributionAlarmConfig, FunctionAlarmConfig } from "./alarm-config.js";
9
+ /**
10
+ * A CloudFront Function declared inline on a cache behavior. The distribution
11
+ * builder creates the underlying {@link CfFunction} construct and wires it
12
+ * into the behavior's function associations. Recommended alarms for the
13
+ * function are emitted automatically, scoped to the behavior's path pattern.
14
+ *
15
+ * Only inline declarations are supported — there is no "bring your own
16
+ * function" escape hatch, because the whole point of owning the function is
17
+ * to emit path-scoped `FunctionExecutionErrors` / `FunctionValidationErrors`
18
+ * / `FunctionThrottles` alarms that couldn't be emitted from an external
19
+ * `IFunctionRef` (which exposes only an ARN, not a function name).
20
+ *
21
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html
22
+ */
23
+ export interface InlineFunctionDefinition {
24
+ /** The viewer event that should invoke the function. */
25
+ eventType: FunctionEventType;
26
+ /** The source for the function — `FunctionCode.fromInline()` or `.fromFile()`. */
27
+ code: FunctionCode;
28
+ /**
29
+ * Explicit physical name for the function. Useful when operators search
30
+ * CloudWatch logs or metrics by function name rather than by ARN. If omitted,
31
+ * CDK generates a name derived from the construct path.
32
+ */
33
+ functionName?: string;
34
+ /**
35
+ * JavaScript runtime.
36
+ * @default FunctionRuntime.JS_2_0
37
+ */
38
+ runtime?: FunctionRuntime;
39
+ /** Optional comment stored on the function resource. */
40
+ comment?: string;
41
+ /**
42
+ * Key-value store to associate with the function. Only supported on the
43
+ * `cloudfront-js-2.0` runtime.
44
+ */
45
+ keyValueStore?: IKeyValueStore;
46
+ /**
47
+ * Per-function alarm configuration. Defaults to the three AWS-recommended
48
+ * alarms (execution errors, validation errors, throttles) each with
49
+ * threshold 0. Set to `false` to disable all alarms for this function, or
50
+ * override individual alarms via their config entry.
51
+ *
52
+ * **Region requirement:** CloudFront metrics are emitted in `us-east-1`
53
+ * only. CloudWatch alarms are regional, so these alarms will only fire if
54
+ * the containing stack is deployed in `us-east-1`. The builder emits a
55
+ * synth-time warning if this isn't the case.
56
+ *
57
+ * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/monitoring-functions.html
58
+ */
59
+ recommendedAlarms?: FunctionAlarmConfig | false;
60
+ }
61
+ /**
62
+ * Configuration for the distribution's default cache behavior.
63
+ *
64
+ * The origin is set separately via {@link IDistributionBuilder.origin}. The
65
+ * `functionAssociations` field from {@link AddBehaviorOptions} is replaced by
66
+ * {@link functions}, which takes {@link InlineFunctionDefinition}s — the
67
+ * builder owns the CloudFront Function constructs so it can emit alarms for
68
+ * them.
69
+ */
70
+ export interface DefaultBehaviorConfig extends Omit<AddBehaviorOptions, "functionAssociations"> {
71
+ /**
72
+ * CloudFront Functions to associate with the default behavior. At most one
73
+ * function per {@link FunctionEventType} is allowed.
74
+ */
75
+ functions?: InlineFunctionDefinition[];
76
+ }
77
+ /**
78
+ * Configuration for a path-pattern cache behavior attached to the distribution
79
+ * via {@link IDistributionBuilder.behavior}.
80
+ *
81
+ * Unlike {@link DefaultBehaviorConfig}, `origin` is required. It may be a
82
+ * concrete {@link IOrigin} or a {@link Resolvable} (typically a {@link ref})
83
+ * for cross-component wiring.
84
+ */
85
+ export interface AdditionalBehaviorConfig extends Omit<BehaviorOptions, "origin" | "functionAssociations"> {
86
+ /** The origin for this behavior, concrete or resolved at build time. */
87
+ origin: Resolvable<IOrigin>;
88
+ /**
89
+ * CloudFront Functions to associate with this behavior. At most one
90
+ * function per {@link FunctionEventType} is allowed.
91
+ */
92
+ functions?: InlineFunctionDefinition[];
93
+ }
9
94
  /**
10
95
  * Configuration properties for the CloudFront distribution builder.
11
96
  *
12
97
  * Extends the CDK {@link DistributionProps} with additional builder-specific
13
- * options. The `defaultBehavior` field is replaced with {@link AddBehaviorOptions}
14
- * (which excludes `origin`) because the origin is set separately via the
15
- * {@link IDistributionBuilder.origin | origin()} method, which supports
16
- * {@link Resolvable} for cross-component wiring.
98
+ * options. `defaultBehavior` accepts a {@link DefaultBehaviorConfig} with
99
+ * inline function definitions; additional behaviors are added via the
100
+ * {@link IDistributionBuilder.behavior} method rather than the raw
101
+ * `additionalBehaviors` record.
17
102
  *
18
103
  * The `enableLogging` CDK prop is replaced by {@link accessLogging}, which
19
104
  * auto-creates a logging bucket with secure defaults when enabled.
20
105
  */
21
- export interface DistributionBuilderProps extends Omit<DistributionProps, "defaultBehavior" | "enableLogging" | "certificate"> {
106
+ export interface DistributionBuilderProps extends Omit<DistributionProps, "defaultBehavior" | "additionalBehaviors" | "enableLogging" | "certificate"> {
22
107
  /**
23
108
  * Whether to automatically create an S3 bucket for CloudFront standard
24
109
  * access logging.
@@ -44,36 +129,59 @@ export interface DistributionBuilderProps extends Omit<DistributionProps, "defau
44
129
  */
45
130
  certificate?: Resolvable<ICertificate>;
46
131
  /**
47
- * Options for the default cache behavior, excluding `origin`.
48
- *
49
- * The origin is set via the {@link IDistributionBuilder.origin | origin()}
50
- * method and injected at build time. All other behavior options (cache
51
- * policy, function associations, viewer protocol policy, etc.) can be
52
- * configured here.
132
+ * Configuration for the default cache behavior. The origin is set via
133
+ * {@link IDistributionBuilder.origin}. Inline CloudFront Functions declared
134
+ * in `functions` are created by the builder and receive path-scoped alarms
135
+ * automatically.
53
136
  */
54
- defaultBehavior?: AddBehaviorOptions;
137
+ defaultBehavior?: DefaultBehaviorConfig;
55
138
  /**
56
- * Configuration for AWS-recommended CloudWatch alarms.
139
+ * Configuration for AWS-recommended CloudWatch alarms at the **distribution**
140
+ * level (5xx error rate, origin latency).
141
+ *
142
+ * Scope: this setting controls *distribution-level* alarms only. Per-function
143
+ * alarms (`FunctionExecutionErrors`, `FunctionValidationErrors`,
144
+ * `FunctionThrottles`) are configured independently via each
145
+ * {@link InlineFunctionDefinition.recommendedAlarms}, because their
146
+ * correct disposition depends on the behavior the function is attached to.
147
+ *
148
+ * **Region requirement:** CloudFront metrics are emitted in `us-east-1`
149
+ * only. CloudWatch alarms are regional, so *every* alarm created by this
150
+ * builder (distribution-level and per-function) will only fire if the
151
+ * containing stack is deployed in `us-east-1`. The builder emits a
152
+ * synth-time warning if this isn't the case.
57
153
  *
58
- * By default, the builder creates recommended alarms for 5xx error rate
59
- * and origin latency. Individual alarms can be customized or disabled.
60
- * Set to `false` to disable all alarms.
154
+ * By default, the builder creates recommended distribution alarms.
155
+ * Individual alarms can be customized or disabled; set to `false` to
156
+ * disable all distribution-level alarms **function alarms remain
157
+ * enabled**. To disable function alarms, set `recommendedAlarms: false`
158
+ * on the corresponding {@link InlineFunctionDefinition}.
61
159
  *
62
- * No alarm actions are configured by default since notification
63
- * methods are user-specific. Access alarms from the build result
64
- * or use an `afterBuild` hook to apply actions.
160
+ * No alarm actions are configured by default since notification methods
161
+ * are user-specific. Access alarms from the build result or use an
162
+ * `afterBuild` hook to apply actions.
65
163
  *
66
- * Function-level alarms (FunctionValidationErrors, FunctionExecutionErrors,
67
- * FunctionThrottles) require per-function dimensions. Use
68
- * {@link IDistributionBuilder.addAlarm} to add them.
164
+ * @example
165
+ * ```ts
166
+ * createDistributionBuilder()
167
+ * .origin(siteOrigin)
168
+ * .recommendedAlarms(false) // disables distribution alarms only
169
+ * .defaultBehavior({
170
+ * functions: [{
171
+ * eventType: FunctionEventType.VIEWER_REQUEST,
172
+ * code,
173
+ * recommendedAlarms: false, // must also disable function alarms explicitly
174
+ * }],
175
+ * });
176
+ * ```
69
177
  *
70
178
  * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
71
179
  */
72
180
  recommendedAlarms?: DistributionAlarmConfig | false;
73
181
  }
74
182
  /**
75
- * The build output of a {@link IDistributionBuilder}. Contains the CDK constructs
76
- * created during {@link Lifecycle.build}, keyed by role.
183
+ * The build output of an {@link IDistributionBuilder}. Contains the CDK
184
+ * constructs created during {@link Lifecycle.build}, keyed by role.
77
185
  */
78
186
  export interface DistributionBuilderResult {
79
187
  /** The CloudFront distribution construct created by the builder. */
@@ -84,42 +192,56 @@ export interface DistributionBuilderResult {
84
192
  */
85
193
  accessLogsBucket?: Bucket;
86
194
  /**
87
- * CloudWatch alarms created for the distribution, keyed by alarm name.
195
+ * CloudFront Functions created by the builder for inline function
196
+ * definitions, keyed by `<behaviorScope><EventType>` —
197
+ * e.g. `defaultBehaviorViewerRequest`, `behaviorApiStarViewerRequest`.
88
198
  *
89
- * Includes both AWS-recommended alarms and any custom alarms added
90
- * via {@link IDistributionBuilder.addAlarm}. Access individual alarms
91
- * by key (e.g., `result.alarms.errorRate`).
92
- *
93
- * No alarm actions are configured apply them via the result or an
94
- * `afterBuild` hook.
199
+ * Empty if no inline functions were declared.
200
+ */
201
+ functions: Record<string, CfFunction>;
202
+ /**
203
+ * CloudWatch alarms created for the distribution and its inline functions,
204
+ * keyed by alarm name. Distribution-level keys: `errorRate`, `originLatency`.
205
+ * Function-level keys are prefixed by behavior scope and event type —
206
+ * e.g. `defaultBehaviorViewerRequestExecutionErrors`.
95
207
  *
96
- * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
208
+ * Includes both recommended alarms and custom alarms added via
209
+ * {@link IDistributionBuilder.addAlarm}. No alarm actions are configured.
97
210
  */
98
211
  alarms: Record<string, Alarm>;
99
212
  }
100
213
  /**
101
214
  * A fluent builder for configuring and creating a CloudFront distribution.
102
215
  *
103
- * Configuration properties from CDK {@link DistributionProps} are exposed as
104
- * overloaded getter/setter methods via the builder proxy. The origin is set
105
- * via the {@link origin} method, which accepts a concrete {@link IOrigin} or
106
- * a {@link Ref} for cross-component wiring.
216
+ * Properties from CDK {@link DistributionProps} are exposed as overloaded
217
+ * getter/setter methods. The origin is set via {@link origin}, which accepts
218
+ * a concrete {@link IOrigin} or a {@link Ref} for cross-component wiring.
219
+ * Additional cache behaviors are added via {@link behavior}, which takes a
220
+ * path pattern and a config including its own origin and inline functions.
107
221
  *
108
222
  * The builder implements {@link Lifecycle}, so it can be used directly as a
109
- * component in a {@link compose | composed system}. When built, it creates
110
- * a CloudFront distribution with the configured properties and returns a
111
- * {@link DistributionBuilderResult}.
223
+ * component in a {@link compose | composed system}. When built, it creates a
224
+ * CloudFront distribution, any inline CloudFront Functions declared on its
225
+ * behaviors, and AWS-recommended alarms scoped per-behavior.
112
226
  *
113
227
  * @example
114
228
  * ```ts
115
229
  * const cdn = createDistributionBuilder()
116
- * .origin(ref("site", (r: BucketBuilderResult) =>
117
- * S3BucketOrigin.withOriginAccessControl(r.bucket)))
118
- * .errorResponses([{
119
- * httpStatus: 404,
120
- * responsePagePath: "/index.html",
121
- * responseHttpStatus: 200,
122
- * }]);
230
+ * .origin(siteOrigin)
231
+ * .defaultBehavior({
232
+ * functions: [{
233
+ * eventType: FunctionEventType.VIEWER_REQUEST,
234
+ * code: FunctionCode.fromFile({ filePath: "src/edge/rewrite.js" }),
235
+ * }],
236
+ * })
237
+ * .behavior("/api/*", {
238
+ * origin: apiOrigin,
239
+ * cachePolicy: CachePolicy.CACHING_DISABLED,
240
+ * functions: [{
241
+ * eventType: FunctionEventType.VIEWER_REQUEST,
242
+ * code: FunctionCode.fromFile({ filePath: "src/edge/api-auth.js" }),
243
+ * }],
244
+ * });
123
245
  * ```
124
246
  */
125
247
  export type IDistributionBuilder = IBuilder<DistributionBuilderProps, DistributionBuilder>;
@@ -137,6 +259,15 @@ declare class DistributionBuilder implements Lifecycle<DistributionBuilderResult
137
259
  * @returns This builder for chaining.
138
260
  */
139
261
  origin(origin: Resolvable<IOrigin>): this;
262
+ /**
263
+ * Adds an additional cache behavior for a path pattern. The behavior's
264
+ * origin is required (concrete or Resolvable). Any inline functions are
265
+ * created by the builder and receive per-behavior alarms scoped to the
266
+ * path pattern.
267
+ *
268
+ * @throws If a behavior for the same path pattern has already been added.
269
+ */
270
+ behavior(pathPattern: string, config: AdditionalBehaviorConfig): this;
140
271
  build(scope: IConstruct, id: string, context?: Record<string, object>): DistributionBuilderResult;
141
272
  }
142
273
  /**
@@ -145,26 +276,27 @@ declare class DistributionBuilder implements Lifecycle<DistributionBuilderResult
145
276
  * This is the entry point for defining a CloudFront distribution component.
146
277
  * The returned builder exposes every {@link DistributionBuilderProps} property
147
278
  * as a fluent setter/getter, plus {@link IDistributionBuilder.origin | origin()}
148
- * for setting the default origin with Ref support. It implements {@link Lifecycle}
149
- * for use with {@link compose}.
279
+ * for setting the default origin with Ref support and
280
+ * {@link IDistributionBuilder.behavior | behavior()} for path-pattern behaviors.
281
+ * It implements {@link Lifecycle} for use with {@link compose}.
150
282
  *
151
283
  * @returns A fluent builder for a CloudFront distribution.
152
284
  *
153
285
  * @example
154
286
  * ```ts
155
287
  * const cdn = createDistributionBuilder()
156
- * .origin(ref("site", (r: BucketBuilderResult) =>
288
+ * .origin(ref<BucketBuilderResult>("site", (r) =>
157
289
  * S3BucketOrigin.withOriginAccessControl(r.bucket)))
158
- * .comment("Community website CDN");
159
- *
160
- * // Use standalone:
161
- * const result = cdn.build(stack, "CDN");
162
- *
163
- * // Or compose into a system:
164
- * const system = compose(
165
- * { site: createBucketBuilder(), cdn },
166
- * { site: [], cdn: ["site"] },
167
- * );
290
+ * .defaultBehavior({
291
+ * functions: [{
292
+ * eventType: FunctionEventType.VIEWER_REQUEST,
293
+ * code: FunctionCode.fromFile({ filePath: "src/edge/rewrite.js" }),
294
+ * }],
295
+ * })
296
+ * .behavior("/api/*", {
297
+ * origin: apiOrigin,
298
+ * cachePolicy: CachePolicy.CACHING_DISABLED,
299
+ * });
168
300
  * ```
169
301
  */
170
302
  export declare function createDistributionBuilder(): IDistributionBuilder;
@@ -1 +1 @@
1
- {"version":3,"file":"distribution-builder.d.ts","sourceRoot":"","sources":["../src/distribution-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,KAAK,MAAM,EAAmB,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,SAAS,EAEd,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAIjE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,iBAAiB,EACjB,iBAAiB,GAAG,eAAe,GAAG,aAAa,CACpD;IACC;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAEvC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,kBAAkB,CAAC;IAErC;;;;;;;;;;;;;;;;OAgBG;IACH,iBAAiB,CAAC,EAAE,uBAAuB,GAAG,KAAK,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,oEAAoE;IACpE,YAAY,EAAE,YAAY,CAAC;IAE3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC,wBAAwB,EAAE,mBAAmB,CAAC,CAAC;AAE3F,cAAM,mBAAoB,YAAW,SAAS,CAAC,yBAAyB,CAAC;;IACvE,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,CAAM;IAI9C,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CACT,KAAK,EAAE,sBAAsB,CAAC,YAAY,CAAC,KACxC,sBAAsB,CAAC,YAAY,CAAC,GACxC,IAAI;IAKP;;;;;;;;OAQG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI;IAKzC,KAAK,CACH,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,yBAAyB;CA4E7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,yBAAyB,IAAI,oBAAoB,CAEhE"}
1
+ {"version":3,"file":"distribution-builder.d.ts","sourceRoot":"","sources":["../src/distribution-builder.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,36 @@
1
1
  import { Distribution, } from "aws-cdk-lib/aws-cloudfront";
2
2
  import { ObjectOwnership } from "aws-cdk-lib/aws-s3";
3
- import { RemovalPolicy } from "aws-cdk-lib";
3
+ import { Annotations, RemovalPolicy, Stack, Token } from "aws-cdk-lib";
4
4
  import { Builder, resolve, } from "@composurecdk/core";
5
- import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
5
+ import { AlarmDefinitionBuilder, createAlarms } from "@composurecdk/cloudwatch";
6
6
  import { createBucketBuilder } from "@composurecdk/s3";
7
- import { createDistributionAlarms } from "./distribution-alarms.js";
7
+ import { resolveDistributionAlarmDefinitions } from "./distribution-alarms.js";
8
8
  import { DISTRIBUTION_DEFAULTS } from "./defaults.js";
9
+ import { resolveBehaviors } from "./resolve-behaviors.js";
10
+ import { pathPatternSlug } from "./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
+ * and will never fire. Warn (don't error) the user if this builder is used
15
+ * from a stack deployed outside `us-east-1`, unless the region is an
16
+ * unresolved token (env-agnostic stack — user knows best).
17
+ */
18
+ function warnIfNotUsEast1(scope) {
19
+ const region = Stack.of(scope).region;
20
+ if (Token.isUnresolved(region))
21
+ return;
22
+ if (region === "us-east-1")
23
+ return;
24
+ 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 disable recommended alarms and wire up a cross-region ` +
27
+ `alarm pattern yourself.`);
28
+ }
9
29
  class DistributionBuilder {
10
30
  props = {};
11
31
  #origin;
32
+ #additionalBehaviors = new Map();
33
+ #behaviorSlugs = new Map();
12
34
  #customAlarms = [];
13
35
  addAlarm(key, configure) {
14
36
  this.#customAlarms.push(configure(new AlarmDefinitionBuilder(key)));
@@ -27,6 +49,32 @@ class DistributionBuilder {
27
49
  this.#origin = origin;
28
50
  return this;
29
51
  }
52
+ /**
53
+ * Adds an additional cache behavior for a path pattern. The behavior's
54
+ * origin is required (concrete or Resolvable). Any inline functions are
55
+ * created by the builder and receive per-behavior alarms scoped to the
56
+ * path pattern.
57
+ *
58
+ * @throws If a behavior for the same path pattern has already been added.
59
+ */
60
+ behavior(pathPattern, config) {
61
+ if (this.#additionalBehaviors.has(pathPattern)) {
62
+ throw new Error(`DistributionBuilder: behavior for path pattern "${pathPattern}" is already defined.`);
63
+ }
64
+ // Alarm keys and Function construct ids are derived from a PascalCase slug
65
+ // of the path pattern. Patterns that differ only by stripped characters
66
+ // (e.g. `/*.html` vs `*.html`) would collide downstream at createAlarms() —
67
+ // surface the collision here with the patterns named.
68
+ const slug = pathPatternSlug(pathPattern);
69
+ const existingPattern = this.#behaviorSlugs.get(slug);
70
+ if (existingPattern !== undefined) {
71
+ throw new Error(`DistributionBuilder: path pattern "${pathPattern}" produces the same alarm/construct ` +
72
+ `slug ("${slug}") as "${existingPattern}". Pick distinct patterns.`);
73
+ }
74
+ this.#behaviorSlugs.set(slug, pathPattern);
75
+ this.#additionalBehaviors.set(pathPattern, config);
76
+ return this;
77
+ }
30
78
  build(scope, id, context) {
31
79
  const resolvedOrigin = this.#origin ? resolve(this.#origin, context ?? {}) : undefined;
32
80
  if (!resolvedOrigin) {
@@ -35,7 +83,7 @@ class DistributionBuilder {
35
83
  }
36
84
  const { accessLogging, certificate, defaultBehavior: userBehavior, recommendedAlarms: alarmConfig, ...distProps } = this.props;
37
85
  const resolvedCertificate = certificate ? resolve(certificate, context ?? {}) : undefined;
38
- const { accessLogging: defaultAccessLogging, defaultBehavior: defaultBehavior, ...cdkDefaults } = DISTRIBUTION_DEFAULTS;
86
+ const { accessLogging: defaultAccessLogging, defaultBehavior: defaultBehaviorDefaults, ...cdkDefaults } = DISTRIBUTION_DEFAULTS;
39
87
  const autoAccessLog = (accessLogging ?? defaultAccessLogging) && !distProps.logBucket;
40
88
  let accessLogsBucket;
41
89
  let accessLogProps = {};
@@ -52,16 +100,24 @@ class DistributionBuilder {
52
100
  logBucket: accessLogsBucket,
53
101
  };
54
102
  }
103
+ const behaviors = resolveBehaviors({
104
+ scope,
105
+ id,
106
+ context: context ?? {},
107
+ defaultOrigin: resolvedOrigin,
108
+ defaultBehavior: userBehavior,
109
+ defaultBehaviorDefaults: defaultBehaviorDefaults ?? {},
110
+ additionalBehaviors: this.#additionalBehaviors,
111
+ });
55
112
  const mergedProps = {
56
113
  ...cdkDefaults,
57
114
  ...accessLogProps,
58
115
  ...distProps,
59
116
  ...(resolvedCertificate ? { certificate: resolvedCertificate } : {}),
60
- defaultBehavior: {
61
- ...defaultBehavior,
62
- ...userBehavior,
63
- origin: resolvedOrigin,
64
- },
117
+ defaultBehavior: behaviors.defaultBehavior,
118
+ ...(Object.keys(behaviors.additionalBehaviors).length > 0
119
+ ? { additionalBehaviors: behaviors.additionalBehaviors }
120
+ : {}),
65
121
  };
66
122
  const distribution = new Distribution(scope, id, mergedProps);
67
123
  // Ensure CloudFront is deleted before the access logs bucket during stack teardown.
@@ -69,10 +125,23 @@ class DistributionBuilder {
69
125
  if (accessLogsBucket) {
70
126
  distribution.node.addDependency(accessLogsBucket);
71
127
  }
72
- const alarms = createDistributionAlarms(scope, id, distribution, alarmConfig, this.#customAlarms);
128
+ const distributionAlarmDefs = alarmConfig === false || alarmConfig?.enabled === false
129
+ ? []
130
+ : resolveDistributionAlarmDefinitions(distribution, alarmConfig);
131
+ const customAlarmDefs = this.#customAlarms.map((b) => b.resolve(distribution));
132
+ const allAlarmDefs = [
133
+ ...distributionAlarmDefs,
134
+ ...behaviors.alarmDefinitions,
135
+ ...customAlarmDefs,
136
+ ];
137
+ if (allAlarmDefs.length > 0) {
138
+ warnIfNotUsEast1(scope);
139
+ }
140
+ const alarms = createAlarms(scope, id, allAlarmDefs);
73
141
  return {
74
142
  distribution,
75
143
  accessLogsBucket,
144
+ functions: behaviors.functions,
76
145
  alarms,
77
146
  };
78
147
  }
@@ -83,26 +152,27 @@ class DistributionBuilder {
83
152
  * This is the entry point for defining a CloudFront distribution component.
84
153
  * The returned builder exposes every {@link DistributionBuilderProps} property
85
154
  * as a fluent setter/getter, plus {@link IDistributionBuilder.origin | origin()}
86
- * for setting the default origin with Ref support. It implements {@link Lifecycle}
87
- * for use with {@link compose}.
155
+ * for setting the default origin with Ref support and
156
+ * {@link IDistributionBuilder.behavior | behavior()} for path-pattern behaviors.
157
+ * It implements {@link Lifecycle} for use with {@link compose}.
88
158
  *
89
159
  * @returns A fluent builder for a CloudFront distribution.
90
160
  *
91
161
  * @example
92
162
  * ```ts
93
163
  * const cdn = createDistributionBuilder()
94
- * .origin(ref("site", (r: BucketBuilderResult) =>
164
+ * .origin(ref<BucketBuilderResult>("site", (r) =>
95
165
  * S3BucketOrigin.withOriginAccessControl(r.bucket)))
96
- * .comment("Community website CDN");
97
- *
98
- * // Use standalone:
99
- * const result = cdn.build(stack, "CDN");
100
- *
101
- * // Or compose into a system:
102
- * const system = compose(
103
- * { site: createBucketBuilder(), cdn },
104
- * { site: [], cdn: ["site"] },
105
- * );
166
+ * .defaultBehavior({
167
+ * functions: [{
168
+ * eventType: FunctionEventType.VIEWER_REQUEST,
169
+ * code: FunctionCode.fromFile({ filePath: "src/edge/rewrite.js" }),
170
+ * }],
171
+ * })
172
+ * .behavior("/api/*", {
173
+ * origin: apiOrigin,
174
+ * cachePolicy: CachePolicy.CACHING_DISABLED,
175
+ * });
106
176
  * ```
107
177
  */
108
178
  export function createDistributionBuilder() {
@@ -1 +1 @@
1
- {"version":3,"file":"distribution-builder.js","sourceRoot":"","sources":["../src/distribution-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"distribution-builder.js","sourceRoot":"","sources":["../src/distribution-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAUb,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAe,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EACL,OAAO,EAGP,OAAO,GAER,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mCAAmC,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AA0QhE;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,KAAiB;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC;QAAE,OAAO;IACvC,IAAI,MAAM,KAAK,WAAW;QAAE,OAAO;IACnC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,CAChC,uCAAuC,EACvC,+EAA+E;QAC7E,OAAO,MAAM,8DAA8D;QAC3E,+EAA+E;QAC/E,yBAAyB,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,mBAAmB;IACvB,KAAK,GAAsC,EAAE,CAAC;IAC9C,OAAO,CAAuB;IACrB,oBAAoB,GAAG,IAAI,GAAG,EAAoC,CAAC;IACnE,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,aAAa,GAA2C,EAAE,CAAC;IAEpE,QAAQ,CACN,GAAW,EACX,SAEyC;QAEzC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,sBAAsB,CAAe,GAAG,CAAC,CAAC,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,MAA2B;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAmB,EAAE,MAAgC;QAC5D,IAAI,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CACb,mDAAmD,WAAW,uBAAuB,CACtF,CAAC;QACJ,CAAC;QACD,2EAA2E;QAC3E,wEAAwE;QACxE,4EAA4E;QAC5E,sDAAsD;QACtD,MAAM,IAAI,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAC1C,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,sCAAsC,WAAW,sCAAsC;gBACrF,UAAU,IAAI,UAAU,eAAe,4BAA4B,CACtE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC3C,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CACH,KAAiB,EACjB,EAAU,EACV,OAAgC;QAEhC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEvF,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,wBAAwB,EAAE,wBAAwB;gBAChD,iDAAiD,CACpD,CAAC;QACJ,CAAC;QAED,MAAM,EACJ,aAAa,EACb,WAAW,EACX,eAAe,EAAE,YAAY,EAC7B,iBAAiB,EAAE,WAAW,EAC9B,GAAG,SAAS,EACb,GAAG,IAAI,CAAC,KAAK,CAAC;QACf,MAAM,mBAAmB,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1F,MAAM,EACJ,aAAa,EAAE,oBAAoB,EACnC,eAAe,EAAE,uBAAuB,EACxC,GAAG,WAAW,EACf,GAAG,qBAAqB,CAAC;QAC1B,MAAM,aAAa,GAAG,CAAC,aAAa,IAAI,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;QAEtF,IAAI,gBAAoC,CAAC;QACzC,IAAI,cAAc,GAAG,EAAE,CAAC;QAExB,IAAI,aAAa,EAAE,CAAC;YAClB,gBAAgB,GAAG,mBAAmB,EAAE;iBACrC,aAAa,CAAC,KAAK,CAAC;iBACpB,SAAS,CAAC,KAAK,CAAC;gBACjB,oFAAoF;iBACnF,eAAe,CAAC,eAAe,CAAC,sBAAsB,CAAC;iBACvD,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC;iBACnC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC;YAC1C,cAAc,GAAG;gBACf,aAAa,EAAE,IAAI;gBACnB,SAAS,EAAE,gBAAgB;aAC5B,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,gBAAgB,CAAC;YACjC,KAAK;YACL,EAAE;YACF,OAAO,EAAE,OAAO,IAAI,EAAE;YACtB,aAAa,EAAE,cAAc;YAC7B,eAAe,EAAE,YAAY;YAC7B,uBAAuB,EAAE,uBAAuB,IAAI,EAAE;YACtD,mBAAmB,EAAE,IAAI,CAAC,oBAAoB;SAC/C,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG;YAClB,GAAG,WAAW;YACd,GAAG,cAAc;YACjB,GAAG,SAAS;YACZ,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,eAAe,EAAE,SAAS,CAAC,eAAe;YAC1C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,MAAM,GAAG,CAAC;gBACvD,CAAC,CAAC,EAAE,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,EAAE;gBACxD,CAAC,CAAC,EAAE,CAAC;SACa,CAAC;QAEvB,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAE9D,oFAAoF;QACpF,gGAAgG;QAChG,IAAI,gBAAgB,EAAE,CAAC;YACrB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,qBAAqB,GACzB,WAAW,KAAK,KAAK,IAAI,WAAW,EAAE,OAAO,KAAK,KAAK;YACrD,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,mCAAmC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QACrE,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QAE/E,MAAM,YAAY,GAAG;YACnB,GAAG,qBAAqB;YACxB,GAAG,SAAS,CAAC,gBAAgB;YAC7B,GAAG,eAAe;SACnB,CAAC;QAEF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,YAAY,CAAC,CAAC;QAErD,OAAO;YACL,YAAY;YACZ,gBAAgB;YAChB,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,MAAM;SACP,CAAC;IACJ,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO,OAAO,CAAgD,mBAAmB,CAAC,CAAC;AACrF,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { createDistributionBuilder, type DistributionBuilderProps, type DistributionBuilderResult, type IDistributionBuilder, } from "./distribution-builder.js";
2
- export { DISTRIBUTION_DEFAULTS } from "./defaults.js";
3
- export { type DistributionAlarmConfig } from "./alarm-config.js";
4
- export { DISTRIBUTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
1
+ export { createDistributionBuilder, type DistributionBuilderProps, type DistributionBuilderResult, type IDistributionBuilder, type DefaultBehaviorConfig, type AdditionalBehaviorConfig, type InlineFunctionDefinition, } from "./distribution-builder.js";
2
+ export { DISTRIBUTION_DEFAULTS, INLINE_FUNCTION_DEFAULTS } from "./defaults.js";
3
+ export { type DistributionAlarmConfig, type FunctionAlarmConfig } from "./alarm-config.js";
4
+ export { DISTRIBUTION_ALARM_DEFAULTS, FUNCTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,GAC9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,KAAK,uBAAuB,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { createDistributionBuilder, } from "./distribution-builder.js";
2
- export { DISTRIBUTION_DEFAULTS } from "./defaults.js";
3
- export { DISTRIBUTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
2
+ export { DISTRIBUTION_DEFAULTS, INLINE_FUNCTION_DEFAULTS } from "./defaults.js";
3
+ export { DISTRIBUTION_ALARM_DEFAULTS, FUNCTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,GAI1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,GAO1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { type AddBehaviorOptions, type BehaviorOptions, Function as CfFunction, type IOrigin } from "aws-cdk-lib/aws-cloudfront";
2
+ import type { IConstruct } from "constructs";
3
+ import type { AlarmDefinition } from "@composurecdk/cloudwatch";
4
+ import type { AdditionalBehaviorConfig, DefaultBehaviorConfig } from "./distribution-builder.js";
5
+ /**
6
+ * Input required to resolve the default behavior, all additional behaviors,
7
+ * and any inline CloudFront Functions into concrete CDK objects.
8
+ */
9
+ export interface ResolveBehaviorsInput {
10
+ /** The construct scope under which functions and behaviors are created. */
11
+ scope: IConstruct;
12
+ /** The distribution's construct id — used as a prefix for Function ids. */
13
+ id: string;
14
+ /** Compose context forwarded to {@link resolve}. Empty record if unused. */
15
+ context: Record<string, object>;
16
+ /** The already-resolved default origin. */
17
+ defaultOrigin: IOrigin;
18
+ /** User-provided default-behavior config (may be undefined). */
19
+ defaultBehavior: DefaultBehaviorConfig | undefined;
20
+ /** The builder's default-behavior defaults, applied before user props. */
21
+ defaultBehaviorDefaults: Partial<AddBehaviorOptions>;
22
+ /**
23
+ * Ordered map of path-pattern → config for additional behaviors. Origins
24
+ * are resolved here via {@link resolve}.
25
+ */
26
+ additionalBehaviors: Map<string, AdditionalBehaviorConfig>;
27
+ }
28
+ /**
29
+ * Output of {@link resolveBehaviors}: concrete behavior options ready to pass
30
+ * to the CDK `Distribution` constructor, plus any owned {@link CfFunction}
31
+ * instances and their alarm definitions.
32
+ */
33
+ export interface ResolveBehaviorsResult {
34
+ /** Concrete `BehaviorOptions` for the default cache behavior. */
35
+ defaultBehavior: BehaviorOptions;
36
+ /** Concrete `BehaviorOptions` keyed by path pattern, in insertion order. */
37
+ additionalBehaviors: Record<string, BehaviorOptions>;
38
+ /**
39
+ * Owned inline CloudFront Functions, keyed by
40
+ * `<behaviorScope><EventType>` — e.g. `defaultBehaviorViewerRequest`.
41
+ */
42
+ functions: Record<string, CfFunction>;
43
+ /** Alarm definitions for the owned inline functions. */
44
+ alarmDefinitions: AlarmDefinition[];
45
+ }
46
+ /**
47
+ * Materializes the default and additional cache behaviors into CDK-ready
48
+ * `BehaviorOptions`, creating any inline CloudFront Functions along the way
49
+ * and producing their path-scoped alarm definitions.
50
+ *
51
+ * Enforces CloudFront invariants at configure time: at most one function per
52
+ * event type per behavior, and `keyValueStore` requires `FunctionRuntime.JS_2_0`.
53
+ */
54
+ export declare function resolveBehaviors(input: ResolveBehaviorsInput): ResolveBehaviorsResult;
55
+ //# sourceMappingURL=resolve-behaviors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-behaviors.d.ts","sourceRoot":"","sources":["../src/resolve-behaviors.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,QAAQ,IAAI,UAAU,EAKtB,KAAK,OAAO,EACb,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAQhE,OAAO,KAAK,EACV,wBAAwB,EACxB,qBAAqB,EAEtB,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,KAAK,EAAE,UAAU,CAAC;IAElB,2EAA2E;IAC3E,EAAE,EAAE,MAAM,CAAC;IAEX,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,2CAA2C;IAC3C,aAAa,EAAE,OAAO,CAAC;IAEvB,gEAAgE;IAChE,eAAe,EAAE,qBAAqB,GAAG,SAAS,CAAC;IAEnD,0EAA0E;IAC1E,uBAAuB,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAErD;;;OAGG;IACH,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CAC5D;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,eAAe,EAAE,eAAe,CAAC;IAEjC,4EAA4E;IAC5E,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAErD;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAEtC,wDAAwD;IACxD,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC;AAiDD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CA+DrF"}
@@ -0,0 +1,96 @@
1
+ import { Function as CfFunction, FunctionRuntime, } from "aws-cdk-lib/aws-cloudfront";
2
+ import { resolve } from "@composurecdk/core";
3
+ import { behaviorFunctionKeyPrefix, eventTypePascal, pathPatternSlug, resolveBehaviorFunctionAlarmDefinitions, } from "./behavior-function-alarms.js";
4
+ import { INLINE_FUNCTION_DEFAULTS } from "./defaults.js";
5
+ function scopeLabel(pathPattern) {
6
+ return pathPattern === null ? "default behavior" : `behavior "${pathPattern}"`;
7
+ }
8
+ function behaviorIdScope(pathPattern) {
9
+ return pathPattern === null ? "DefaultBehavior" : `Behavior${pathPatternSlug(pathPattern)}`;
10
+ }
11
+ function assertUniqueEventTypes(functions, pathPattern) {
12
+ const seen = new Set();
13
+ for (const fn of functions) {
14
+ if (seen.has(fn.eventType)) {
15
+ throw new Error(`DistributionBuilder: ${scopeLabel(pathPattern)} has multiple functions for eventType "${fn.eventType}". ` +
16
+ `CloudFront allows at most one function per event type per behavior.`);
17
+ }
18
+ seen.add(fn.eventType);
19
+ }
20
+ }
21
+ function omit(obj, ...keys) {
22
+ const skip = new Set(keys);
23
+ const out = {};
24
+ for (const [k, v] of Object.entries(obj)) {
25
+ if (!skip.has(k))
26
+ out[k] = v;
27
+ }
28
+ return out;
29
+ }
30
+ function assertKeyValueStoreRuntime(def, pathPattern) {
31
+ if (!def.keyValueStore)
32
+ return;
33
+ const effectiveRuntime = def.runtime ?? INLINE_FUNCTION_DEFAULTS.runtime;
34
+ if (effectiveRuntime !== FunctionRuntime.JS_2_0) {
35
+ throw new Error(`DistributionBuilder: ${scopeLabel(pathPattern)} function (${def.eventType}) uses a ` +
36
+ `keyValueStore, which requires FunctionRuntime.JS_2_0.`);
37
+ }
38
+ }
39
+ /**
40
+ * Materializes the default and additional cache behaviors into CDK-ready
41
+ * `BehaviorOptions`, creating any inline CloudFront Functions along the way
42
+ * and producing their path-scoped alarm definitions.
43
+ *
44
+ * Enforces CloudFront invariants at configure time: at most one function per
45
+ * event type per behavior, and `keyValueStore` requires `FunctionRuntime.JS_2_0`.
46
+ */
47
+ export function resolveBehaviors(input) {
48
+ const { scope, id, context, defaultOrigin, defaultBehavior, defaultBehaviorDefaults } = input;
49
+ const functions = {};
50
+ const alarmDefinitions = [];
51
+ const buildInlineFunctions = (pathPattern, definitions) => {
52
+ if (!definitions || definitions.length === 0)
53
+ return [];
54
+ assertUniqueEventTypes(definitions, pathPattern);
55
+ const scopeId = behaviorIdScope(pathPattern);
56
+ const associations = [];
57
+ for (const def of definitions) {
58
+ assertKeyValueStoreRuntime(def, pathPattern);
59
+ const { eventType } = def;
60
+ const fnId = `${id}${scopeId}${eventTypePascal(eventType)}Fn`;
61
+ const fn = new CfFunction(scope, fnId, {
62
+ ...INLINE_FUNCTION_DEFAULTS,
63
+ ...omit(def, "eventType", "recommendedAlarms"),
64
+ });
65
+ functions[behaviorFunctionKeyPrefix(pathPattern, eventType)] = fn;
66
+ associations.push({ function: fn, eventType });
67
+ alarmDefinitions.push(...resolveBehaviorFunctionAlarmDefinitions(pathPattern, eventType, fn, def.recommendedAlarms));
68
+ }
69
+ return associations;
70
+ };
71
+ const defaultAssociations = buildInlineFunctions(null, defaultBehavior?.functions);
72
+ const userDefaultBehavior = omit(defaultBehavior ?? {}, "functions");
73
+ const resolvedDefaultBehavior = {
74
+ ...defaultBehaviorDefaults,
75
+ ...userDefaultBehavior,
76
+ ...(defaultAssociations.length > 0 ? { functionAssociations: defaultAssociations } : {}),
77
+ origin: defaultOrigin,
78
+ };
79
+ const resolvedAdditionalBehaviors = {};
80
+ for (const [pathPattern, config] of input.additionalBehaviors) {
81
+ const resolvedOrigin = resolve(config.origin, context);
82
+ const associations = buildInlineFunctions(pathPattern, config.functions);
83
+ resolvedAdditionalBehaviors[pathPattern] = {
84
+ ...omit(config, "functions", "origin"),
85
+ origin: resolvedOrigin,
86
+ ...(associations.length > 0 ? { functionAssociations: associations } : {}),
87
+ };
88
+ }
89
+ return {
90
+ defaultBehavior: resolvedDefaultBehavior,
91
+ additionalBehaviors: resolvedAdditionalBehaviors,
92
+ functions,
93
+ alarmDefinitions,
94
+ };
95
+ }
96
+ //# sourceMappingURL=resolve-behaviors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-behaviors.js","sourceRoot":"","sources":["../src/resolve-behaviors.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,IAAI,UAAU,EAItB,eAAe,GAEhB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,uCAAuC,GACxC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AA2DzD,SAAS,UAAU,CAAC,WAA0B;IAC5C,OAAO,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,aAAa,WAAW,GAAG,CAAC;AACjF,CAAC;AAED,SAAS,eAAe,CAAC,WAA0B;IACjD,OAAO,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAW,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;AAC9F,CAAC;AAED,SAAS,sBAAsB,CAC7B,SAAqC,EACrC,WAA0B;IAE1B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC1C,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,wBAAwB,UAAU,CAAC,WAAW,CAAC,0CAA0C,EAAE,CAAC,SAAS,KAAK;gBACxG,qEAAqE,CACxE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAsC,GAAM,EAAE,GAAG,IAAS;IACrE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAc,IAAI,CAAC,CAAC;IACxC,MAAM,GAAG,GAAiC,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAiB,CAAC;AAC3B,CAAC;AAED,SAAS,0BAA0B,CACjC,GAA6B,EAC7B,WAA0B;IAE1B,IAAI,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO;IAC/B,MAAM,gBAAgB,GAAG,GAAG,CAAC,OAAO,IAAI,wBAAwB,CAAC,OAAO,CAAC;IACzE,IAAI,gBAAgB,KAAK,eAAe,CAAC,MAAM,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,wBAAwB,UAAU,CAAC,WAAW,CAAC,cAAc,GAAG,CAAC,SAAS,WAAW;YACnF,uDAAuD,CAC1D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IAC3D,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,uBAAuB,EAAE,GAAG,KAAK,CAAC;IAE9F,MAAM,SAAS,GAA+B,EAAE,CAAC;IACjD,MAAM,gBAAgB,GAAsB,EAAE,CAAC;IAE/C,MAAM,oBAAoB,GAAG,CAC3B,WAA0B,EAC1B,WAAmD,EAC5B,EAAE;QACzB,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACxD,sBAAsB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAC7C,MAAM,YAAY,GAA0B,EAAE,CAAC;QAC/C,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,0BAA0B,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YAC7C,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC;YAC1B,MAAM,IAAI,GAAG,GAAG,EAAE,GAAG,OAAO,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC;YAC9D,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE;gBACrC,GAAG,wBAAwB;gBAC3B,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,mBAAmB,CAAC;aAC9B,CAAC,CAAC;YACpB,SAAS,CAAC,yBAAyB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;YAClE,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;YAC/C,gBAAgB,CAAC,IAAI,CACnB,GAAG,uCAAuC,CACxC,WAAW,EACX,SAAS,EACT,EAAE,EACF,GAAG,CAAC,iBAAiB,CACtB,CACF,CAAC;QACJ,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,oBAAoB,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;IACnF,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;IAErE,MAAM,uBAAuB,GAAoB;QAC/C,GAAG,uBAAuB;QAC1B,GAAG,mBAAmB;QACtB,GAAG,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,MAAM,EAAE,aAAa;KACtB,CAAC;IAEF,MAAM,2BAA2B,GAAoC,EAAE,CAAC;IACxE,KAAK,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAC;QAC9D,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,YAAY,GAAG,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACzE,2BAA2B,CAAC,WAAW,CAAC,GAAG;YACzC,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC;YACtC,MAAM,EAAE,cAAc;YACtB,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,eAAe,EAAE,uBAAuB;QACxC,mBAAmB,EAAE,2BAA2B;QAChD,SAAS;QACT,gBAAgB;KACjB,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@composurecdk/cloudfront",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Composable CloudFront distribution builder with well-architected defaults",
5
5
  "repository": {
6
6
  "type": "git",