@fjall/components-infrastructure 0.80.4 → 0.82.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 (52) hide show
  1. package/dist/lib/__tests__/setup.js +1 -78
  2. package/dist/lib/app.d.ts +5 -0
  3. package/dist/lib/app.js +29 -1
  4. package/dist/lib/config/aws/ecrDefaultImage.js +23 -21
  5. package/dist/lib/patterns/aws/compute.d.ts +29 -21
  6. package/dist/lib/patterns/aws/compute.js +10 -3
  7. package/dist/lib/patterns/aws/database.d.ts +1 -0
  8. package/dist/lib/patterns/aws/database.js +33 -3
  9. package/dist/lib/patterns/aws/storage.d.ts +1 -0
  10. package/dist/lib/patterns/aws/storage.js +23 -1
  11. package/dist/lib/resources/aws/compute/ecs.d.ts +50 -2
  12. package/dist/lib/resources/aws/compute/ecs.js +134 -18
  13. package/dist/lib/resources/aws/compute/ecsFreeTier.d.ts +2 -1
  14. package/dist/lib/resources/aws/compute/ecsFreeTier.js +1 -352
  15. package/dist/lib/resources/aws/compute/ecsSpot.d.ts +2 -1
  16. package/dist/lib/resources/aws/compute/ecsSpot.js +1 -332
  17. package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.js +1 -180
  18. package/dist/lib/resources/aws/monitoring/monitoringRole.js +61 -4
  19. package/dist/lib/resources/aws/utilities/cfnOutput.js +1 -13
  20. package/package.json +3 -3
  21. package/dist/lib/patterns/aws/cdn.d.ts +0 -133
  22. package/dist/lib/patterns/aws/cdn.js +0 -216
  23. package/dist/lib/patterns/aws/dynamodb.d.ts +0 -66
  24. package/dist/lib/patterns/aws/dynamodb.js +0 -106
  25. package/dist/lib/patterns/aws/loadBalancer.d.ts +0 -163
  26. package/dist/lib/patterns/aws/loadBalancer.js +0 -278
  27. package/dist/lib/patterns/aws/queue.d.ts +0 -61
  28. package/dist/lib/patterns/aws/queue.js +0 -103
  29. package/dist/lib/resources/aws/cdn/cloudFront.d.ts +0 -65
  30. package/dist/lib/resources/aws/cdn/cloudFront.js +0 -135
  31. package/dist/lib/resources/aws/cdn/index.d.ts +0 -1
  32. package/dist/lib/resources/aws/cdn/index.js +0 -18
  33. package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.d.ts +0 -20
  34. package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.js +0 -180
  35. package/dist/lib/resources/aws/database/dynamodb.d.ts +0 -70
  36. package/dist/lib/resources/aws/database/dynamodb.js +0 -170
  37. package/dist/lib/resources/aws/database/rdsDeletionWaiter.d.ts +0 -33
  38. package/dist/lib/resources/aws/database/rdsDeletionWaiter.js +0 -74
  39. package/dist/lib/resources/aws/messaging/index.d.ts +0 -1
  40. package/dist/lib/resources/aws/messaging/index.js +0 -18
  41. package/dist/lib/resources/aws/messaging/sqs.d.ts +0 -65
  42. package/dist/lib/resources/aws/messaging/sqs.js +0 -195
  43. package/dist/lib/resources/aws/networking/vpcEndpoint.d.ts +0 -20
  44. package/dist/lib/resources/aws/networking/vpcEndpoint.js +0 -59
  45. package/dist/lib/resources/aws/networking/vpcEndpoints.d.ts +0 -71
  46. package/dist/lib/resources/aws/networking/vpcEndpoints.js +0 -125
  47. package/dist/lib/resources/aws/utilities/cfnOutput.test.d.ts +0 -1
  48. package/dist/lib/resources/aws/utilities/cfnOutput.test.js +0 -102
  49. package/dist/lib/utils/sanitizeCfnKey.d.ts +0 -5
  50. package/dist/lib/utils/sanitizeCfnKey.js +0 -11
  51. package/dist/lib/utils/tagResource.d.ts +0 -24
  52. package/dist/lib/utils/tagResource.js +0 -30
