@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.
- package/dist/lib/__tests__/setup.js +1 -78
- package/dist/lib/app.d.ts +5 -0
- package/dist/lib/app.js +29 -1
- package/dist/lib/config/aws/ecrDefaultImage.js +23 -21
- package/dist/lib/patterns/aws/compute.d.ts +29 -21
- package/dist/lib/patterns/aws/compute.js +10 -3
- package/dist/lib/patterns/aws/database.d.ts +1 -0
- package/dist/lib/patterns/aws/database.js +33 -3
- package/dist/lib/patterns/aws/storage.d.ts +1 -0
- package/dist/lib/patterns/aws/storage.js +23 -1
- package/dist/lib/resources/aws/compute/ecs.d.ts +50 -2
- package/dist/lib/resources/aws/compute/ecs.js +134 -18
- package/dist/lib/resources/aws/compute/ecsFreeTier.d.ts +2 -1
- package/dist/lib/resources/aws/compute/ecsFreeTier.js +1 -352
- package/dist/lib/resources/aws/compute/ecsSpot.d.ts +2 -1
- package/dist/lib/resources/aws/compute/ecsSpot.js +1 -332
- package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.js +1 -180
- package/dist/lib/resources/aws/monitoring/monitoringRole.js +61 -4
- package/dist/lib/resources/aws/utilities/cfnOutput.js +1 -13
- package/package.json +3 -3
- package/dist/lib/patterns/aws/cdn.d.ts +0 -133
- package/dist/lib/patterns/aws/cdn.js +0 -216
- package/dist/lib/patterns/aws/dynamodb.d.ts +0 -66
- package/dist/lib/patterns/aws/dynamodb.js +0 -106
- package/dist/lib/patterns/aws/loadBalancer.d.ts +0 -163
- package/dist/lib/patterns/aws/loadBalancer.js +0 -278
- package/dist/lib/patterns/aws/queue.d.ts +0 -61
- package/dist/lib/patterns/aws/queue.js +0 -103
- package/dist/lib/resources/aws/cdn/cloudFront.d.ts +0 -65
- package/dist/lib/resources/aws/cdn/cloudFront.js +0 -135
- package/dist/lib/resources/aws/cdn/index.d.ts +0 -1
- package/dist/lib/resources/aws/cdn/index.js +0 -18
- package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.d.ts +0 -20
- package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.js +0 -180
- package/dist/lib/resources/aws/database/dynamodb.d.ts +0 -70
- package/dist/lib/resources/aws/database/dynamodb.js +0 -170
- package/dist/lib/resources/aws/database/rdsDeletionWaiter.d.ts +0 -33
- package/dist/lib/resources/aws/database/rdsDeletionWaiter.js +0 -74
- package/dist/lib/resources/aws/messaging/index.d.ts +0 -1
- package/dist/lib/resources/aws/messaging/index.js +0 -18
- package/dist/lib/resources/aws/messaging/sqs.d.ts +0 -65
- package/dist/lib/resources/aws/messaging/sqs.js +0 -195
- package/dist/lib/resources/aws/networking/vpcEndpoint.d.ts +0 -20
- package/dist/lib/resources/aws/networking/vpcEndpoint.js +0 -59
- package/dist/lib/resources/aws/networking/vpcEndpoints.d.ts +0 -71
- package/dist/lib/resources/aws/networking/vpcEndpoints.js +0 -125
- package/dist/lib/resources/aws/utilities/cfnOutput.test.d.ts +0 -1
- package/dist/lib/resources/aws/utilities/cfnOutput.test.js +0 -102
- package/dist/lib/utils/sanitizeCfnKey.d.ts +0 -5
- package/dist/lib/utils/sanitizeCfnKey.js +0 -11
- package/dist/lib/utils/tagResource.d.ts +0 -24
- 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.
|
|
3
|
+
"version": "0.82.0",
|
|
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.
|
|
39
|
+
"@fjall/util": "^0.82.0",
|
|
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": "
|
|
48
|
+
"gitHead": "c5e406a6661d858023d507164fd31ec3c39d90df",
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL3BhdHRlcm5zL2F3cy9jZG4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBT0EsaURBTWlDO0FBQ2pDLHVDQUFzQztBQUN0Qyx1Q0FBb0M7QUFvRXBDOztHQUVHO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFnQjtJQUN4QyxzQ0FBc0M7SUFDdEMsSUFBSSxLQUFLLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDM0UsT0FBTyxDQUFDLElBQUksQ0FDVixxRUFBcUU7WUFDbkUsbURBQW1ELENBQ3RELENBQUM7SUFDSixDQUFDO0lBRUQsNENBQTRDO0lBQzVDLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDNUUsT0FBTyxDQUFDLElBQUksQ0FDViwwRUFBMEU7WUFDeEUsOERBQThELENBQ2pFLENBQUM7SUFDSixDQUFDO0lBRUQsc0JBQXNCO0lBQ3RCLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUMvQixNQUFNLFFBQVEsR0FBRyxLQUFvQixDQUFDO1FBQ3RDLElBQUksUUFBUSxDQUFDLFlBQVksWUFBWSxpQkFBTyxFQUFFLENBQUM7WUFDN0MsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNuRCxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ1IsTUFBTSxJQUFJLEtBQUssQ0FDYixrREFBa0Q7b0JBQ2hELDZEQUE2RCxDQUNoRSxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsd0JBQXdCO0lBQ3hCLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUNoQyxNQUFNLFVBQVUsR0FBRyxLQUFzQixDQUFDO1FBQzFDLElBQUksVUFBVSxDQUFDLE1BQU0sWUFBWSxpQkFBTyxFQUFFLENBQUM7WUFDekMsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2RCxJQUFJLFdBQVcsS0FBSyxLQUFLLEVBQUUsQ0FBQztnQkFDMUIsTUFBTSxJQUFJLEtBQUssQ0FDYixvREFBb0Q7b0JBQ2xELHlEQUF5RCxDQUM1RCxDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksV0FBVyxLQUFLLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQztnQkFDbEUsTUFBTSxJQUFJLEtBQUssQ0FDYix3REFBd0Q7b0JBQ3RELHdEQUF3RCxDQUMzRCxDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksV0FBVyxLQUFLLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQztnQkFDcEUsTUFBTSxJQUFJLEtBQUssQ0FDYiwwREFBMEQ7b0JBQ3hELDBEQUEwRCxDQUM3RCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBYSxHQUFJLFNBQVEsNEJBQXNCO0lBQzdDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBZ0I7UUFDeEQsTUFBTSxhQUFhLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O09BRUc7SUFDSyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQWdCO1FBQzFDLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0RCxPQUFPO1lBQ0wsYUFBYTtZQUNiLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxXQUFXO1lBQ3JDLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtZQUM1QixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVc7WUFDOUIsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO1lBQzlCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztZQUN0QixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7WUFDbEMsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1NBQzNCLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSyxNQUFNLENBQUMsb0JBQW9CLENBQUMsS0FBZ0I7UUFDbEQsUUFBUSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDekIsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNWLE1BQU0sT0FBTyxHQUFHLEtBQW1CLENBQUM7Z0JBQ3BDLE1BQU0sTUFBTSxHQUNWLE9BQU8sQ0FBQyxNQUFNLFlBQVksbUJBQVM7b0JBQ2pDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRTtvQkFDNUIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7Z0JBQ3JCLE9BQU87b0JBQ0wsSUFBSSxFQUFFLElBQUk7b0JBQ1YsTUFBTTtvQkFDTixVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7aUJBQy9CLENBQUM7WUFDSixDQUFDO1lBRUQsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNYLE1BQU0sUUFBUSxHQUFHLEtBQW9CLENBQUM7Z0JBQ3RDLE1BQU0sWUFBWSxHQUNoQixRQUFRLENBQUMsWUFBWSxZQUFZLGlCQUFPO29CQUN0QyxDQUFDLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUc7b0JBQzFDLENBQUMsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDO2dCQUM1QixPQUFPO29CQUNMLElBQUksRUFBRSxLQUFLO29CQUNYLFlBQVk7b0JBQ1osY0FBYyxFQUFFLFFBQVEsQ0FBQyxjQUFjO2lCQUN4QyxDQUFDO1lBQ0osQ0FBQztZQUVELEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDWixNQUFNLFNBQVMsR0FBRyxLQUFxQixDQUFDO2dCQUN4QyxPQUFPO29CQUNMLElBQUksRUFBRSxNQUFNO29CQUNaLFVBQVUsRUFBRSxTQUFTLENBQUMsVUFBVTtvQkFDaEMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxVQUFVO29CQUNoQyxjQUFjLEVBQUUsU0FBUyxDQUFDLGNBQWM7aUJBQ3pDLENBQUM7WUFDSixDQUFDO1lBRUQsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUNaLE1BQU0sVUFBVSxHQUFHLEtBQXNCLENBQUM7Z0JBQzFDLE9BQU8sR0FBRyxDQUFDLHdCQUF3QixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN6RCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLE1BQU0sQ0FBQyx3QkFBd0IsQ0FDckMsUUFBc0M7UUFFdEMsdUJBQXVCO1FBQ3ZCLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDakMsT0FBTztnQkFDTCxJQUFJLEVBQUUsTUFBTTtnQkFDWixVQUFVLEVBQUUsUUFBUTthQUNyQixDQUFDO1FBQ0osQ0FBQztRQUVELHdCQUF3QjtRQUN4QixJQUFJLFFBQVEsWUFBWSxtQkFBUyxFQUFFLENBQUM7WUFDbEMsT0FBTztnQkFDTCxJQUFJLEVBQUUsSUFBSTtnQkFDVixNQUFNLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRTthQUM3QixDQUFDO1FBQ0osQ0FBQztRQUVELGlDQUFpQztRQUNqQyxJQUFJLFFBQVEsWUFBWSxpQkFBTyxFQUFFLENBQUM7WUFDaEMsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBRTlDLElBQUksV0FBVyxLQUFLLEtBQUssRUFBRSxDQUFDO2dCQUMxQixNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ2hELElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2pCLE9BQU87d0JBQ0wsSUFBSSxFQUFFLEtBQUs7d0JBQ1gsWUFBWTtxQkFDYixDQUFDO2dCQUNKLENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDOUMsSUFBSSxXQUFXLEVBQUUsQ0FBQztvQkFDaEIsd0NBQXdDO29CQUN4QyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDakMsT0FBTzt3QkFDTCxJQUFJLEVBQUUsTUFBTTt3QkFDWixVQUFVLEVBQUUsR0FBRyxDQUFDLFFBQVE7cUJBQ3pCLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxJQUFJLEtBQUssQ0FDYiw4Q0FBOEMsT0FBTyxRQUFRLElBQUk7WUFDL0QseURBQXlELENBQzVELENBQUM7SUFDSixDQUFDO0NBQ0Y7QUE5SEQsa0JBOEhDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQ0c7QUFDSCxNQUFhLFVBQVU7SUFDckI7Ozs7OztPQU1HO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFVLEVBQUUsS0FBZ0I7UUFDdkMsT0FBTyxDQUFDLElBQVMsRUFBRSxLQUFnQixFQUFPLEVBQUU7WUFDMUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDeEIsT0FBTyxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQWRELGdDQWNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IHR5cGUgSUJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IHR5cGUgSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQgeyB0eXBlIElDZXJ0aWZpY2F0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIElDYWNoZVBvbGljeSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udFwiO1xuXG5pbXBvcnQgdHlwZSBBcHAgZnJvbSBcIi4uLy4uL2FwcFwiO1xuaW1wb3J0IHtcbiAgQ2xvdWRGcm9udERpc3RyaWJ1dGlvbixcbiAgdHlwZSBDbG91ZEZyb250RGlzdHJpYnV0aW9uUHJvcHMsXG4gIHR5cGUgQ2RuT3JpZ2luQ29uZmlnLFxuICB0eXBlIENkbkJlaGF2aW91cixcbiAgdHlwZSBDYWNoZVBvbGljeVByZXNldFxufSBmcm9tIFwiLi4vLi4vcmVzb3VyY2VzL2F3cy9jZG5cIjtcbmltcG9ydCB7IFMzU3RvcmFnZSB9IGZyb20gXCIuL3N0b3JhZ2VcIjtcbmltcG9ydCB7IENvbXB1dGUgfSBmcm9tIFwiLi9jb21wdXRlXCI7XG5cbi8qKlxuICogUzMgb3JpZ2luIENETiBwcm9wcyAtIHVzZSB3aXRoIFMzIGJ1Y2tldFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFMzQ2RuUHJvcHMge1xuICBvcmlnaW5UeXBlOiBcInMzXCI7XG4gIGJ1Y2tldDogSUJ1Y2tldCB8IFMzU3RvcmFnZTtcbiAgb3JpZ2luUGF0aD86IHN0cmluZztcbiAgY2FjaGVQb2xpY3k/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
|