@fjall/components-infrastructure 0.80.4 → 0.81.2

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 (40) hide show
  1. package/dist/lib/__tests__/setup.js +1 -78
  2. package/dist/lib/resources/aws/compute/ecsFreeTier.d.ts +2 -1
  3. package/dist/lib/resources/aws/compute/ecsFreeTier.js +1 -352
  4. package/dist/lib/resources/aws/compute/ecsSpot.d.ts +2 -1
  5. package/dist/lib/resources/aws/compute/ecsSpot.js +1 -332
  6. package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.js +1 -180
  7. package/dist/lib/resources/aws/utilities/cfnOutput.js +1 -13
  8. package/package.json +3 -3
  9. package/dist/lib/patterns/aws/cdn.d.ts +0 -133
  10. package/dist/lib/patterns/aws/cdn.js +0 -216
  11. package/dist/lib/patterns/aws/dynamodb.d.ts +0 -66
  12. package/dist/lib/patterns/aws/dynamodb.js +0 -106
  13. package/dist/lib/patterns/aws/loadBalancer.d.ts +0 -163
  14. package/dist/lib/patterns/aws/loadBalancer.js +0 -278
  15. package/dist/lib/patterns/aws/queue.d.ts +0 -61
  16. package/dist/lib/patterns/aws/queue.js +0 -103
  17. package/dist/lib/resources/aws/cdn/cloudFront.d.ts +0 -65
  18. package/dist/lib/resources/aws/cdn/cloudFront.js +0 -135
  19. package/dist/lib/resources/aws/cdn/index.d.ts +0 -1
  20. package/dist/lib/resources/aws/cdn/index.js +0 -18
  21. package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.d.ts +0 -20
  22. package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.js +0 -180
  23. package/dist/lib/resources/aws/database/dynamodb.d.ts +0 -70
  24. package/dist/lib/resources/aws/database/dynamodb.js +0 -170
  25. package/dist/lib/resources/aws/database/rdsDeletionWaiter.d.ts +0 -33
  26. package/dist/lib/resources/aws/database/rdsDeletionWaiter.js +0 -74
  27. package/dist/lib/resources/aws/messaging/index.d.ts +0 -1
  28. package/dist/lib/resources/aws/messaging/index.js +0 -18
  29. package/dist/lib/resources/aws/messaging/sqs.d.ts +0 -65
  30. package/dist/lib/resources/aws/messaging/sqs.js +0 -195
  31. package/dist/lib/resources/aws/networking/vpcEndpoint.d.ts +0 -20
  32. package/dist/lib/resources/aws/networking/vpcEndpoint.js +0 -59
  33. package/dist/lib/resources/aws/networking/vpcEndpoints.d.ts +0 -71
  34. package/dist/lib/resources/aws/networking/vpcEndpoints.js +0 -125
  35. package/dist/lib/resources/aws/utilities/cfnOutput.test.d.ts +0 -1
  36. package/dist/lib/resources/aws/utilities/cfnOutput.test.js +0 -102
  37. package/dist/lib/utils/sanitizeCfnKey.d.ts +0 -5
  38. package/dist/lib/utils/sanitizeCfnKey.js +0 -11
  39. package/dist/lib/utils/tagResource.d.ts +0 -24
  40. package/dist/lib/utils/tagResource.js +0 -30
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/components-infrastructure",
3
- "version": "0.80.4",
3
+ "version": "0.81.2",
4
4
  "bin": {
5
5
  "infrastructure": "bin/infrastructure.js"
6
6
  },
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@aws-sdk/client-organizations": "^3.716.0",
39
- "@fjall/util": "^0.80.4",
39
+ "@fjall/util": "^0.81.2",
40
40
  "@pepperize/cdk-organizations": "^0.7.135",
41
41
  "cdk-time-sleep": "^1.0.0",
42
42
  "constructs": "^10.0.0",
@@ -45,7 +45,7 @@
45
45
  "overrides": {
46
46
  "@smithy/core": "2.5.5"
47
47
  },