@@ -1,163 +0,0 @@
1
- import { Construct } from "constructs";
2
- import { ApplicationLoadBalancer, ApplicationListener, ApplicationTargetGroup, type IApplicationTargetGroup } from "aws-cdk-lib/aws-elasticloadbalancingv2";
3
- import { Certificate } from "aws-cdk-lib/aws-certificatemanager";
4
- import { Connections, type IConnectable, type IVpc, Port, SecurityGroup } from "aws-cdk-lib/aws-ec2";
5
- import type App from "../../app";
6
- import { HostedZone as FjallHostedZone } from "./hostedZone";
7
- /**
8
- * Routing configuration for registering services with the load balancer.
9
- */
10
- export interface LoadBalancerRoutingConfig {
11
- /**
12
- * Path pattern(s) to match. Examples: "/api/*", ["/api/*", "/v1/*"]
13
- */
14
- path?: string | string[];
15
- /**
16
- * Host pattern(s) to match. Examples: "api.example.com", ["api.example.com", "www.example.com"]
17
- */
18
- host?: string | string[];
19
- /**
20
- * Priority for this routing rule. Lower numbers = higher priority.
21
- * Must be unique per listener. Range: 1-50000.
22
- */
23
- priority: number;
24
- /**
25
- * Health check path for this target group. Default: "/"
26
- */
27
- healthCheckPath?: string;
28
- }
29
- /**
30
- * Health check configuration for the load balancer.
31
- */
32
- export interface LoadBalancerHealthCheckConfig {
33
- /** Health check path. Default: "/" */
34
- path?: string;
35
- /** Interval between health checks in seconds. Default: 30 */
36
- interval?: number;
37
- /** Health check timeout in seconds. Default: 5 */
38
- timeout?: number;
39
- /** Number of consecutive successes before healthy. Default: 2 */
40
- healthyThreshold?: number;
41
- /** Number of consecutive failures before unhealthy. Default: 3 */
42
- unhealthyThreshold?: number;
43
- }
44
- /**
45
- * Domain configuration for HTTPS and DNS.
46
- */
47
- export interface LoadBalancerDomainConfig {
48
- /** Domain name (e.g., "api.example.com") */
49
- name: string;
50
- /** Existing hosted zone. If omitted, creates new one. */
51
- hostedZone?: FjallHostedZone;
52
- /** Existing certificate. If omitted, creates new one with DNS validation. */
53
- certificate?: Certificate;
54
- }
55
- /**
56
- * Properties for LoadBalancerFactory.build()
57
- */
58
- export interface ILoadBalancerProps {
59
- /** VPC to place the load balancer in. Default: app's default VPC */
60
- vpc?: IVpc;
61
- /**
62
- * Domain configuration for HTTPS.
63
- * - string: Domain name (creates hosted zone and certificate)
64
- * - LoadBalancerDomainConfig: Full configuration
65
- * - Omit: HTTP only
66
- */
67
- domain?: string | LoadBalancerDomainConfig;
68
- /**
69
- * Whether the load balancer is internet-facing.
70
- * Default: true
71
- */
72
- public?: boolean;
73
- /**
74
- * Default health check configuration.
75
- * Individual services can override this.
76
- */
77
- healthCheck?: LoadBalancerHealthCheckConfig;
78
- }
79
- /**
80
- * Internal props with resolved VPC.
81
- */
82
- interface LoadBalancerPropsResolved extends ILoadBalancerProps {
83
- vpc: IVpc;
84
- }
85
- /**
86
- * Factory for creating LoadBalancer constructs.
87
- *
88
- * @example
89
- * // Simple HTTP load balancer
90
- * const alb = app.addCompute(
91
- * LoadBalancerFactory.build("MainALB", {})
92
- * );
93
- *
94
- * @example
95
- * // HTTPS load balancer with domain
96
- * const alb = app.addCompute(
97
- * LoadBalancerFactory.build("MainALB", {
98
- * domain: "app.example.com"
99
- * })
100
- * );
101
- *
102
- * @example
103
- * // Internal load balancer
104
- * const alb = app.addCompute(
105
- * LoadBalancerFactory.build("InternalALB", {
106
- * public: false
107
- * })
108
- * );
109
- */
110
- export declare class LoadBalancerFactory {
111
- static build(id: string, props: ILoadBalancerProps): (app: App, scope: Construct) => LoadBalancer;
112
- }
113
- /**
114
- * Application Load Balancer construct that can be shared across multiple ECS services.
115
- *
116
- * Use LoadBalancerFactory.build() to create instances via app.addCompute().
117
- */
118
- export declare class LoadBalancer extends Construct implements IConnectable {
119
- readonly alb: ApplicationLoadBalancer;
120
- readonly listener: ApplicationListener;
121
- readonly securityGroup: SecurityGroup;
122
- readonly url: string;
123
- readonly connections: Connections;
124
- private readonly hostedZone?;
125
- private readonly certificate?;
126
- private readonly defaultHealthCheck;
127
- private readonly isHttps;
128
- constructor(scope: Construct, id: string, props: LoadBalancerPropsResolved);
129
- /**
130
- * Register a target group with routing rules.
131
- * Called internally by EcsCluster when loadBalancer.target is specified.
132
- *
133
- * @param targetGroup - The target group to register
134
- * @param routing - Routing configuration (path, host, priority)
135
- */
136
- registerTargetGroup(targetGroup: IApplicationTargetGroup, routing: LoadBalancerRoutingConfig): void;
137
- /**
138
- * Create a target group for an ECS service.
139
- * Returns the target group for the service to register with.
140
- *
141
- * @param id - Unique identifier for the target group
142
- * @param port - Container port
143
- * @param vpc - VPC for the target group
144
- * @param healthCheckPath - Optional health check path override
145
- */
146
- createTargetGroup(id: string, port: number, vpc: IVpc, healthCheckPath?: string): ApplicationTargetGroup;
147
- /**
148
- * Allow traffic from this load balancer to a connectable resource.
149
- */
150
- allowTo(connectable: IConnectable, port?: Port): void;
151
- private normaliseDomainConfig;
152
- private setupDomain;
153
- private truncateName;
154
- /**
155
- * Get the DNS name of the load balancer.
156
- */
157
- getDnsName(): string;
158
- /**
159
- * Get the ARN of the load balancer.
160
- */
161
- getArn(): string;
162
- }
163
- export {};
@@ -1,278 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LoadBalancer = exports.LoadBalancerFactory = void 0;
4
- const constructs_1 = require("constructs");
5
- const aws_elasticloadbalancingv2_1 = require("aws-cdk-lib/aws-elasticloadbalancingv2");
6
- const aws_certificatemanager_1 = require("aws-cdk-lib/aws-certificatemanager");
7
- const aws_route53_1 = require("aws-cdk-lib/aws-route53");
8
- const aws_route53_targets_1 = require("aws-cdk-lib/aws-route53-targets");
9
- const aws_ec2_1 = require("aws-cdk-lib/aws-ec2");
10
- const aws_cdk_lib_1 = require("aws-cdk-lib");
11
- const cfnOutput_1 = require("../../resources/aws/utilities/cfnOutput");
12
- const hostedZone_1 = require("./hostedZone");
13
- /**
14
- * Validates load balancer props and logs warnings for misconfigured options.
15
- */
16
- function validateLoadBalancerProps(props) {
17
- if (props.healthCheck) {
18
- if (props.healthCheck.interval !== undefined) {
19
- if (props.healthCheck.interval < 5 || props.healthCheck.interval > 300) {
20
- throw new Error("Health check interval must be between 5 and 300 seconds.");
21
- }
22
- }
23
- if (props.healthCheck.timeout !== undefined) {
24
- if (props.healthCheck.timeout < 2 || props.healthCheck.timeout > 120) {
25
- throw new Error("Health check timeout must be between 2 and 120 seconds.");
26
- }
27
- }
28
- }
29
- }
30
- /**
31
- * Factory for creating LoadBalancer constructs.
32
- *
33
- * @example
34
- * // Simple HTTP load balancer
35
- * const alb = app.addCompute(
36
- * LoadBalancerFactory.build("MainALB", {})
37
- * );
38
- *
39
- * @example
40
- * // HTTPS load balancer with domain
41
- * const alb = app.addCompute(
42
- * LoadBalancerFactory.build("MainALB", {
43
- * domain: "app.example.com"
44
- * })
45
- * );
46
- *
47
- * @example
48
- * // Internal load balancer
49
- * const alb = app.addCompute(
50
- * LoadBalancerFactory.build("InternalALB", {
51
- * public: false
52
- * })
53
- * );
54
- */
55
- class LoadBalancerFactory {
56
- static build(id, props) {
57
- return (app, scope) => {
58
- validateLoadBalancerProps(props);
59
- const resolvedProps = {
60
- ...props,
61
- vpc: props.vpc || app.getVpc()
62
- };
63
- return new LoadBalancer(scope, id, resolvedProps);
64
- };
65
- }
66
- }
67
- exports.LoadBalancerFactory = LoadBalancerFactory;
68
- /**
69
- * Application Load Balancer construct that can be shared across multiple ECS services.
70
- *
71
- * Use LoadBalancerFactory.build() to create instances via app.addCompute().
72
- */
73
- class LoadBalancer extends constructs_1.Construct {
74
- constructor(scope, id, props) {
75
- super(scope, id);
76
- this.defaultHealthCheck = props.healthCheck || {};
77
- this.isHttps = !!props.domain;
78
- // Create security group
79
- this.securityGroup = new aws_ec2_1.SecurityGroup(this, "SecurityGroup", {
80
- vpc: props.vpc,
81
- description: `Security group for ${id} load balancer`,
82
- allowAllOutbound: true
83
- });
84
- // Allow inbound traffic
85
- const inboundPort = this.isHttps ? 443 : 80;
86
- this.securityGroup.addIngressRule({ connections: { allowFromAnyIpv4: () => { } } }, aws_ec2_1.Port.tcp(inboundPort), `Allow inbound ${this.isHttps ? "HTTPS" : "HTTP"}`);
87
- // Create ALB
88
- const loadBalancerName = this.truncateName(`${id}ALB`, 32);
89
- this.alb = new aws_elasticloadbalancingv2_1.ApplicationLoadBalancer(this, "ALB", {
90
- vpc: props.vpc,
91
- internetFacing: props.public !== false,
92
- securityGroup: this.securityGroup,
93
- loadBalancerName,
94
- vpcSubnets: {
95
- subnetType: props.public !== false ? aws_ec2_1.SubnetType.PUBLIC : aws_ec2_1.SubnetType.PRIVATE_WITH_EGRESS
96
- }
97
- });
98
- // Set up domain if configured
99
- if (props.domain) {
100
- const domainConfig = this.normaliseDomainConfig(props.domain);
101
- this.setupDomain(domainConfig);
102
- }
103
- // Create listener
104
- if (this.isHttps && this.certificate) {
105
- this.listener = this.alb.addListener("Listener", {
106
- port: 443,
107
- protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTPS,
108
- certificates: [this.certificate]
109
- });
110
- // Add HTTP redirect
111
- this.alb.addListener("HttpRedirect", {
112
- port: 80,
113
- protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP,
114
- defaultAction: {
115
- redirect: {
116
- protocol: "HTTPS",
117
- port: "443",
118
- permanent: true
119
- }
120
- }
121
- });
122
- }
123
- else {
124
- this.listener = this.alb.addListener("Listener", {
125
- port: 80,
126
- protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP
127
- });
128
- }
129
- // Add default action (returns 503 if no targets match)
130
- this.listener.addAction("DefaultAction", {
131
- action: {
132
- fixedResponse: {
133
- statusCode: 503,
134
- contentType: "text/plain",
135
- messageBody: "No service available"
136
- }
137
- }
138
- });
139
- // Set URL
140
- this.url = this.isHttps
141
- ? `https://${this.alb.loadBalancerDnsName}`
142
- : `http://${this.alb.loadBalancerDnsName}`;
143
- // Set up connections
144
- this.connections = new aws_ec2_1.Connections({
145
- securityGroups: [this.securityGroup],
146
- defaultPort: aws_ec2_1.Port.tcp(inboundPort)
147
- });
148
- // Outputs
149
- new cfnOutput_1.CfnOutput(this, "LoadBalancerDnsName", {
150
- key: `${id}LoadBalancerDnsName`,
151
- exportName: `${id}LoadBalancerDnsName`,
152
- value: this.alb.loadBalancerDnsName
153
- });
154
- new cfnOutput_1.CfnOutput(this, "LoadBalancerUrl", {
155
- key: `${id}LoadBalancerUrl`,
156
- exportName: `${id}LoadBalancerUrl`,
157
- value: this.url,
158
- description: `Load Balancer URL for ${id}`
159
- });
160
- new cfnOutput_1.CfnOutput(this, "LoadBalancerArn", {
161
- key: `${id}LoadBalancerArn`,
162
- exportName: `${id}LoadBalancerArn`,
163
- value: this.alb.loadBalancerArn,
164
- description: `Load Balancer ARN for ${id}`
165
- });
166
- }
167
- /**
168
- * Register a target group with routing rules.
169
- * Called internally by EcsCluster when loadBalancer.target is specified.
170
- *
171
- * @param targetGroup - The target group to register
172
- * @param routing - Routing configuration (path, host, priority)
173
- */
174
- registerTargetGroup(targetGroup, routing) {
175
- const conditions = [];
176
- if (routing.path) {
177
- const paths = Array.isArray(routing.path) ? routing.path : [routing.path];
178
- conditions.push(aws_elasticloadbalancingv2_1.ListenerCondition.pathPatterns(paths));
179
- }
180
- if (routing.host) {
181
- const hosts = Array.isArray(routing.host) ? routing.host : [routing.host];
182
- conditions.push(aws_elasticloadbalancingv2_1.ListenerCondition.hostHeaders(hosts));
183
- }
184
- if (conditions.length === 0) {
185
- throw new Error("At least one routing condition (path or host) must be specified.");
186
- }
187
- this.listener.addTargetGroups(`Rule${routing.priority}`, {
188
- targetGroups: [targetGroup],
189
- conditions,
190
- priority: routing.priority
191
- });
192
- }
193
- /**
194
- * Create a target group for an ECS service.
195
- * Returns the target group for the service to register with.
196
- *
197
- * @param id - Unique identifier for the target group
198
- * @param port - Container port
199
- * @param vpc - VPC for the target group
200
- * @param healthCheckPath - Optional health check path override
201
- */
202
- createTargetGroup(id, port, vpc, healthCheckPath) {
203
- const targetGroup = new aws_elasticloadbalancingv2_1.ApplicationTargetGroup(this, `${id}TargetGroup`, {
204
- vpc,
205
- port,
206
- protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP,
207
- targetType: aws_elasticloadbalancingv2_1.TargetType.IP,
208
- healthCheck: {
209
- path: healthCheckPath || this.defaultHealthCheck.path || "/",
210
- interval: aws_cdk_lib_1.Duration.seconds(this.defaultHealthCheck.interval || 30),
211
- timeout: aws_cdk_lib_1.Duration.seconds(this.defaultHealthCheck.timeout || 5),
212
- healthyThresholdCount: this.defaultHealthCheck.healthyThreshold || 2,
213
- unhealthyThresholdCount: this.defaultHealthCheck.unhealthyThreshold || 3
214
- }
215
- });
216
- return targetGroup;
217
- }
218
- /**
219
- * Allow traffic from this load balancer to a connectable resource.
220
- */
221
- allowTo(connectable, port) {
222
- this.connections.allowTo(connectable, port || connectable.connections.defaultPort || aws_ec2_1.Port.allTcp());
223
- }
224
- normaliseDomainConfig(domain) {
225
- if (typeof domain === "string") {
226
- return { name: domain };
227
- }
228
- return domain;
229
- }
230
- setupDomain(config) {
231
- // Get or create hosted zone
232
- if (config.hostedZone) {
233
- this.hostedZone = config.hostedZone.getInternalHostedZone();
234
- }
235
- else {
236
- const hostedZone = new hostedZone_1.HostedZone(this, "HostedZone", {
237
- zoneName: config.name
238
- });
239
- this.hostedZone = hostedZone.getInternalHostedZone();
240
- }
241
- // Get or create certificate
242
- if (config.certificate) {
243
- this.certificate = config.certificate;
244
- }
245
- else {
246
- this.certificate = new aws_certificatemanager_1.Certificate(this, "Certificate", {
247
- domainName: config.name,
248
- validation: aws_certificatemanager_1.CertificateValidation.fromDns(this.hostedZone)
249
- });
250
- }
251
- // Create DNS record pointing to ALB
252
- new aws_route53_1.ARecord(this, "AliasRecord", {
253
- zone: this.hostedZone,
254
- recordName: config.name,
255
- target: aws_route53_1.RecordTarget.fromAlias(new aws_route53_targets_1.LoadBalancerTarget(this.alb))
256
- });
257
- }
258
- truncateName(name, maxLength) {
259
- if (name.length <= maxLength) {
260
- return name;
261
- }
262
- return name.substring(0, maxLength).replace(/-+$/, "");
263
- }
264
- /**
265
- * Get the DNS name of the load balancer.
266
- */
267
- getDnsName() {
268
- return this.alb.loadBalancerDnsName;
269
- }
270
- /**
271
- * Get the ARN of the load balancer.
272
- */
273
- getArn() {
274
- return this.alb.loadBalancerArn;
275
- }
276
- }
277
- exports.LoadBalancer = LoadBalancer;
278
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZEJhbGFuY2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL3BhdHRlcm5zL2F3cy9sb2FkQmFsYW5jZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXVDO0FBQ3ZDLHVGQVFnRDtBQUNoRCwrRUFHNEM7QUFDNUMseURBQWtGO0FBQ2xGLHlFQUFxRTtBQUNyRSxpREFPNkI7QUFDN0IsNkNBQXVDO0FBR3ZDLHVFQUFvRTtBQUNwRSw2Q0FBNkQ7QUFxRjdEOztHQUVHO0FBQ0gsU0FBUyx5QkFBeUIsQ0FBQyxLQUF5QjtJQUMxRCxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN0QixJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzdDLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsUUFBUSxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUN2RSxNQUFNLElBQUksS0FBSyxDQUNiLDBEQUEwRCxDQUMzRCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVDLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUNyRSxNQUFNLElBQUksS0FBSyxDQUNiLHlEQUF5RCxDQUMxRCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7QUFDSCxNQUFhLG1CQUFtQjtJQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLEVBQVUsRUFBRSxLQUF5QjtRQUNoRCxPQUFPLENBQUMsR0FBUSxF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ZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcixcbiAgQXBwbGljYXRpb25MaXN0ZW5lcixcbiAgQXBwbGljYXRpb25Qcm90b2NvbCxcbiAgQXBwbGljYXRpb25UYXJnZXRHcm91cCxcbiAgTGlzdGVuZXJDb25kaXRpb24sXG4gIFRhcmdldFR5cGUsXG4gIHR5cGUgSUFwcGxpY2F0aW9uVGFyZ2V0R3JvdXBcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQge1xuICBDZXJ0aWZpY2F0ZSxcbiAgQ2VydGlmaWNhdGVWYWxpZGF0aW9uXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQgeyBBUmVjb3JkLCBSZWNvcmRUYXJnZXQsIHR5cGUgSUhvc3RlZFpvbmUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXJvdXRlNTNcIjtcbmltcG9ydCB7IExvYWRCYWxhbmNlclRhcmdldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzXCI7XG5pbXBvcnQge1xuICBDb25uZWN0aW9ucyxcbiAgdHlwZSBJQ29ubmVjdGFibGUsXG4gIHR5cGUgSVZwYyxcbiAgUG9ydCxcbiAgU2VjdXJpdHlHcm91cCxcbiAgU3VibmV0VHlwZVxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjMlwiO1xuaW1wb3J0IHsgRHVyYXRpb24gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuaW1wb3J0IHR5cGUgQXBwIGZyb20gXCIuLi8uLi9hcHBcIjtcbmltcG9ydCB7IENmbk91dHB1dCB9IGZyb20gXCIuLi8uLi9yZXNvdXJjZXMvYXdzL3V0aWxpdGllcy9jZm5PdXRwdXRcIjtcbmltcG9ydCB7IEhvc3RlZFpvbmUgYXMgRmphbGxIb3N0ZWRab25lIH0gZnJvbSBcIi4vaG9zdGVkWm9uZVwiO1xuXG4vKipcbiAqIFJvdXRpbmcgY29uZmlndXJhdGlvbiBmb3IgcmVnaXN0ZXJpbmcgc2VydmljZXMgd2l0aCB0aGUgbG9hZCBiYWxhbmNlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMb2FkQmFsYW5jZXJSb3V0aW5nQ29uZmlnIHtcbiAgLyoqXG4gICAqIFBhdGggcGF0dGVybihzKSB0byBtYXRjaC4gRXhhbXBsZXM6IFwiL2FwaS8qXCIsIFtcIi9hcGkvKlwiLCBcIi92MS8qXCJdXG4gICAqL1xuICBwYXRoPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIC8qKlxuICAgKiBIb3N0IHBhdHRlcm4ocykgdG8gbWF0Y2guIEV4YW1wbGVzOiBcImFwaS5leGFtcGxlLmNvbVwiLCBbXCJhcGkuZXhhbXBsZS5jb21cIiwgXCJ3d3cuZXhhbXBsZS5jb21cIl1cbiAgICovXG4gIGhvc3Q/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIFByaW9yaXR5IGZvciB0aGlzIHJvdXRpbmcgcnVsZS4gTG93ZXIgbnVtYmVycyA9IGhpZ2hlciBwcmlvcml0eS5cbiAgICogTXVzdCBiZSB1bmlxdWUgcGVyIGxpc3RlbmVyLiBSYW5nZTogMS01MDAwMC5cbiAgICovXG4gIHByaW9yaXR5OiBudW1iZXI7XG4gIC8qKlxuICAgKiBIZWFsdGggY2hlY2sgcGF0aCBmb3IgdGhpcyB0YXJnZXQgZ3JvdXAuIERlZmF1bHQ6IFwiL1wiXG4gICAqL1xuICBoZWFsdGhDaGVja1BhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogSGVhbHRoIGNoZWNrIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBsb2FkIGJhbGFuY2VyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvYWRCYWxhbmNlckhlYWx0aENoZWNrQ29uZmlnIHtcbiAgLyoqIEhlYWx0aCBjaGVjayBwYXRoLiBEZWZhdWx0OiBcIi9cIiAqL1xuICBwYXRoPzogc3RyaW5nO1xuICAvKiogSW50ZXJ2YWwgYmV0d2VlbiBoZWFsdGggY2hlY2tzIGluIHNlY29uZHMuIERlZmF1bHQ6IDMwICovXG4gIGludGVydmFsPzogbnVtYmVyO1xuICAvKiogSGVhbHRoIGNoZWNrIHRpbWVvdXQgaW4gc2Vjb25kcy4gRGVmYXVsdDogNSAqL1xuICB0aW1lb3V0PzogbnVtYmVyO1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIHN1Y2Nlc3NlcyBiZWZvcmUgaGVhbHRoeS4gRGVmYXVsdDogMiAqL1xuICBoZWFsdGh5VGhyZXNob2xkPzogbnVtYmVyO1xuICAvKiogTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGZhaWx1cmVzIGJlZm9yZSB1bmhlYWx0aHkuIERlZmF1bHQ6IDMgKi9cbiAgdW5oZWFsdGh5VGhyZXNob2xkPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIERvbWFpbiBjb25maWd1cmF0aW9uIGZvciBIVFRQUyBhbmQgRE5TLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvYWRCYWxhbmNlckRvbWFpbkNvbmZpZyB7XG4gIC8qKiBEb21haW4gbmFtZSAoZS5nLiwgXCJhcGkuZXhhbXBsZS5jb21cIikgKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKiogRXhpc3RpbmcgaG9zdGVkIHpvbmUuIElmIG9taXR0ZWQsIGNyZWF0ZXMgbmV3IG9uZS4gKi9cbiAgaG9zdGVkWm9uZT86IEZqYWxsSG9zdGVkWm9uZTtcbiAgLyoqIEV4aXN0aW5nIGNlcnRpZmljYXRlLiBJZiBvbWl0dGVkLCBjcmVhdGVzIG5ldyBvbmUgd2l0aCBETlMgdmFsaWRhdGlvbi4gKi9cbiAgY2VydGlmaWNhdGU/OiBDZXJ0aWZpY2F0ZTtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBMb2FkQmFsYW5jZXJGYWN0b3J5LmJ1aWxkKClcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJTG9hZEJhbGFuY2VyUHJvcHMge1xuICAvKiogVlBDIHRvIHBsYWNlIHRoZSBsb2FkIGJhbGFuY2VyIGluLiBEZWZhdWx0OiBhcHAncyBkZWZhdWx0IFZQQyAqL1xuICB2cGM/OiBJVnBjO1xuICAvKipcbiAgICogRG9tYWluIGNvbmZpZ3VyYXRpb24gZm9yIEhUVFBTLlxuICAgKiAtIHN0cmluZzogRG9tYWluIG5hbWUgKGNyZWF0ZXMgaG9zdGVkIHpvbmUgYW5kIGNlcnRpZmljYXRlKVxuICAgKiAtIExvYWRCYWxhbmNlckRvbWFpbkNvbmZpZzogRnVsbCBjb25maWd1cmF0aW9uXG4gICAqIC0gT21pdDogSFRUUCBvbmx5XG4gICAqL1xuICBkb21haW4/OiBzdHJpbmcgfCBMb2FkQmFsYW5jZXJEb21haW5Db25maWc7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBsb2FkIGJhbGFuY2VyIGlzIGludGVybmV0LWZhY2luZy5cbiAgICogRGVmYXVsdDogdHJ1ZVxuICAgKi9cbiAgcHVibGljPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIERlZmF1bHQgaGVhbHRoIGNoZWNrIGNvbmZpZ3VyYXRpb24uXG4gICAqIEluZGl2aWR1YWwgc2VydmljZXMgY2FuIG92ZXJyaWRlIHRoaXMuXG4gICAqL1xuICBoZWFsdGhDaGVjaz86IExvYWRCYWxhbmNlckhlYWx0aENoZWNrQ29uZmlnO1xufVxuXG4vKipcbiAqIEludGVybmFsIHByb3BzIHdpdGggcmVzb2x2ZWQgVlBDLlxuICovXG5pbnRlcmZhY2UgTG9hZEJhbGFuY2VyUHJvcHNSZXNvbHZlZCBleHRlbmRzIElMb2FkQmFsYW5jZXJQcm9wcyB7XG4gIHZwYzogSVZwYztcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgbG9hZCBiYWxhbmNlciBwcm9wcyBhbmQgbG9ncyB3YXJuaW5ncyBmb3IgbWlzY29uZmlndXJlZCBvcHRpb25zLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUxvYWRCYWxhbmNlclByb3BzKHByb3BzOiBJTG9hZEJhbGFuY2VyUHJvcHMpOiB2b2lkIHtcbiAgaWYgKHByb3BzLmhlYWx0aENoZWNrKSB7XG4gICAgaWYgKHByb3BzLmhlYWx0aENoZWNrLmludGVydmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChwcm9wcy5oZWFsdGhDaGVjay5pbnRlcnZhbCA8IDUgfHwgcHJvcHMuaGVhbHRoQ2hlY2suaW50ZXJ2YWwgPiAzMDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiSGVhbHRoIGNoZWNrIGludGVydmFsIG11c3QgYmUgYmV0d2VlbiA1IGFuZCAzMDAgc2Vjb25kcy5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocHJvcHMuaGVhbHRoQ2hlY2sudGltZW91dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAocHJvcHMuaGVhbHRoQ2hlY2sudGltZW91dCA8IDIgfHwgcHJvcHMuaGVhbHRoQ2hlY2sudGltZW91dCA+IDEyMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgXCJIZWFsdGggY2hlY2sgdGltZW91dCBtdXN0IGJlIGJldHdlZW4gMiBhbmQgMTIwIHNlY29uZHMuXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBGYWN0b3J5IGZvciBjcmVhdGluZyBMb2FkQmFsYW5jZXIgY29uc3RydWN0cy5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU2ltcGxlIEhUVFAgbG9hZCBiYWxhbmNlclxuICogY29uc3QgYWxiID0gYXBwLmFkZENvbXB1dGUoXG4gKiAgIExvYWRCYWxhbmNlckZhY3RvcnkuYnVpbGQoXCJNYWluQUxCXCIsIHt9KVxuICogKTtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSFRUUFMgbG9hZCBiYWxhbmNlciB3aXRoIGRvbWFpblxuICogY29uc3QgYWxiID0gYXBwLmFkZENvbXB1dGUoXG4gKiAgIExvYWRCYWxhbmNlckZhY3RvcnkuYnVpbGQoXCJNYWluQUxCXCIsIHtcbiAqICAgICBkb21haW46IFwiYXBwLmV4YW1wbGUuY29tXCJcbiAqICAgfSlcbiAqICk7XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEludGVybmFsIGxvYWQgYmFsYW5jZXJcbiAqIGNvbnN0IGFsYiA9IGFwcC5hZGRDb21wdXRlKFxuICogICBMb2FkQmFsYW5jZXJGYWN0b3J5LmJ1aWxkKFwiSW50ZXJuYWxBTEJcIiwge1xuICogICAgIHB1YmxpYzogZmFsc2VcbiAqICAgfSlcbiAqICk7XG4gKi9cbmV4cG9ydCBjbGFzcyBMb2FkQmFsYW5jZXJGYWN0b3J5IHtcbiAgc3RhdGljIGJ1aWxkKGlkOiBzdHJpbmcsIHByb3BzOiBJTG9hZEJhbGFuY2VyUHJvcHMpIHtcbiAgICByZXR1cm4gKGFwcDogQXBwLCBzY29wZTogQ29uc3RydWN0KTogTG9hZEJhbGFuY2VyID0+IHtcbiAgICAgIHZhbGlkYXRlTG9hZEJhbGFuY2VyUHJvcHMocHJvcHMpO1xuXG4gICAgICBjb25zdCByZXNvbHZlZFByb3BzOiBMb2FkQmFsYW5jZXJQcm9wc1Jlc29sdmVkID0ge1xuICAgICAgICAuLi5wcm9wcyxcbiAgICAgICAgdnBjOiBwcm9wcy52cGMgfHwgYXBwLmdldFZwYygpXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gbmV3IExvYWRCYWxhbmNlcihzY29wZSwgaWQsIHJlc29sdmVkUHJvcHMpO1xuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyIGNvbnN0cnVjdCB0aGF0IGNhbiBiZSBzaGFyZWQgYWNyb3NzIG11bHRpcGxlIEVDUyBzZXJ2aWNlcy5cbiAqXG4gKiBVc2UgTG9hZEJhbGFuY2VyRmFjdG9yeS5idWlsZCgpIHRvIGNyZWF0ZSBpbnN0YW5jZXMgdmlhIGFwcC5hZGRDb21wdXRlKCkuXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2FkQmFsYW5jZXIgZXh0ZW5kcyBDb25zdHJ1Y3QgaW1wbGVtZW50cyBJQ29ubmVjdGFibGUge1xuICBwdWJsaWMgcmVhZG9ubHkgYWxiOiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlcjtcbiAgcHVibGljIHJlYWRvbmx5IGxpc3RlbmVyOiBBcHBsaWNhdGlvbkxpc3RlbmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgc2VjdXJpdHlHcm91cDogU2VjdXJpdHlHcm91cDtcbiAgcHVibGljIHJlYWRvbmx5IHVybDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgY29ubmVjdGlvbnM6IENvbm5lY3Rpb25zO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaG9zdGVkWm9uZT86IElIb3N0ZWRab25lO1xuICBwcml2YXRlIHJlYWRvbmx5IGNlcnRpZmljYXRlPzogQ2VydGlmaWNhdGU7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdEhlYWx0aENoZWNrOiBMb2FkQmFsYW5jZXJIZWFsdGhDaGVja0NvbmZpZztcbiAgcHJpdmF0ZSByZWFkb25seSBpc0h0dHBzOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBMb2FkQmFsYW5jZXJQcm9wc1Jlc29sdmVkKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIHRoaXMuZGVmYXVsdEhlYWx0aENoZWNrID0gcHJvcHMuaGVhbHRoQ2hlY2sgfHwge307XG4gICAgdGhpcy5pc0h0dHBzID0gISFwcm9wcy5kb21haW47XG5cbiAgICAvLyBDcmVhdGUgc2VjdXJpdHkgZ3JvdXBcbiAgICB0aGlzLnNlY3VyaXR5R3JvdXAgPSBuZXcgU2VjdXJpdHlHcm91cCh0aGlzLCBcIlNlY3VyaXR5R3JvdXBcIiwge1xuICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICBkZXNjcmlwdGlvbjogYFNlY3VyaXR5IGdyb3VwIGZvciAke2lkfSBsb2FkIGJhbGFuY2VyYCxcbiAgICAgIGFsbG93QWxsT3V0Ym91bmQ6IHRydWVcbiAgICB9KTtcblxuICAgIC8vIEFsbG93IGluYm91bmQgdHJhZmZpY1xuICAgIGNvbnN0IGluYm91bmRQb3J0ID0gdGhpcy5pc0h0dHBzID8gNDQzIDogODA7XG4gICAgdGhpcy5zZWN1cml0eUdyb3VwLmFkZEluZ3Jlc3NSdWxlKFxuICAgICAgeyBjb25uZWN0aW9uczogeyBhbGxvd0Zyb21BbnlJcHY0OiAoKSA9PiB7fSB9IH0gYXMgYW55LFxuICAgICAgUG9ydC50Y3AoaW5ib3VuZFBvcnQpLFxuICAgICAgYEFsbG93IGluYm91bmQgJHt0aGlzLmlzSHR0cHMgPyBcIkhUVFBTXCIgOiBcIkhUVFBcIn1gXG4gICAgKTtcblxuICAgIC8vIENyZWF0ZSBBTEJcbiAgICBjb25zdCBsb2FkQmFsYW5jZXJOYW1lID0gdGhpcy50cnVuY2F0ZU5hbWUoYCR7aWR9QUxCYCwgMzIpO1xuICAgIHRoaXMuYWxiID0gbmV3IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKHRoaXMsIFwiQUxCXCIsIHtcbiAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgaW50ZXJuZXRGYWNpbmc6IHByb3BzLnB1YmxpYyAhPT0gZmFsc2UsXG4gICAgICBzZWN1cml0eUdyb3VwOiB0aGlzLnNlY3VyaXR5R3JvdXAsXG4gICAgICBsb2FkQmFsYW5jZXJOYW1lLFxuICAgICAgdnBjU3VibmV0czoge1xuICAgICAgICBzdWJuZXRUeXBlOlxuICAgICAgICAgIHByb3BzLnB1YmxpYyAhPT0gZmFsc2UgPyBTdWJuZXRUeXBlLlBVQkxJQyA6IFN1Ym5ldFR5cGUuUFJJVkFURV9XSVRIX0VHUkVTU1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU2V0IHVwIGRvbWFpbiBpZiBjb25maWd1cmVkXG4gICAgaWYgKHByb3BzLmRvbWFpbikge1xuICAgICAgY29uc3QgZG9tYWluQ29uZmlnID0gdGhpcy5ub3JtYWxpc2VEb21haW5Db25maWcocHJvcHMuZG9tYWluKTtcbiAgICAgIHRoaXMuc2V0dXBEb21haW4oZG9tYWluQ29uZmlnKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgbGlzdGVuZXJcbiAgICBpZiAodGhpcy5pc0h0dHBzICYmIHRoaXMuY2VydGlmaWNhdGUpIHtcbiAgICAgIHRoaXMubGlzdGVuZXIgPSB0aGlzLmFsYi5hZGRMaXN0ZW5lcihcIkxpc3RlbmVyXCIsIHtcbiAgICAgICAgcG9ydDogNDQzLFxuICAgICAgICBwcm90b2NvbDogQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQUyxcbiAgICAgICAgY2VydGlmaWNhdGVzOiBbdGhpcy5jZXJ0aWZpY2F0ZV1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBBZGQgSFRUUCByZWRpcmVjdFxuICAgICAgdGhpcy5hbGIuYWRkTGlzdGVuZXIoXCJIdHRwUmVkaXJlY3RcIiwge1xuICAgICAgICBwb3J0OiA4MCxcbiAgICAgICAgcHJvdG9jb2w6IEFwcGxpY2F0aW9uUHJvdG9jb2wuSFRUUCxcbiAgICAgICAgZGVmYXVsdEFjdGlvbjoge1xuICAgICAgICAgIHJlZGlyZWN0OiB7XG4gICAgICAgICAgICBwcm90b2NvbDogXCJIVFRQU1wiLFxuICAgICAgICAgICAgcG9ydDogXCI0NDNcIixcbiAgICAgICAgICAgIHBlcm1hbmVudDogdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSBhcyBhbnlcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxpc3RlbmVyID0gdGhpcy5hbGIuYWRkTGlzdGVuZXIoXCJMaXN0ZW5lclwiLCB7XG4gICAgICAgIHBvcnQ6IDgwLFxuICAgICAgICBwcm90b2NvbDogQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBZGQgZGVmYXVsdCBhY3Rpb24gKHJldHVybnMgNTAzIGlmIG5vIHRhcmdldHMgbWF0Y2gpXG4gICAgdGhpcy5saXN0ZW5lci5hZGRBY3Rpb24oXCJEZWZhdWx0QWN0aW9uXCIsIHtcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICBmaXhlZFJlc3BvbnNlOiB7XG4gICAgICAgICAgc3RhdHVzQ29kZTogNTAzLFxuICAgICAgICAgIGNvbnRlbnRUeXBlOiBcInRleHQvcGxhaW5cIixcbiAgICAgICAgICBtZXNzYWdlQm9keTogXCJObyBzZXJ2aWNlIGF2YWlsYWJsZVwiXG4gICAgICAgIH1cbiAgICAgIH0gYXMgYW55XG4gICAgfSk7XG5cbiAgICAvLyBTZXQgVVJMXG4gICAgdGhpcy51cmwgPSB0aGlzLmlzSHR0cHNcbiAgICAgID8gYGh0dHBzOi8vJHt0aGlzLmFsYi5sb2FkQmFsYW5jZXJEbnNOYW1lfWBcbiAgICAgIDogYGh0dHA6Ly8ke3RoaXMuYWxiLmxvYWRCYWxhbmNlckRuc05hbWV9YDtcblxuICAgIC8vIFNldCB1cCBjb25uZWN0aW9uc1xuICAgIHRoaXMuY29ubmVjdGlvbnMgPSBuZXcgQ29ubmVjdGlvbnMoe1xuICAgICAgc2VjdXJpdHlHcm91cHM6IFt0aGlzLnNlY3VyaXR5R3JvdXBdLFxuICAgICAgZGVmYXVsdFBvcnQ6IFBvcnQudGNwKGluYm91bmRQb3J0KVxuICAgIH0pO1xuXG4gICAgLy8gT3V0cHV0c1xuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgXCJMb2FkQmFsYW5jZXJEbnNOYW1lXCIsIHtcbiAgICAgIGtleTogYCR7aWR9TG9hZEJhbGFuY2VyRG5zTmFtZWAsXG4gICAgICBleHBvcnROYW1lOiBgJHtpZH1Mb2FkQmFsYW5jZXJEbnNOYW1lYCxcbiAgICAgIHZhbHVlOiB0aGlzLmFsYi5sb2FkQmFsYW5jZXJEbnNOYW1lXG4gICAgfSk7XG5cbiAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsIFwiTG9hZEJhbGFuY2VyVXJsXCIsIHtcbiAgICAgIGtleTogYCR7aWR9TG9hZEJhbGFuY2VyVXJsYCxcbiAgICAgIGV4cG9ydE5hbWU6IGAke2lkfUxvYWRCYWxhbmNlclVybGAsXG4gICAgICB2YWx1ZTogdGhpcy51cmwsXG4gICAgICBkZXNjcmlwdGlvbjogYExvYWQgQmFsYW5jZXIgVVJMIGZvciAke2lkfWBcbiAgICB9KTtcblxuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgXCJMb2FkQmFsYW5jZXJBcm5cIiwge1xuICAgICAga2V5OiBgJHtpZH1Mb2FkQmFsYW5jZXJBcm5gLFxuICAgICAgZXhwb3J0TmFtZTogYCR7aWR9TG9hZEJhbGFuY2VyQXJuYCxcbiAgICAgIHZhbHVlOiB0aGlzLmFsYi5sb2FkQmFsYW5jZXJBcm4sXG4gICAgICBkZXNjcmlwdGlvbjogYExvYWQgQmFsYW5jZXIgQVJOIGZvciAke2lkfWBcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhIHRhcmdldCBncm91cCB3aXRoIHJvdXRpbmcgcnVsZXMuXG4gICAqIENhbGxlZCBpbnRlcm5hbGx5IGJ5IEVjc0NsdXN0ZXIgd2hlbiBsb2FkQmFsYW5jZXIudGFyZ2V0IGlzIHNwZWNpZmllZC5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldEdyb3VwIC0gVGhlIHRhcmdldCBncm91cCB0byByZWdpc3RlclxuICAgKiBAcGFyYW0gcm91dGluZyAtIFJvdXRpbmcgY29uZmlndXJhdGlvbiAocGF0aCwgaG9zdCwgcHJpb3JpdHkpXG4gICAqL1xuICBwdWJsaWMgcmVnaXN0ZXJUYXJnZXRHcm91cChcbiAgICB0YXJnZXRHcm91cDogSUFwcGxpY2F0aW9uVGFyZ2V0R3JvdXAsXG4gICAgcm91dGluZzogTG9hZEJhbGFuY2VyUm91dGluZ0NvbmZpZ1xuICApOiB2b2lkIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBMaXN0ZW5lckNvbmRpdGlvbltdID0gW107XG5cbiAgICBpZiAocm91dGluZy5wYXRoKSB7XG4gICAgICBjb25zdCBwYXRocyA9IEFycmF5LmlzQXJyYXkocm91dGluZy5wYXRoKSA/IHJvdXRpbmcucGF0aCA6IFtyb3V0aW5nLnBhdGhdO1xuICAgICAgY29uZGl0aW9ucy5wdXNoKExpc3RlbmVyQ29uZGl0aW9uLnBhdGhQYXR0ZXJucyhwYXRocykpO1xuICAgIH1cblxuICAgIGlmIChyb3V0aW5nLmhvc3QpIHtcbiAgICAgIGNvbnN0IGhvc3RzID0gQXJyYXkuaXNBcnJheShyb3V0aW5nLmhvc3QpID8gcm91dGluZy5ob3N0IDogW3JvdXRpbmcuaG9zdF07XG4gICAgICBjb25kaXRpb25zLnB1c2goTGlzdGVuZXJDb25kaXRpb24uaG9zdEhlYWRlcnMoaG9zdHMpKTtcbiAgICB9XG5cbiAgICBpZiAoY29uZGl0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJBdCBsZWFzdCBvbmUgcm91dGluZyBjb25kaXRpb24gKHBhdGggb3IgaG9zdCkgbXVzdCBiZSBzcGVjaWZpZWQuXCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5saXN0ZW5lci5hZGRUYXJnZXRHcm91cHMoYFJ1bGUke3JvdXRpbmcucHJpb3JpdHl9YCwge1xuICAgICAgdGFyZ2V0R3JvdXBzOiBbdGFyZ2V0R3JvdXBdLFxuICAgICAgY29uZGl0aW9ucyxcbiAgICAgIHByaW9yaXR5OiByb3V0aW5nLnByaW9yaXR5XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgdGFyZ2V0IGdyb3VwIGZvciBhbiBFQ1Mgc2VydmljZS5cbiAgICogUmV0dXJucyB0aGUgdGFyZ2V0IGdyb3VwIGZvciB0aGUgc2VydmljZSB0byByZWdpc3RlciB3aXRoLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIHRhcmdldCBncm91cFxuICAgKiBAcGFyYW0gcG9ydCAtIENvbnRhaW5lciBwb3J0XG4gICAqIEBwYXJhbSB2cGMgLSBWUEMgZm9yIHRoZSB0YXJnZXQgZ3JvdXBcbiAgICogQHBhcmFtIGhlYWx0aENoZWNrUGF0aCAtIE9wdGlvbmFsIGhlYWx0aCBjaGVjayBwYXRoIG92ZXJyaWRlXG4gICAqL1xuICBwdWJsaWMgY3JlYXRlVGFyZ2V0R3JvdXAoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwb3J0OiBudW1iZXIsXG4gICAgdnBjOiBJVnBjLFxuICAgIGhlYWx0aENoZWNrUGF0aD86IHN0cmluZ1xuICApOiBBcHBsaWNhdGlvblRhcmdldEdyb3VwIHtcbiAgICBjb25zdCB0YXJnZXRHcm91cCA9IG5ldyBBcHBsaWNhdGlvblRhcmdldEdyb3VwKHRoaXMsIGAke2lkfVRhcmdldEdyb3VwYCwge1xuICAgICAgdnBjLFxuICAgICAgcG9ydCxcbiAgICAgIHByb3RvY29sOiBBcHBsaWNhdGlvblByb3RvY29sLkhUVFAsXG4gICAgICB0YXJnZXRUeXBlOiBUYXJnZXRUeXBlLklQLFxuICAgICAgaGVhbHRoQ2hlY2s6IHtcbiAgICAgICAgcGF0aDogaGVhbHRoQ2hlY2tQYXRoIHx8IHRoaXMuZGVmYXVsdEhlYWx0aENoZWNrLnBhdGggfHwgXCIvXCIsXG4gICAgICAgIGludGVydmFsOiBEdXJhdGlvbi5zZWNvbmRzKFxuICAgICAgICAgIHRoaXMuZGVmYXVsdEhlYWx0aENoZWNrLmludGVydmFsIHx8IDMwXG4gICAgICAgICksXG4gICAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoXG4gICAgICAgICAgdGhpcy5kZWZhdWx0SGVhbHRoQ2hlY2sudGltZW91dCB8fCA1XG4gICAgICAgICksXG4gICAgICAgIGhlYWx0aHlUaHJlc2hvbGRDb3VudDogdGhpcy5kZWZhdWx0SGVhbHRoQ2hlY2suaGVhbHRoeVRocmVzaG9sZCB8fCAyLFxuICAgICAgICB1bmhlYWx0aHlUaHJlc2hvbGRDb3VudDogdGhpcy5kZWZhdWx0SGVhbHRoQ2hlY2sudW5oZWFsdGh5VGhyZXNob2xkIHx8IDNcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB0YXJnZXRHcm91cDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvdyB0cmFmZmljIGZyb20gdGhpcyBsb2FkIGJhbGFuY2VyIHRvIGEgY29ubmVjdGFibGUgcmVzb3VyY2UuXG4gICAqL1xuICBwdWJsaWMgYWxsb3dUbyhjb25uZWN0YWJsZTogSUNvbm5lY3RhYmxlLCBwb3J0PzogUG9ydCk6IHZvaWQge1xuICAgIHRoaXMuY29ubmVjdGlvbnMuYWxsb3dUbyhcbiAgICAgIGNvbm5lY3RhYmxlLFxuICAgICAgcG9ydCB8fCBjb25uZWN0YWJsZS5jb25uZWN0aW9ucy5kZWZhdWx0UG9ydCB8fCBQb3J0LmFsbFRjcCgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXNlRG9tYWluQ29uZmlnKFxuICAgIGRvbWFpbjogc3RyaW5nIHwgTG9hZEJhbGFuY2VyRG9tYWluQ29uZmlnXG4gICk6IExvYWRCYWxhbmNlckRvbWFpbkNvbmZpZyB7XG4gICAgaWYgKHR5cGVvZiBkb21haW4gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB7IG5hbWU6IGRvbWFpbiB9O1xuICAgIH1cbiAgICByZXR1cm4gZG9tYWluO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cERvbWFpbihjb25maWc6IExvYWRCYWxhbmNlckRvbWFpbkNvbmZpZyk6IHZvaWQge1xuICAgIC8vIEdldCBvciBjcmVhdGUgaG9zdGVkIHpvbmVcbiAgICBpZiAoY29uZmlnLmhvc3RlZFpvbmUpIHtcbiAgICAgICh0aGlzIGFzIGFueSkuaG9zdGVkWm9uZSA9IGNvbmZpZy5ob3N0ZWRab25lLmdldEludGVybmFsSG9zdGVkWm9uZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBob3N0ZWRab25lID0gbmV3IEZqYWxsSG9zdGVkWm9uZSh0aGlzLCBcIkhvc3RlZFpvbmVcIiwge1xuICAgICAgICB6b25lTmFtZTogY29uZmlnLm5hbWVcbiAgICAgIH0pO1xuICAgICAgKHRoaXMgYXMgYW55KS5ob3N0ZWRab25lID0gaG9zdGVkWm9uZS5nZXRJbnRlcm5hbEhvc3RlZFpvbmUoKTtcbiAgICB9XG5cbiAgICAvLyBHZXQgb3IgY3JlYXRlIGNlcnRpZmljYXRlXG4gICAgaWYgKGNvbmZpZy5jZXJ0aWZpY2F0ZSkge1xuICAgICAgKHRoaXMgYXMgYW55KS5jZXJ0aWZpY2F0ZSA9IGNvbmZpZy5jZXJ0aWZpY2F0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgKHRoaXMgYXMgYW55KS5jZXJ0aWZpY2F0ZSA9IG5ldyBDZXJ0aWZpY2F0ZSh0aGlzLCBcIkNlcnRpZmljYXRlXCIsIHtcbiAgICAgICAgZG9tYWluTmFtZTogY29uZmlnLm5hbWUsXG4gICAgICAgIHZhbGlkYXRpb246IENlcnRpZmljYXRlVmFsaWRhdGlvbi5mcm9tRG5zKHRoaXMuaG9zdGVkWm9uZSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBETlMgcmVjb3JkIHBvaW50aW5nIHRvIEFMQlxuICAgIG5ldyBBUmVjb3JkKHRoaXMsIFwiQWxpYXNSZWNvcmRcIiwge1xuICAgICAgem9uZTogdGhpcy5ob3N0ZWRab25lISxcbiAgICAgIHJlY29yZE5hbWU6IGNvbmZpZy5uYW1lLFxuICAgICAgdGFyZ2V0OiBSZWNvcmRUYXJnZXQuZnJvbUFsaWFzKG5ldyBMb2FkQmFsYW5jZXJUYXJnZXQodGhpcy5hbGIpKVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB0cnVuY2F0ZU5hbWUobmFtZTogc3RyaW5nLCBtYXhMZW5ndGg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKG5hbWUubGVuZ3RoIDw9IG1heExlbmd0aCkge1xuICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygwLCBtYXhMZW5ndGgpLnJlcGxhY2UoLy0rJC8sIFwiXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgRE5TIG5hbWUgb2YgdGhlIGxvYWQgYmFsYW5jZXIuXG4gICAqL1xuICBwdWJsaWMgZ2V0RG5zTmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmFsYi5sb2FkQmFsYW5jZXJEbnNOYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgQVJOIG9mIHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgKi9cbiAgcHVibGljIGdldEFybigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmFsYi5sb2FkQmFsYW5jZXJBcm47XG4gIH1cbn1cbiJdfQ==
@@ -1,61 +0,0 @@
1
- import { Construct } from "constructs";
2
- import type App from "../../app";
3
- import { SQSQueue } from "../../resources/aws/messaging/sqs";
4
- export interface ISQSProps {
5
- queueType?: "standard" | "fifo";
6
- visibilityTimeout?: number;
7
- messageRetentionPeriod?: number;
8
- receiveMessageWaitTime?: number;
9
- maxMessageSize?: number;
10
- deliveryDelay?: number;
11
- deadLetterQueue?: {
12
- enabled: boolean;
13
- maxReceiveCount?: number;
14
- };
15
- encryption?: "SSE_SQS" | "SSE_KMS" | "NONE";
16
- kmsKeyArn?: string;
17
- contentBasedDeduplication?: boolean;
18
- fifoThroughputLimit?: "perQueue" | "perMessageGroupId";
19
- deduplicationScope?: "queue" | "messageGroup";
20
- removalPolicy?: "DESTROY" | "RETAIN";
21
- }
22
- /**
23
- * SQS queue wrapper with grant methods and Fjall patterns.
24
- */
25
- export declare class Queue extends SQSQueue {
26
- constructor(scope: Construct, id: string, props: ISQSProps);
27
- }
28
- /**
29
- * Factory for creating SQS queues.
30
- *
31
- * @example
32
- * // Standard queue with DLQ
33
- * const notifications = app.addQueue(QueueFactory.build("Notifications", {
34
- * queueType: "standard",
35
- * deadLetterQueue: { enabled: true, maxReceiveCount: 3 }
36
- * }));
37
- *
38
- * @example
39
- * // FIFO queue for OpenNext revalidation
40
- * const revalidation = app.addQueue(QueueFactory.build("Revalidation", {
41
- * queueType: "fifo",
42
- * visibilityTimeout: 300,
43
- * contentBasedDeduplication: true
44
- * }));
45
- *
46
- * @example
47
- * // Grant permissions
48
- * revalidation.grantSend(serverFunction);
49
- * revalidation.grantConsume(revalidationFunction);
50
- */
51
- export declare class QueueFactory {
52
- /**
53
- * Build an SQS queue factory function.
54
- *
55
- * @param id - Unique identifier for the queue
56
- * @param props - SQS queue configuration properties
57
- * @returns Factory function that creates the queue when invoked
58
- */
59
- static build(id: string, props?: ISQSProps): (_app: App, scope: Construct) => Queue;
60
- }
61
- export type { SQSQueueProps } from "../../resources/aws/messaging/sqs";