48
- "gitHead": "7f39b84637d7394d1998b0710312d54db75452fa",
48
+ "gitHead": "c9fbb517b3114f2f781adcf69d93775496279e1c",
49
49
  "peerDependencies": {
50
50
  "aws-cdk": "^2.206.0",
51
51
  "aws-cdk-lib": "^2.206.0",
@@ -1,133 +0,0 @@
1
- import { Construct } from "constructs";
2
- import { type IBucket } from "aws-cdk-lib/aws-s3";
3
- import { type IApplicationLoadBalancer } from "aws-cdk-lib/aws-elasticloadbalancingv2";
4
- import { type ICertificate } from "aws-cdk-lib/aws-certificatemanager";
5
- import { type ICachePolicy } from "aws-cdk-lib/aws-cloudfront";
6
- import type App from "../../app";
7
- import { CloudFrontDistribution, type CdnBehaviour, type CachePolicyPreset } from "../../resources/aws/cdn";
8
- import { S3Storage } from "./storage";
9
- import { Compute } from "./compute";
10
- /**
11
- * S3 origin CDN props - use with S3 bucket
12
- */
13
- export interface S3CdnProps {
14
- originType: "s3";
15
- bucket: IBucket | S3Storage;
16
- originPath?: string;
17
- cachePolicy?: CachePolicyPreset | ICachePolicy;
18
- behaviours?: CdnBehaviour[];
19
- domainNames?: string[];
20
- certificate?: ICertificate;
21
- comment?: string;
22
- enableLogging?: boolean;
23
- logBucket?: IBucket;
24
- }
25
- /**
26
- * ALB origin CDN props - use with Application Load Balancer
27
- */
28
- export interface AlbCdnProps {
29
- originType: "alb";
30
- loadBalancer: IApplicationLoadBalancer | Compute;
31
- protocolPolicy?: "HTTP_ONLY" | "HTTPS_ONLY" | "MATCH_VIEWER";
32
- cachePolicy?: CachePolicyPreset | ICachePolicy;
33
- behaviours?: CdnBehaviour[];
34
- domainNames?: string[];
35
- certificate?: ICertificate;
36
- comment?: string;
37
- enableLogging?: boolean;
38
- logBucket?: IBucket;
39
- }
40
- /**
41
- * HTTP origin CDN props - use with custom HTTP endpoint
42
- */
43
- export interface HttpCdnProps {
44
- originType: "http";
45
- domainName: string;
46
- originPath?: string;
47
- protocolPolicy?: "HTTP_ONLY" | "HTTPS_ONLY" | "MATCH_VIEWER";
48
- cachePolicy?: CachePolicyPreset | ICachePolicy;
49
- behaviours?: CdnBehaviour[];
50
- domainNames?: string[];
51
- certificate?: ICertificate;
52
- comment?: string;
53
- enableLogging?: boolean;
54
- logBucket?: IBucket;
55
- }
56
- /**
57
- * Smart origin CDN props - auto-detect origin type from Fjall resource
58
- */
59
- export interface SmartCdnProps {
60
- originType: "auto";
61
- origin: S3Storage | Compute | string;
62
- cachePolicy?: CachePolicyPreset | ICachePolicy;
63
- behaviours?: CdnBehaviour[];
64
- domainNames?: string[];
65
- certificate?: ICertificate;
66
- comment?: string;
67
- enableLogging?: boolean;
68
- logBucket?: IBucket;
69
- }
70
- export type ICdnProps = S3CdnProps | AlbCdnProps | HttpCdnProps | SmartCdnProps;
71
- /**
72
- * CDN wrapper class that extends CloudFrontDistribution with Fjall patterns.
73
- */
74
- export declare class Cdn extends CloudFrontDistribution {
75
- constructor(scope: Construct, id: string, props: ICdnProps);
76
- /**
77
- * Resolve ICdnProps to CloudFrontDistributionProps.
78
- */
79
- private static resolveProps;
80
- /**
81
- * Resolve the default origin from ICdnProps.
82
- */
83
- private static resolveDefaultOrigin;
84
- /**
85
- * Auto-detect origin configuration from a Fjall resource.
86
- */
87
- private static detectOriginFromResource;
88
- }
89
- /**
90
- * Factory for creating CDN (CloudFront) distributions.
91
- *
92
- * @example
93
- * // S3 origin
94
- * const assets = app.addStorage(StorageFactory.build("Assets", { bucketType: "private" }));
95
- * app.addCdn(CdnFactory.build("AssetsCdn", {
96
- * originType: "s3",
97
- * bucket: assets
98
- * }));
99
- *
100
- * @example
101
- * // ALB origin (ECS)
102
- * const api = app.addCompute(ComputeFactory.build("Api", { type: "ecs", ... }));
103
- * app.addCdn(CdnFactory.build("ApiCdn", {
104
- * originType: "alb",
105
- * loadBalancer: api
106
- * }));
107
- *
108
- * @example
109
- * // Smart detection
110
- * app.addCdn(CdnFactory.build("AppCdn", {
111
- * originType: "auto",
112
- * origin: assets
113
- * }));
114
- *
115
- * @example
116
- * // Custom domain
117
- * app.addCdn(CdnFactory.build("AppCdn", {
118
- * originType: "s3",
119
- * bucket: assets,
120
- * domainNames: ["app.example.com"],
121
- * certificate: myCert
122
- * }));
123
- */
124
- export declare class CdnFactory {
125
- /**
126
- * Build a CDN factory function.
127
- *
128
- * @param id - Unique identifier for the CDN
129
- * @param props - CDN configuration properties
130
- * @returns Factory function that creates the CDN when invoked
131
- */
132
- static build(id: string, props: ICdnProps): (_app: App, scope: Construct) => Cdn;
133
- }
@@ -1,216 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CdnFactory = exports.Cdn = void 0;
4
- const cdn_1 = require("../../resources/aws/cdn");
5
- const storage_1 = require("./storage");
6
- const compute_1 = require("./compute");
7
- /**
8
- * Validates CDN props and logs warnings for misconfigured options.
9
- */
10
- function validateCdnProps(props) {
11
- // Validate certificate region warning
12
- if (props.certificate && props.domainNames && props.domainNames.length > 0) {
13
- console.info("[Fjall] Note: CloudFront certificates must be in us-east-1 region. " +
14
- "Ensure your certificate was created in us-east-1.");
15
- }
16
- // Validate domain names require certificate
17
- if (props.domainNames && props.domainNames.length > 0 && !props.certificate) {
18
- console.warn("[Fjall] Warning: 'domainNames' provided but no 'certificate' specified. " +
19
- "Custom domain names require an ACM certificate in us-east-1.");
20
- }
21
- // Validate ALB origin
22
- if (props.originType === "alb") {
23
- const albProps = props;
24
- if (albProps.loadBalancer instanceof compute_1.Compute) {
25
- const lb = albProps.loadBalancer.getLoadBalancer();
26
- if (!lb) {
27
- throw new Error("Compute resource does not have a load balancer. " +
28
- "Ensure ECS compute has loadBalancer enabled for CDN origin.");
29
- }
30
- }
31
- }
32
- // Validate smart origin
33
- if (props.originType === "auto") {
34
- const smartProps = props;
35
- if (smartProps.origin instanceof compute_1.Compute) {
36
- const computeType = smartProps.origin.getComputeType();
37
- if (computeType === "ec2") {
38
- throw new Error("EC2 compute type is not supported for CDN origin. " +
39
- "Use ECS with load balancer or Lambda with function URL.");
40
- }
41
- if (computeType === "ecs" && !smartProps.origin.getLoadBalancer()) {
42
- throw new Error("ECS compute must have a load balancer for CDN origin. " +
43
- "Enable loadBalancer in your ECS compute configuration.");
44
- }
45
- if (computeType === "lambda" && !smartProps.origin.getFunctionUrl()) {
46
- throw new Error("Lambda compute must have a function URL for CDN origin. " +
47
- "Enable functionUrl in your Lambda compute configuration.");
48
- }
49
- }
50
- }
51
- }
52
- /**
53
- * CDN wrapper class that extends CloudFrontDistribution with Fjall patterns.
54
- */
55
- class Cdn extends cdn_1.CloudFrontDistribution {
56
- constructor(scope, id, props) {
57
- const resolvedProps = Cdn.resolveProps(props);
58
- super(scope, id, resolvedProps);
59
- }
60
- /**
61
- * Resolve ICdnProps to CloudFrontDistributionProps.
62
- */
63
- static resolveProps(props) {
64
- const defaultOrigin = Cdn.resolveDefaultOrigin(props);
65
- return {
66
- defaultOrigin,
67
- defaultCachePolicy: props.cachePolicy,
68
- behaviours: props.behaviours,
69
- domainNames: props.domainNames,
70
- certificate: props.certificate,
71
- comment: props.comment,
72
- enableLogging: props.enableLogging,
73
- logBucket: props.logBucket
74
- };
75
- }
76
- /**
77
- * Resolve the default origin from ICdnProps.
78
- */
79
- static resolveDefaultOrigin(props) {
80
- switch (props.originType) {
81
- case "s3": {
82
- const s3Props = props;
83
- const bucket = s3Props.bucket instanceof storage_1.S3Storage
84
- ? s3Props.bucket.getBucket()
85
- : s3Props.bucket;
86
- return {
87
- type: "s3",
88
- bucket,
89
- originPath: s3Props.originPath
90
- };
91
- }
92
- case "alb": {
93
- const albProps = props;
94
- const loadBalancer = albProps.loadBalancer instanceof compute_1.Compute
95
- ? albProps.loadBalancer.getLoadBalancer()
96
- : albProps.loadBalancer;
97
- return {
98
- type: "alb",
99
- loadBalancer,
100
- protocolPolicy: albProps.protocolPolicy
101
- };
102
- }
103
- case "http": {
104
- const httpProps = props;
105
- return {
106
- type: "http",
107
- domainName: httpProps.domainName,
108
- originPath: httpProps.originPath,
109
- protocolPolicy: httpProps.protocolPolicy
110
- };
111
- }
112
- case "auto": {
113
- const smartProps = props;
114
- return Cdn.detectOriginFromResource(smartProps.origin);
115
- }
116
- }
117
- }
118
- /**
119
- * Auto-detect origin configuration from a Fjall resource.
120
- */
121
- static detectOriginFromResource(resource) {
122
- // String → HTTP origin
123
- if (typeof resource === "string") {
124
- return {
125
- type: "http",
126
- domainName: resource
127
- };
128
- }
129
- // S3Storage → S3 origin
130
- if (resource instanceof storage_1.S3Storage) {
131
- return {
132
- type: "s3",
133
- bucket: resource.getBucket()
134
- };
135
- }
136
- // Compute → ALB or Lambda origin
137
- if (resource instanceof compute_1.Compute) {
138
- const computeType = resource.getComputeType();
139
- if (computeType === "ecs") {
140
- const loadBalancer = resource.getLoadBalancer();
141
- if (loadBalancer) {
142
- return {
143
- type: "alb",
144
- loadBalancer
145
- };
146
- }
147
- }
148
- if (computeType === "lambda") {
149
- const functionUrl = resource.getFunctionUrl();
150
- if (functionUrl) {
151
- // Lambda function URL is an HTTP origin
152
- const url = new URL(functionUrl);
153
- return {
154
- type: "http",
155
- domainName: url.hostname
156
- };
157
- }
158
- }
159
- }
160
- throw new Error(`Unable to detect CDN origin from resource: ${typeof resource}. ` +
161
- "Provide explicit origin configuration using originType.");
162
- }
163
- }
164
- exports.Cdn = Cdn;
165
- /**
166
- * Factory for creating CDN (CloudFront) distributions.
167
- *
168
- * @example
169
- * // S3 origin
170
- * const assets = app.addStorage(StorageFactory.build("Assets", { bucketType: "private" }));
171
- * app.addCdn(CdnFactory.build("AssetsCdn", {
172
- * originType: "s3",
173
- * bucket: assets
174
- * }));
175
- *
176
- * @example
177
- * // ALB origin (ECS)
178
- * const api = app.addCompute(ComputeFactory.build("Api", { type: "ecs", ... }));
179
- * app.addCdn(CdnFactory.build("ApiCdn", {
180
- * originType: "alb",
181
- * loadBalancer: api
182
- * }));
183
- *
184
- * @example
185
- * // Smart detection
186
- * app.addCdn(CdnFactory.build("AppCdn", {
187
- * originType: "auto",
188
- * origin: assets
189
- * }));
190
- *
191
- * @example
192
- * // Custom domain
193
- * app.addCdn(CdnFactory.build("AppCdn", {
194
- * originType: "s3",
195
- * bucket: assets,
196
- * domainNames: ["app.example.com"],
197
- * certificate: myCert
198
- * }));
199
- */
200
- class CdnFactory {
201
- /**
202
- * Build a CDN factory function.
203
- *
204
- * @param id - Unique identifier for the CDN
205
- * @param props - CDN configuration properties
206
- * @returns Factory function that creates the CDN when invoked
207
- */
208
- static build(id, props) {
209
- return (_app, scope) => {
210
- validateCdnProps(props);
211
- return new Cdn(scope, id, props);
212
- };
213
- }
214
- }
215
- exports.CdnFactory = CdnFactory;
216
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL3BhdHRlcm5zL2F3cy9jZG4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBT0EsaURBTWlDO0FBQ2pDLHVDQUFzQztBQUN0Qyx1Q0FBb0M7QUFvRXBDOztHQUVHO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFnQjtJQUN4QyxzQ0FBc0M7SUFDdEMsSUFBSSxLQUFLLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDM0UsT0FBTyxDQUFDLElBQUksQ0FDVixxRUFBcUU7WUFDbkUsbURBQW1ELENBQ3RELENBQUM7SUFDSixDQUFDO0lBRUQsNENBQTRDO0lBQzVDLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDNUUsT0FBTyxDQUFDLElBQUksQ0FDViwwRUFBMEU7WUFDeEUsOERBQThELENBQ2pFLENBQUM7SUFDSixDQUFDO0lBRUQsc0JBQXNCO0lBQ3RCLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUMvQixNQUFNLFFBQVEsR0FBRyxLQUFvQixDQUFDO1FBQ3RDLElBQUksUUFBUSxDQUFDLFlBQVksWUFBWSxpQkFBTyxFQUFFLENBQUM7WUFDN0MsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNuRCxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ1IsTUFBTSxJQUFJLEtBQUssQ0FDYixrREFBa0Q7b0JBQ2hELDZEQUE2RCxDQUNoRSxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsd0JBQXdCO0lBQ3hCLElBQUksS0FBSyxDQUFD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SUFBSSxFQUFFLEtBQUs7d0JBQ1gsWUFBWTtxQkFDYixDQUFDO2dCQUNKLENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDOUMsSUFBSSxXQUFXLEVBQUUsQ0FBQztvQkFDaEIsd0NBQXdDO29CQUN4QyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDakMsT0FBTzt3QkFDTCxJQUFJLEVBQUUsTUFBTTt3QkFDWixVQUFVLEVBQUUsR0FBRyxDQUFDLFFBQVE7cUJBQ3pCLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxJQUFJLEtBQUssQ0FDYiw4Q0FBOEMsT0FBTyxRQUFRLElBQUk7WUFDL0QseURBQXlELENBQzVELENBQUM7SUFDSixDQUFDO0NBQ0Y7QUE5SEQsa0JBOEhDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQ0c7QUFDSCxNQUFhLFVBQVU7SUFDckI7Ozs7OztPQU1HO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFVLEVBQUUsS0FBZ0I7UUFDdkMsT0FBTyxDQUFDLElBQVMsRUFBRSxLQUFnQixFQUFPLEVBQUU7WUFDMUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDeEIsT0FBTyxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQWRELGdDQWNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IHR5cGUgSUJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IHR5cGUgSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQgeyB0eXBlIElDZXJ0aWZpY2F0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIElDYWNoZVBvbGljeSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udFwiO1xuXG5pbXBvcnQgdHlwZSBBcHAgZnJvbSBcIi4uLy4uL2FwcFwiO1xuaW1wb3J0IHtcbiAgQ2xvdWRGcm9udERpc3RyaWJ1dGlvbixcbiAgdHlwZSBDbG91ZEZyb250RGlzdHJpYnV0aW9uUHJvcHMsXG4gIHR5cGUgQ2RuT3JpZ2luQ29uZmlnLFxuICB0eXBlIENkbkJlaGF2aW91cixcbiAgdHlwZSBDYWNoZVBvbGljeVByZXNldFxufSBmcm9tIFwiLi4vLi4vcmVzb3VyY2VzL2F3cy9jZG5cIjtcbmltcG9ydCB7IFMzU3RvcmFnZSB9IGZyb20gXCIuL3N0b3JhZ2VcIjtcbmltcG9ydCB7IENvbXB1dGUgfSBmcm9tIFwiLi9jb21wdXRlXCI7XG5cbi8qKlxuICogUzMgb3JpZ2luIENETiBwcm9wcyAtIHVzZSB3aXRoIFMzIGJ1Y2tldFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFMzQ2RuUHJvcHMge1xuICBvcmlnaW5UeXBlOiBcInMzXCI7XG4gIGJ1Y2tldDogSUJ1Y2tldCB8IFMzU3RvcmFnZTtcbiAgb3JpZ2luUGF0aD86IHN0cmluZztcbiAgY2FjaGVQb2xpY3k/OiBDYWNoZVBvbGljeVByZXNldCB8IElDYWNoZVBvbGljeTtcbiAgYmVoYXZpb3Vycz86IENkbkJlaGF2aW91cltdO1xuICBkb21haW5OYW1lcz86IHN0cmluZ1tdO1xuICBjZXJ0aWZpY2F0ZT86IElDZXJ0aWZpY2F0ZTtcbiAgY29tbWVudD86IHN0cmluZztcbiAgZW5hYmxlTG9nZ2luZz86IGJvb2xlYW47XG4gIGxvZ0J1Y2tldD86IElCdWNrZXQ7XG59XG5cbi8qKlxuICogQUxCIG9yaWdpbiBDRE4gcHJvcHMgLSB1c2Ugd2l0aCBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWxiQ2RuUHJvcHMge1xuICBvcmlnaW5UeXBlOiBcImFsYlwiO1xuICBsb2FkQmFsYW5jZXI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciB8IENvbXB1dGU7XG4gIHByb3RvY29sUG9saWN5PzogXCJIVFRQX09OTFlcIiB8IFwiSFRUUFNfT05MWVwiIHwgXCJNQVRDSF9WSUVXRVJcIjtcbiAgY2FjaGVQb2xpY3k/OiBDYWNoZVBvbGljeVByZXNldCB8IElDYWNoZVBvbGljeTtcbiAgYmVoYXZpb3Vycz86IENkbkJlaGF2aW91cltdO1xuICBkb21haW5OYW1lcz86IHN0cmluZ1tdO1xuICBjZXJ0aWZpY2F0ZT86IElDZXJ0aWZpY2F0ZTtcbiAgY29tbWVudD86IHN0cmluZztcbiAgZW5hYmxlTG9nZ2luZz86IGJvb2xlYW47XG4gIGxvZ0J1Y2tldD86IElCdWNrZXQ7XG59XG5cbi8qKlxuICogSFRUUCBvcmlnaW4gQ0ROIHByb3BzIC0gdXNlIHdpdGggY3VzdG9tIEhUVFAgZW5kcG9pbnRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwQ2RuUHJvcHMge1xuICBvcmlnaW5UeXBlOiBcImh0dHBcIjtcbiAgZG9tYWluTmFtZTogc3RyaW5nO1xuICBvcmlnaW5QYXRoPzogc3RyaW5nO1xuICBwcm90b2NvbFBvbGljeT86IFwiSFRUUF9PTkxZXCIgfCBcIkhUVFBTX09OTFlcIiB8IFwiTUFUQ0hfVklFV0VSXCI7XG4gIGNhY2hlUG9saWN5PzogQ2FjaGVQb2xpY3lQcmVzZXQgfCBJQ2FjaGVQb2xpY3k7XG4gIGJlaGF2aW91cnM/OiBDZG5CZWhhdmlvdXJbXTtcbiAgZG9tYWluTmFtZXM/OiBzdHJpbmdbXTtcbiAgY2VydGlmaWNhdGU/OiBJQ2VydGlmaWNhdGU7XG4gIGNvbW1lbnQ/OiBzdHJpbmc7XG4gIGVuYWJsZUxvZ2dpbmc/OiBib29sZWFuO1xuICBsb2dCdWNrZXQ/OiBJQnVja2V0O1xufVxuXG4vKipcbiAqIFNtYXJ0IG9yaWdpbiBDRE4gcHJvcHMgLSBhdXRvLWRldGVjdCBvcmlnaW4gdHlwZSBmcm9tIEZqYWxsIHJlc291cmNlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU21hcnRDZG5Qcm9wcyB7XG4gIG9yaWdpblR5cGU6IFwiYXV0b1wiO1xuICBvcmlnaW46IFMzU3RvcmFnZSB8IENvbXB1dGUgfCBzdHJpbmc7XG4gIGNhY2hlUG9saWN5PzogQ2FjaGVQb2xpY3lQcmVzZXQgfCBJQ2FjaGVQb2xpY3k7XG4gIGJlaGF2aW91cnM/OiBDZG5CZWhhdmlvdXJbXTtcbiAgZG9tYWluTmFtZXM/OiBzdHJpbmdbXTtcbiAgY2VydGlmaWNhdGU/OiBJQ2VydGlmaWNhdGU7XG4gIGNvbW1lbnQ/OiBzdHJpbmc7XG4gIGVuYWJsZUxvZ2dpbmc/OiBib29sZWFuO1xuICBsb2dCdWNrZXQ/OiBJQnVja2V0O1xufVxuXG5leHBvcnQgdHlwZSBJQ2RuUHJvcHMgPSBTM0NkblByb3BzIHwgQWxiQ2RuUHJvcHMgfCBIdHRwQ2RuUHJvcHMgfCBTbWFydENkblByb3BzO1xuXG4vKipcbiAqIFZhbGlkYXRlcyBDRE4gcHJvcHMgYW5kIGxvZ3Mgd2FybmluZ3MgZm9yIG1pc2NvbmZpZ3VyZWQgb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVDZG5Qcm9wcyhwcm9wczogSUNkblByb3BzKTogdm9pZCB7XG4gIC8vIFZhbGlkYXRlIGNlcnRpZmljYXRlIHJlZ2lvbiB3YXJuaW5nXG4gIGlmIChwcm9wcy5jZXJ0aWZpY2F0ZSAmJiBwcm9wcy5kb21haW5OYW1lcyAmJiBwcm9wcy5kb21haW5OYW1lcy5sZW5ndGggPiAwKSB7XG4gICAgY29uc29sZS5pbmZvKFxuICAgICAgXCJbRmphbGxdIE5vdGU6IENsb3VkRnJvbnQgY2VydGlmaWNhdGVzIG11c3QgYmUgaW4gdXMtZWFzdC0xIHJlZ2lvbi4gXCIgK1xuICAgICAgICBcIkVuc3VyZSB5b3VyIGNlcnRpZmljYXRlIHdhcyBjcmVhdGVkIGluIHVzLWVhc3QtMS5cIlxuICAgICk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBkb21haW4gbmFtZXMgcmVxdWlyZSBjZXJ0aWZpY2F0ZVxuICBpZiAocHJvcHMuZG9tYWluTmFtZXMgJiYgcHJvcHMuZG9tYWluTmFtZXMubGVuZ3RoID4gMCAmJiAhcHJvcHMuY2VydGlmaWNhdGUpIHtcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBcIltGamFsbF0gV2FybmluZzogJ2RvbWFpbk5hbWVzJyBwcm92aWRlZCBidXQgbm8gJ2NlcnRpZmljYXRlJyBzcGVjaWZpZWQuIFwiICtcbiAgICAgICAgXCJDdXN0b20gZG9tYWluIG5hbWVzIHJlcXVpcmUgYW4gQUNNIGNlcnRpZmljYXRlIGluIHVzLWVhc3QtMS5cIlxuICAgICk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBBTEIgb3JpZ2luXG4gIGlmIChwcm9wcy5vcmlnaW5UeXBlID09PSBcImFsYlwiKSB7XG4gICAgY29uc3QgYWxiUHJvcHMgPSBwcm9wcyBhcyBBbGJDZG5Qcm9wcztcbiAgICBpZiAoYWxiUHJvcHMubG9hZEJhbGFuY2VyIGluc3RhbmNlb2YgQ29tcHV0ZSkge1xuICAgICAgY29uc3QgbGIgPSBhbGJQcm9wcy5sb2FkQmFsYW5jZXIuZ2V0TG9hZEJhbGFuY2VyKCk7XG4gICAgICBpZiAoIWxiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIkNvbXB1dGUgcmVzb3VyY2UgZG9lcyBub3QgaGF2ZSBhIGxvYWQgYmFsYW5jZXIuIFwiICtcbiAgICAgICAgICAgIFwiRW5zdXJlIEVDUyBjb21wdXRlIGhhcyBsb2FkQmFsYW5jZXIgZW5hYmxlZCBmb3IgQ0ROIG9yaWdpbi5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFZhbGlkYXRlIHNtYXJ0IG9yaWdpblxuICBpZiAocHJvcHMub3JpZ2luVHlwZSA9PT0gXCJhdXRvXCIpIHtcbiAgICBjb25zdCBzbWFydFByb3BzID0gcHJvcHMgYXMgU21hcnRDZG5Qcm9wcztcbiAgICBpZiAoc21hcnRQcm9wcy5vcmlnaW4gaW5zdGFuY2VvZiBDb21wdXRlKSB7XG4gICAgICBjb25zdCBjb21wdXRlVHlwZSA9IHNtYXJ0UHJvcHMub3JpZ2luLmdldENvbXB1dGVUeXBlKCk7XG4gICAgICBpZiAoY29tcHV0ZVR5cGUgPT09IFwiZWMyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiRUMyIGNvbXB1dGUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIGZvciBDRE4gb3JpZ2luLiBcIiArXG4gICAgICAgICAgICBcIlVzZSBFQ1Mgd2l0aCBsb2FkIGJhbGFuY2VyIG9yIExhbWJkYSB3aXRoIGZ1bmN0aW9uIFVSTC5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKGNvbXB1dGVUeXBlID09PSBcImVjc1wiICYmICFzbWFydFByb3BzLm9yaWdpbi5nZXRMb2FkQmFsYW5jZXIoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgXCJFQ1MgY29tcHV0ZSBtdXN0IGhhdmUgYSBsb2FkIGJhbGFuY2VyIGZvciBDRE4gb3JpZ2luLiBcIiArXG4gICAgICAgICAgICBcIkVuYWJsZSBsb2FkQmFsYW5jZXIgaW4geW91ciBFQ1MgY29tcHV0ZSBjb25maWd1cmF0aW9uLlwiXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoY29tcHV0ZVR5cGUgPT09IFwibGFtYmRhXCIgJiYgIXNtYXJ0UHJvcHMub3JpZ2luLmdldEZ1bmN0aW9uVXJsKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiTGFtYmRhIGNvbXB1dGUgbXVzdCBoYXZlIGEgZnVuY3Rpb24gVVJMIGZvciBDRE4gb3JpZ2luLiBcIiArXG4gICAgICAgICAgICBcIkVuYWJsZSBmdW5jdGlvblVybCBpbiB5b3VyIExhbWJkYSBjb21wdXRlIGNvbmZpZ3VyYXRpb24uXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDRE4gd3JhcHBlciBjbGFzcyB0aGF0IGV4dGVuZHMgQ2xvdWRGcm9udERpc3RyaWJ1dGlvbiB3aXRoIEZqYWxsIHBhdHRlcm5zLlxuICovXG5leHBvcnQgY2xhc3MgQ2RuIGV4dGVuZHMgQ2xvdWRGcm9udERpc3RyaWJ1dGlvbiB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBJQ2RuUHJvcHMpIHtcbiAgICBjb25zdCByZXNvbHZlZFByb3BzID0gQ2RuLnJlc29sdmVQcm9wcyhwcm9wcyk7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCByZXNvbHZlZFByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIElDZG5Qcm9wcyB0byBDbG91ZEZyb250RGlzdHJpYnV0aW9uUHJvcHMuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyByZXNvbHZlUHJvcHMocHJvcHM6IElDZG5Qcm9wcyk6IENsb3VkRnJvbnREaXN0cmlidXRpb25Qcm9wcyB7XG4gICAgY29uc3QgZGVmYXVsdE9yaWdpbiA9IENkbi5yZXNvbHZlRGVmYXVsdE9yaWdpbihwcm9wcyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGVmYXVsdE9yaWdpbixcbiAgICAgIGRlZmF1bHRDYWNoZVBvbGljeTogcHJvcHMuY2FjaGVQb2xpY3ksXG4gICAgICBiZWhhdmlvdXJzOiBwcm9wcy5iZWhhdmlvdXJzLFxuICAgICAgZG9tYWluTmFtZXM6IHByb3BzLmRvbWFpbk5hbWVzLFxuICAgICAgY2VydGlmaWNhdGU6IHByb3BzLmNlcnRpZmljYXRlLFxuICAgICAgY29tbWVudDogcHJvcHMuY29tbWVudCxcbiAgICAgIGVuYWJsZUxvZ2dpbmc6IHByb3BzLmVuYWJsZUxvZ2dpbmcsXG4gICAgICBsb2dCdWNrZXQ6IHByb3BzLmxvZ0J1Y2tldFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGUgZGVmYXVsdCBvcmlnaW4gZnJvbSBJQ2RuUHJvcHMuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyByZXNvbHZlRGVmYXVsdE9yaWdpbihwcm9wczogSUNkblByb3BzKTogQ2RuT3JpZ2luQ29uZmlnIHtcbiAgICBzd2l0Y2ggKHByb3BzLm9yaWdpblR5cGUpIHtcbiAgICAgIGNhc2UgXCJzM1wiOiB7XG4gICAgICAgIGNvbnN0IHMzUHJvcHMgPSBwcm9wcyBhcyBTM0NkblByb3BzO1xuICAgICAgICBjb25zdCBidWNrZXQgPVxuICAgICAgICAgIHMzUHJvcHMuYnVja2V0IGluc3RhbmNlb2YgUzNTdG9yYWdlXG4gICAgICAgICAgICA/IHMzUHJvcHMuYnVja2V0LmdldEJ1Y2tldCgpXG4gICAgICAgICAgICA6IHMzUHJvcHMuYnVja2V0O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6IFwiczNcIixcbiAgICAgICAgICBidWNrZXQsXG4gICAgICAgICAgb3JpZ2luUGF0aDogczNQcm9wcy5vcmlnaW5QYXRoXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNhc2UgXCJhbGJcIjoge1xuICAgICAgICBjb25zdCBhbGJQcm9wcyA9IHByb3BzIGFzIEFsYkNkblByb3BzO1xuICAgICAgICBjb25zdCBsb2FkQmFsYW5jZXIgPVxuICAgICAgICAgIGFsYlByb3BzLmxvYWRCYWxhbmNlciBpbnN0YW5jZW9mIENvbXB1dGVcbiAgICAgICAgICAgID8gYWxiUHJvcHMubG9hZEJhbGFuY2VyLmdldExvYWRCYWxhbmNlcigpIVxuICAgICAgICAgICAgOiBhbGJQcm9wcy5sb2FkQmFsYW5jZXI7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogXCJhbGJcIixcbiAgICAgICAgICBsb2FkQmFsYW5jZXIsXG4gICAgICAgICAgcHJvdG9jb2xQb2xpY3k6IGFsYlByb3BzLnByb3RvY29sUG9saWN5XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNhc2UgXCJodHRwXCI6IHtcbiAgICAgICAgY29uc3QgaHR0cFByb3BzID0gcHJvcHMgYXMgSHR0cENkblByb3BzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6IFwiaHR0cFwiLFxuICAgICAgICAgIGRvbWFpbk5hbWU6IGh0dHBQcm9wcy5kb21haW5OYW1lLFxuICAgICAgICAgIG9yaWdpblBhdGg6IGh0dHBQcm9wcy5vcmlnaW5QYXRoLFxuICAgICAgICAgIHByb3RvY29sUG9saWN5OiBodHRwUHJvcHMucHJvdG9jb2xQb2xpY3lcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY2FzZSBcImF1dG9cIjoge1xuICAgICAgICBjb25zdCBzbWFydFByb3BzID0gcHJvcHMgYXMgU21hcnRDZG5Qcm9wcztcbiAgICAgICAgcmV0dXJuIENkbi5kZXRlY3RPcmlnaW5Gcm9tUmVzb3VyY2Uoc21hcnRQcm9wcy5vcmlnaW4pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBdXRvLWRldGVjdCBvcmlnaW4gY29uZmlndXJhdGlvbiBmcm9tIGEgRmphbGwgcmVzb3VyY2UuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBkZXRlY3RPcmlnaW5Gcm9tUmVzb3VyY2UoXG4gICAgcmVzb3VyY2U6IFMzU3RvcmFnZSB8IENvbXB1dGUgfCBzdHJpbmdcbiAgKTogQ2RuT3JpZ2luQ29uZmlnIHtcbiAgICAvLyBTdHJpbmcg4oaSIEhUVFAgb3JpZ2luXG4gICAgaWYgKHR5cGVvZiByZXNvdXJjZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogXCJodHRwXCIsXG4gICAgICAgIGRvbWFpbk5hbWU6IHJlc291cmNlXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFMzU3RvcmFnZSDihpIgUzMgb3JpZ2luXG4gICAgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgUzNTdG9yYWdlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcInMzXCIsXG4gICAgICAgIGJ1Y2tldDogcmVzb3VyY2UuZ2V0QnVja2V0KClcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQ29tcHV0ZSDihpIgQUxCIG9yIExhbWJkYSBvcmlnaW5cbiAgICBpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBDb21wdXRlKSB7XG4gICAgICBjb25zdCBjb21wdXRlVHlwZSA9IHJlc291cmNlLmdldENvbXB1dGVUeXBlKCk7XG5cbiAgICAgIGlmIChjb21wdXRlVHlwZSA9PT0gXCJlY3NcIikge1xuICAgICAgICBjb25zdCBsb2FkQmFsYW5jZXIgPSByZXNvdXJjZS5nZXRMb2FkQmFsYW5jZXIoKTtcbiAgICAgICAgaWYgKGxvYWRCYWxhbmNlcikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBcImFsYlwiLFxuICAgICAgICAgICAgbG9hZEJhbGFuY2VyXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY29tcHV0ZVR5cGUgPT09IFwibGFtYmRhXCIpIHtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25VcmwgPSByZXNvdXJjZS5nZXRGdW5jdGlvblVybCgpO1xuICAgICAgICBpZiAoZnVuY3Rpb25VcmwpIHtcbiAgICAgICAgICAvLyBMYW1iZGEgZnVuY3Rpb24gVVJMIGlzIGFuIEhUVFAgb3JpZ2luXG4gICAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTChmdW5jdGlvblVybCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IFwiaHR0cFwiLFxuICAgICAgICAgICAgZG9tYWluTmFtZTogdXJsLmhvc3RuYW1lXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBVbmFibGUgdG8gZGV0ZWN0IENETiBvcmlnaW4gZnJvbSByZXNvdXJjZTogJHt0eXBlb2YgcmVzb3VyY2V9LiBgICtcbiAgICAgICAgXCJQcm92aWRlIGV4cGxpY2l0IG9yaWdpbiBjb25maWd1cmF0aW9uIHVzaW5nIG9yaWdpblR5cGUuXCJcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogRmFjdG9yeSBmb3IgY3JlYXRpbmcgQ0ROIChDbG91ZEZyb250KSBkaXN0cmlidXRpb25zLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTMyBvcmlnaW5cbiAqIGNvbnN0IGFzc2V0cyA9IGFwcC5hZGRTdG9yYWdlKFN0b3JhZ2VGYWN0b3J5LmJ1aWxkKFwiQXNzZXRzXCIsIHsgYnVja2V0VHlwZTogXCJwcml2YXRlXCIgfSkpO1xuICogYXBwLmFkZENkbihDZG5GYWN0b3J5LmJ1aWxkKFwiQXNzZXRzQ2RuXCIsIHtcbiAqICAgb3JpZ2luVHlwZTogXCJzM1wiLFxuICogICBidWNrZXQ6IGFzc2V0c1xuICogfSkpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBBTEIgb3JpZ2luIChFQ1MpXG4gKiBjb25zdCBhcGkgPSBhcHAuYWRkQ29tcHV0ZShDb21wdXRlRmFjdG9yeS5idWlsZChcIkFwaVwiLCB7IHR5cGU6IFwiZWNzXCIsIC4uLiB9KSk7XG4gKiBhcHAuYWRkQ2RuKENkbkZhY3RvcnkuYnVpbGQoXCJBcGlDZG5cIiwge1xuICogICBvcmlnaW5UeXBlOiBcImFsYlwiLFxuICogICBsb2FkQmFsYW5jZXI6IGFwaVxuICogfSkpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTbWFydCBkZXRlY3Rpb25cbiAqIGFwcC5hZGRDZG4oQ2RuRmFjdG9yeS5idWlsZChcIkFwcENkblwiLCB7XG4gKiAgIG9yaWdpblR5cGU6IFwiYXV0b1wiLFxuICogICBvcmlnaW46IGFzc2V0c1xuICogfSkpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDdXN0b20gZG9tYWluXG4gKiBhcHAuYWRkQ2RuKENkbkZhY3RvcnkuYnVpbGQoXCJBcHBDZG5cIiwge1xuICogICBvcmlnaW5UeXBlOiBcInMzXCIsXG4gKiAgIGJ1Y2tldDogYXNzZXRzLFxuICogICBkb21haW5OYW1lczogW1wiYXBwLmV4YW1wbGUuY29tXCJdLFxuICogICBjZXJ0aWZpY2F0ZTogbXlDZXJ0XG4gKiB9KSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBDZG5GYWN0b3J5IHtcbiAgLyoqXG4gICAqIEJ1aWxkIGEgQ0ROIGZhY3RvcnkgZnVuY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSBpZCAtIFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgQ0ROXG4gICAqIEBwYXJhbSBwcm9wcyAtIENETiBjb25maWd1cmF0aW9uIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgRmFjdG9yeSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgdGhlIENETiB3aGVuIGludm9rZWRcbiAgICovXG4gIHN0YXRpYyBidWlsZChpZDogc3RyaW5nLCBwcm9wczogSUNkblByb3BzKSB7XG4gICAgcmV0dXJuIChfYXBwOiBBcHAsIHNjb3BlOiBDb25zdHJ1Y3QpOiBDZG4gPT4ge1xuICAgICAgdmFsaWRhdGVDZG5Qcm9wcyhwcm9wcyk7XG4gICAgICByZXR1cm4gbmV3IENkbihzY29wZSwgaWQsIHByb3BzKTtcbiAgICB9O1xuICB9XG59XG4iXX0=
@@ -1,66 +0,0 @@
1
- import { Construct } from "constructs";
2
- import type App from "../../app";
3
- import { DynamoDBTable, type DynamoDBKeySchema, type DynamoDBGlobalSecondaryIndex } from "../../resources/aws/database/dynamodb";
4
- export interface IDynamoDBProps {
5
- partitionKey: DynamoDBKeySchema;
6
- sortKey?: DynamoDBKeySchema;
7
- billingMode?: "PAY_PER_REQUEST" | "PROVISIONED";
8
- readCapacity?: number;
9
- writeCapacity?: number;
10
- globalSecondaryIndexes?: DynamoDBGlobalSecondaryIndex[];
11
- timeToLiveAttribute?: string;
12
- stream?: "NEW_IMAGE" | "OLD_IMAGE" | "NEW_AND_OLD_IMAGES" | "KEYS_ONLY";
13
- pointInTimeRecovery?: boolean;
14
- encryption?: "AWS_OWNED" | "AWS_MANAGED" | "CUSTOMER_MANAGED";
15
- removalPolicy?: "DESTROY" | "RETAIN" | "SNAPSHOT";
16
- }
17
- /**
18
- * DynamoDB table wrapper with grant methods and Fjall patterns.
19
- */
20
- export declare class DynamoDB extends DynamoDBTable {
21
- constructor(scope: Construct, id: string, props: IDynamoDBProps);
22
- }
23
- /**
24
- * Factory for creating DynamoDB tables.
25
- *
26
- * @example
27
- * // Simple table with on-demand billing
28
- * const cache = app.addTable(DynamoDBFactory.build("Cache", {
29
- * partitionKey: { name: "id", type: "S" }
30
- * }));
31
- *
32
- * @example
33
- * // Table with sort key and GSI (for OpenNext tag cache)
34
- * const tagCache = app.addTable(DynamoDBFactory.build("TagCache", {
35
- * partitionKey: { name: "tag", type: "S" },
36
- * sortKey: { name: "path", type: "S" },
37
- * globalSecondaryIndexes: [{
38
- * indexName: "revalidate",
39
- * partitionKey: { name: "path", type: "S" },
40
- * sortKey: { name: "revalidatedAt", type: "N" }
41
- * }]
42
- * }));
43
- *
44
- * @example
45
- * // Table with streaming for Lambda triggers
46
- * const events = app.addTable(DynamoDBFactory.build("Events", {
47
- * partitionKey: { name: "pk", type: "S" },
48
- * sortKey: { name: "sk", type: "S" },
49
- * stream: "NEW_AND_OLD_IMAGES"
50
- * }));
51
- *
52
- * @example
53
- * // Grant permissions
54
- * tagCache.grantReadWrite(serverFunction);
55
- */
56
- export declare class DynamoDBFactory {
57
- /**
58
- * Build a DynamoDB factory function.
59
- *
60
- * @param id - Unique identifier for the table
61
- * @param props - DynamoDB table configuration properties
62
- * @returns Factory function that creates the table when invoked
63
- */
64
- static build(id: string, props: IDynamoDBProps): (_app: App, scope: Construct) => DynamoDB;
65
- }
66
- export type { DynamoDBKeySchema, DynamoDBGlobalSecondaryIndex, DynamoDBTableProps } from "../../resources/aws/database/dynamodb";
@@ -1,106 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DynamoDBFactory = exports.DynamoDB = void 0;
4
- const dynamodb_1 = require("../../resources/aws/database/dynamodb");
5
- /**
6
- * Validates DynamoDB props and logs warnings for misconfigured options.
7
- */
8
- function validateDynamoDBProps(props) {
9
- // Validate provisioned capacity
10
- if (props.billingMode === "PROVISIONED") {
11
- if (!props.readCapacity || !props.writeCapacity) {
12
- console.warn("[Fjall] Warning: 'billingMode' is PROVISIONED but capacity not specified. " +
13
- "Using default values. Consider specifying 'readCapacity' and 'writeCapacity'.");
14
- }
15
- }
16
- // Warn about capacity with on-demand billing
17
- if (props.billingMode !== "PROVISIONED") {
18
- if (props.readCapacity || props.writeCapacity) {
19
- console.warn("[Fjall] Warning: 'readCapacity' or 'writeCapacity' specified but 'billingMode' " +
20
- "is not PROVISIONED. Capacity settings will be ignored.");
21
- }
22
- }
23
- // Validate GSI partition keys are different from table partition key
24
- if (props.globalSecondaryIndexes) {
25
- const tablePartitionKey = props.partitionKey.name;
26
- for (const gsi of props.globalSecondaryIndexes) {
27
- if (gsi.partitionKey.name === tablePartitionKey &&
28
- gsi.sortKey?.name === props.sortKey?.name) {
29
- console.warn(`[Fjall] Warning: GSI '${gsi.indexName}' has the same key schema as the table. ` +
30
- "This may not provide the query flexibility you need.");
31
- }
32
- }
33
- }
34
- }
35
- /**
36
- * DynamoDB table wrapper with grant methods and Fjall patterns.
37
- */
38
- class DynamoDB extends dynamodb_1.DynamoDBTable {
39
- constructor(scope, id, props) {
40
- const tableProps = {
41
- partitionKey: props.partitionKey,
42
- sortKey: props.sortKey,
43
- billingMode: props.billingMode,
44
- readCapacity: props.readCapacity,
45
- writeCapacity: props.writeCapacity,
46
- globalSecondaryIndexes: props.globalSecondaryIndexes,
47
- timeToLiveAttribute: props.timeToLiveAttribute,
48
- stream: props.stream,
49
- pointInTimeRecovery: props.pointInTimeRecovery,
50
- encryption: props.encryption,
51
- removalPolicy: props.removalPolicy
52
- };
53
- super(scope, id, tableProps);
54
- }
55
- }
56
- exports.DynamoDB = DynamoDB;
57
- /**
58
- * Factory for creating DynamoDB tables.
59
- *
60
- * @example
61
- * // Simple table with on-demand billing
62
- * const cache = app.addTable(DynamoDBFactory.build("Cache", {
63
- * partitionKey: { name: "id", type: "S" }
64
- * }));
65
- *
66
- * @example
67
- * // Table with sort key and GSI (for OpenNext tag cache)
68
- * const tagCache = app.addTable(DynamoDBFactory.build("TagCache", {
69
- * partitionKey: { name: "tag", type: "S" },
70
- * sortKey: { name: "path", type: "S" },
71
- * globalSecondaryIndexes: [{
72
- * indexName: "revalidate",
73
- * partitionKey: { name: "path", type: "S" },
74
- * sortKey: { name: "revalidatedAt", type: "N" }
75
- * }]
76
- * }));
77
- *
78
- * @example
79
- * // Table with streaming for Lambda triggers
80
- * const events = app.addTable(DynamoDBFactory.build("Events", {
81
- * partitionKey: { name: "pk", type: "S" },
82
- * sortKey: { name: "sk", type: "S" },
83
- * stream: "NEW_AND_OLD_IMAGES"
84
- * }));
85
- *
86
- * @example
87
- * // Grant permissions
88
- * tagCache.grantReadWrite(serverFunction);
89
- */
90
- class DynamoDBFactory {
91
- /**
92
- * Build a DynamoDB factory function.
93
- *
94
- * @param id - Unique identifier for the table
95
- * @param props - DynamoDB table configuration properties
96
- * @returns Factory function that creates the table when invoked
97
- */
98
- static build(id, props) {
99
- return (_app, scope) => {
100
- validateDynamoDBProps(props);
101
- return new DynamoDB(scope, id, props);
102
- };
103
- }
104
- }
105
- exports.DynamoDBFactory = DynamoDBFactory;
106
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1vZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWIvcGF0dGVybnMvYXdzL2R5bmFtb2RiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUtBLG9FQUsrQztBQWdCL0M7O0dBRUc7QUFDSCxTQUFTLHFCQUFxQixDQUFDLEtBQXFCO0lBQ2xELGdDQUFnQztJQUNoQyxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssYUFBYSxFQUFFLENBQUM7UUFDeEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDaEQsT0FBTyxDQUFDLElBQUksQ0FDViw0RUFBNEU7Z0JBQzFFLCtFQUErRSxDQUNsRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCw2Q0FBNkM7SUFDN0MsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLGFBQWEsRUFBRSxDQUFDO1FBQ3hDLElBQUksS0FBSyxDQUFDLFlBQVksSUFBSSxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDOUMsT0FBTyxDQUFDLElBQUksQ0FDVixpRkFBaUY7Z0JBQy9FLHdEQUF3RCxDQUMzRCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxxRUFBcUU7SUFDckUsSUFBSSxLQUFLLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUNqQyxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO1FBQ2xELEtBQUssTUFBTSxHQUFHLElBQUksS0FBSyxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDL0MsSUFDRSxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksS0FBSyxpQkFBaUI7Z0JBQzNDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxLQUFLLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUN6QyxDQUFDO2dCQUNELE9BQU8sQ0FBQyxJQUFJLENBQ1YseUJBQXlCLEdBQUcsQ0FBQyxTQUFTLDBDQUEwQztvQkFDOUUsc0RBQXNELENBQ3pELENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLFFBQVMsU0FBUSx3QkFBYTtJQUN6QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXFCO1FBQzdELE1BQU0sVUFBVSxHQUF1QjtZQUNyQyxZQUFZLEVBQUUsS0FBSyxDQUFDLFlBQVk7WUFDaEMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztZQUM5QixZQUFZLEVBQUUsS0FBSyxDQUFDLFlBQVk7WUFDaEMsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ2xDLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxzQkFBc0I7WUFDcEQsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM5QyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07WUFDcEIsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLG1CQUFtQjtZQUM5QyxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7WUFDNUIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1NBQ25DLENBQUM7UUFDRixLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUMvQixDQUFDO0NBQ0Y7QUFqQkQsNEJBaUJDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBQ0gsTUFBYSxlQUFlO0lBQzFCOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBVSxFQUFFLEtBQXFCO1FBQzVDLE9BQU8sQ0FBQyxJQUFTLEVBQUUsS0FBZ0IsRUFBWSxFQUFFO1lBQy9DLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzdCLE9BQU8sSUFBSSxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUFkRCwwQ0FjQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyB0eXBlIElHcmFudGFibGUsIHR5cGUgR3JhbnQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiO1xuaW1wb3J0IHsgdHlwZSBJVGFibGUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWR5bmFtb2RiXCI7XG5cbmltcG9ydCB0eXBlIEFwcCBmcm9tIFwiLi4vLi4vYXBwXCI7XG5pbXBvcnQge1xuICBEeW5hbW9EQlRhYmxlLFxuICB0eXBlIER5bmFtb0RCVGFibGVQcm9wcyxcbiAgdHlwZSBEeW5hbW9EQktleVNjaGVtYSxcbiAgdHlwZSBEeW5hbW9EQkdsb2JhbFNlY29uZGFyeUluZGV4XG59IGZyb20gXCIuLi8uLi9yZXNvdXJjZXMvYXdzL2RhdGFiYXNlL2R5bmFtb2RiXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUR5bmFtb0RCUHJvcHMge1xuICBwYXJ0aXRpb25LZXk6IER5bmFtb0RCS2V5U2NoZW1hO1xuICBzb3J0S2V5PzogRHluYW1vREJLZXlTY2hlbWE7XG4gIGJpbGxpbmdNb2RlPzogXCJQQVlfUEVSX1JFUVVFU1RcIiB8IFwiUFJPVklTSU9ORURcIjtcbiAgcmVhZENhcGFjaXR5PzogbnVtYmVyO1xuICB3cml0ZUNhcGFjaXR5PzogbnVtYmVyO1xuICBnbG9iYWxTZWNvbmRhcnlJbmRleGVzPzogRHluYW1vREJHbG9iYWxTZWNvbmRhcnlJbmRleFtdO1xuICB0aW1lVG9MaXZlQXR0cmlidXRlPzogc3RyaW5nO1xuICBzdHJlYW0/OiBcIk5FV19JTUFHRVwiIHwgXCJPTERfSU1BR0VcIiB8IFwiTkVXX0FORF9PTERfSU1BR0VTXCIgfCBcIktFWVNfT05MWVwiO1xuICBwb2ludEluVGltZVJlY292ZXJ5PzogYm9vbGVhbjtcbiAgZW5jcnlwdGlvbj86IFwiQVdTX09XTkVEXCIgfCBcIkFXU19NQU5BR0VEXCIgfCBcIkNVU1RPTUVSX01BTkFHRURcIjtcbiAgcmVtb3ZhbFBvbGljeT86IFwiREVTVFJPWVwiIHwgXCJSRVRBSU5cIiB8IFwiU05BUFNIT1RcIjtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgRHluYW1vREIgcHJvcHMgYW5kIGxvZ3Mgd2FybmluZ3MgZm9yIG1pc2NvbmZpZ3VyZWQgb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVEeW5hbW9EQlByb3BzKHByb3BzOiBJRHluYW1vREJQcm9wcyk6IHZvaWQge1xuICAvLyBWYWxpZGF0ZSBwcm92aXNpb25lZCBjYXBhY2l0eVxuICBpZiAocHJvcHMuYmlsbGluZ01vZGUgPT09IFwiUFJPVklTSU9ORURcIikge1xuICAgIGlmICghcHJvcHMucmVhZENhcGFjaXR5IHx8ICFwcm9wcy53cml0ZUNhcGFjaXR5KSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIFwiW0ZqYWxsXSBXYXJuaW5nOiAnYmlsbGluZ01vZGUnIGlzIFBST1ZJU0lPTkVEIGJ1dCBjYXBhY2l0eSBub3Qgc3BlY2lmaWVkLiBcIiArXG4gICAgICAgICAgXCJVc2luZyBkZWZhdWx0IHZhbHVlcy4gQ29uc2lkZXIgc3BlY2lmeWluZyAncmVhZENhcGFjaXR5JyBhbmQgJ3dyaXRlQ2FwYWNpdHknLlwiXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFdhcm4gYWJvdXQgY2FwYWNpdHkgd2l0aCBvbi1kZW1hbmQgYmlsbGluZ1xuICBpZiAocHJvcHMuYmlsbGluZ01vZGUgIT09IFwiUFJPVklTSU9ORURcIikge1xuICAgIGlmIChwcm9wcy5yZWFkQ2FwYWNpdHkgfHwgcHJvcHMud3JpdGVDYXBhY2l0eSkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIltGamFsbF0gV2FybmluZzogJ3JlYWRDYXBhY2l0eScgb3IgJ3dyaXRlQ2FwYWNpdHknIHNwZWNpZmllZCBidXQgJ2JpbGxpbmdNb2RlJyBcIiArXG4gICAgICAgICAgXCJpcyBub3QgUFJPVklTSU9ORUQuIENhcGFjaXR5IHNldHRpbmdzIHdpbGwgYmUgaWdub3JlZC5cIlxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBHU0kgcGFydGl0aW9uIGtleXMgYXJlIGRpZmZlcmVudCBmcm9tIHRhYmxlIHBhcnRpdGlvbiBrZXlcbiAgaWYgKHByb3BzLmdsb2JhbFNlY29uZGFyeUluZGV4ZXMpIHtcbiAgICBjb25zdCB0YWJsZVBhcnRpdGlvbktleSA9IHByb3BzLnBhcnRpdGlvbktleS5uYW1lO1xuICAgIGZvciAoY29uc3QgZ3NpIG9mIHByb3BzLmdsb2JhbFNlY29uZGFyeUluZGV4ZXMpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZ3NpLnBhcnRpdGlvbktleS5uYW1lID09PSB0YWJsZVBhcnRpdGlvbktleSAmJlxuICAgICAgICBnc2kuc29ydEtleT8ubmFtZSA9PT0gcHJvcHMuc29ydEtleT8ubmFtZVxuICAgICAgKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICBgW0ZqYWxsXSBXYXJuaW5nOiBHU0kgJyR7Z3NpLmluZGV4TmFtZX0nIGhhcyB0aGUgc2FtZSBrZXkgc2NoZW1hIGFzIHRoZSB0YWJsZS4gYCArXG4gICAgICAgICAgICBcIlRoaXMgbWF5IG5vdCBwcm92aWRlIHRoZSBxdWVyeSBmbGV4aWJpbGl0eSB5b3UgbmVlZC5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIER5bmFtb0RCIHRhYmxlIHdyYXBwZXIgd2l0aCBncmFudCBtZXRob2RzIGFuZCBGamFsbCBwYXR0ZXJucy5cbiAqL1xuZXhwb3J0IGNsYXNzIER5bmFtb0RCIGV4dGVuZHMgRHluYW1vREJUYWJsZSB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBJRHluYW1vREJQcm9wcykge1xuICAgIGNvbnN0IHRhYmxlUHJvcHM6IER5bmFtb0RCVGFibGVQcm9wcyA9IHtcbiAgICAgIHBhcnRpdGlvbktleTogcHJvcHMucGFydGl0aW9uS2V5LFxuICAgICAgc29ydEtleTogcHJvcHMuc29ydEtleSxcbiAgICAgIGJpbGxpbmdNb2RlOiBwcm9wcy5iaWxsaW5nTW9kZSxcbiAgICAgIHJlYWRDYXBhY2l0eTogcHJvcHMucmVhZENhcGFjaXR5LFxuICAgICAgd3JpdGVDYXBhY2l0eTogcHJvcHMud3JpdGVDYXBhY2l0eSxcbiAgICAgIGdsb2JhbFNlY29uZGFyeUluZGV4ZXM6IHByb3BzLmdsb2JhbFNlY29uZGFyeUluZGV4ZXMsXG4gICAgICB0aW1lVG9MaXZlQXR0cmlidXRlOiBwcm9wcy50aW1lVG9MaXZlQXR0cmlidXRlLFxuICAgICAgc3RyZWFtOiBwcm9wcy5zdHJlYW0sXG4gICAgICBwb2ludEluVGltZVJlY292ZXJ5OiBwcm9wcy5wb2ludEluVGltZVJlY292ZXJ5LFxuICAgICAgZW5jcnlwdGlvbjogcHJvcHMuZW5jcnlwdGlvbixcbiAgICAgIHJlbW92YWxQb2xpY3k6IHByb3BzLnJlbW92YWxQb2xpY3lcbiAgICB9O1xuICAgIHN1cGVyKHNjb3BlLCBpZCwgdGFibGVQcm9wcyk7XG4gIH1cbn1cblxuLyoqXG4gKiBGYWN0b3J5IGZvciBjcmVhdGluZyBEeW5hbW9EQiB0YWJsZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFNpbXBsZSB0YWJsZSB3aXRoIG9uLWRlbWFuZCBiaWxsaW5nXG4gKiBjb25zdCBjYWNoZSA9IGFwcC5hZGRUYWJsZShEeW5hbW9EQkZhY3RvcnkuYnVpbGQoXCJDYWNoZVwiLCB7XG4gKiAgIHBhcnRpdGlvbktleTogeyBuYW1lOiBcImlkXCIsIHR5cGU6IFwiU1wiIH1cbiAqIH0pKTtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGFibGUgd2l0aCBzb3J0IGtleSBhbmQgR1NJIChmb3IgT3Blbk5leHQgdGFnIGNhY2hlKVxuICogY29uc3QgdGFnQ2FjaGUgPSBhcHAuYWRkVGFibGUoRHluYW1vREJGYWN0b3J5LmJ1aWxkKFwiVGFnQ2FjaGVcIiwge1xuICogICBwYXJ0aXRpb25LZXk6IHsgbmFtZTogXCJ0YWdcIiwgdHlwZTogXCJTXCIgfSxcbiAqICAgc29ydEtleTogeyBuYW1lOiBcInBhdGhcIiwgdHlwZTogXCJTXCIgfSxcbiAqICAgZ2xvYmFsU2Vjb25kYXJ5SW5kZXhlczogW3tcbiAqICAgICBpbmRleE5hbWU6IFwicmV2YWxpZGF0ZVwiLFxuICogICAgIHBhcnRpdGlvbktleTogeyBuYW1lOiBcInBhdGhcIiwgdHlwZTogXCJTXCIgfSxcbiAqICAgICBzb3J0S2V5OiB7IG5hbWU6IFwicmV2YWxpZGF0ZWRBdFwiLCB0eXBlOiBcIk5cIiB9XG4gKiAgIH1dXG4gKiB9KSk7XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRhYmxlIHdpdGggc3RyZWFtaW5nIGZvciBMYW1iZGEgdHJpZ2dlcnNcbiAqIGNvbnN0IGV2ZW50cyA9IGFwcC5hZGRUYWJsZShEeW5hbW9EQkZhY3RvcnkuYnVpbGQoXCJFdmVudHNcIiwge1xuICogICBwYXJ0aXRpb25LZXk6IHsgbmFtZTogXCJwa1wiLCB0eXBlOiBcIlNcIiB9LFxuICogICBzb3J0S2V5OiB7IG5hbWU6IFwic2tcIiwgdHlwZTogXCJTXCIgfSxcbiAqICAgc3RyZWFtOiBcIk5FV19BTkRfT0xEX0lNQUdFU1wiXG4gKiB9KSk7XG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEdyYW50IHBlcm1pc3Npb25zXG4gKiB0YWdDYWNoZS5ncmFudFJlYWRXcml0ZShzZXJ2ZXJGdW5jdGlvbik7XG4gKi9cbmV4cG9ydCBjbGFzcyBEeW5hbW9EQkZhY3Rvcnkge1xuICAvKipcbiAgICogQnVpbGQgYSBEeW5hbW9EQiBmYWN0b3J5IGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIHRhYmxlXG4gICAqIEBwYXJhbSBwcm9wcyAtIER5bmFtb0RCIHRhYmxlIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBGYWN0b3J5IGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyB0aGUgdGFibGUgd2hlbiBpbnZva2VkXG4gICAqL1xuICBzdGF0aWMgYnVpbGQoaWQ6IHN0cmluZywgcHJvcHM6IElEeW5hbW9EQlByb3BzKSB7XG4gICAgcmV0dXJuIChfYXBwOiBBcHAsIHNjb3BlOiBDb25zdHJ1Y3QpOiBEeW5hbW9EQiA9PiB7XG4gICAgICB2YWxpZGF0ZUR5bmFtb0RCUHJvcHMocHJvcHMpO1xuICAgICAgcmV0dXJuIG5ldyBEeW5hbW9EQihzY29wZSwgaWQsIHByb3BzKTtcbiAgICB9O1xuICB9XG59XG5cbi8vIFJlLWV4cG9ydCB0eXBlcyBmb3IgY29udmVuaWVuY2VcbmV4cG9ydCB0eXBlIHtcbiAgRHluYW1vREJLZXlTY2hlbWEsXG4gIER5bmFtb0RCR2xvYmFsU2Vjb25kYXJ5SW5kZXgsXG4gIER5bmFtb0RCVGFibGVQcm9wc1xufSBmcm9tIFwiLi4vLi4vcmVzb3VyY2VzL2F3cy9kYXRhYmFzZS9keW5hbW9kYlwiO1xuIl19