@capraconsulting/webapp-deploy-lambda 2.3.0 → 2.4.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/lib/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { Source } from "./source";
2
+ export type { ISource, SourceConfig } from "./source";
3
+ export { WebappDeploy } from "./webapp-deploy";
4
+ export type { WebappDeployProps } from "./webapp-deploy";
package/lib/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Source } from "./source";
2
+ export { WebappDeploy } from "./webapp-deploy";
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUVqQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi9zb3VyY2VcIlxuZXhwb3J0IHR5cGUgeyBJU291cmNlLCBTb3VyY2VDb25maWcgfSBmcm9tIFwiLi9zb3VyY2VcIlxuZXhwb3J0IHsgV2ViYXBwRGVwbG95IH0gZnJvbSBcIi4vd2ViYXBwLWRlcGxveVwiXG5leHBvcnQgdHlwZSB7IFdlYmFwcERlcGxveVByb3BzIH0gZnJvbSBcIi4vd2ViYXBwLWRlcGxveVwiXG4iXX0=
@@ -0,0 +1,58 @@
1
+ import * as constructs from "constructs";
2
+ import * as iam from "aws-cdk-lib/aws-iam";
3
+ import * as s3 from "aws-cdk-lib/aws-s3";
4
+ import * as s3Assets from "aws-cdk-lib/aws-s3-assets";
5
+ export interface SourceConfig {
6
+ /**
7
+ * The source bucket to deploy from.
8
+ */
9
+ readonly bucket: s3.IBucket;
10
+ /**
11
+ * An S3 object key in the source bucket that points to a zip file.
12
+ */
13
+ readonly zipObjectKey: string;
14
+ }
15
+ /**
16
+ * Bind context for ISources
17
+ */
18
+ export interface SourceContext {
19
+ /**
20
+ * The role for the handler
21
+ *
22
+ * @default - no policy is modified
23
+ */
24
+ readonly handlerRole?: iam.IRole;
25
+ }
26
+ /**
27
+ * Represents a source for bucket deployments.
28
+ */
29
+ export interface ISource {
30
+ /**
31
+ * Binds the source to a bucket deployment.
32
+ */
33
+ bind(scope: constructs.Construct, context?: SourceContext): SourceConfig;
34
+ }
35
+ /**
36
+ * Specifies bucket deployment source.
37
+ *
38
+ * Usage:
39
+ *
40
+ * Source.bucket(bucket, key)
41
+ * Source.asset('/local/path/to/directory')
42
+ * Source.asset('/local/path/to/a/file.zip')
43
+ *
44
+ */
45
+ export declare class Source {
46
+ /**
47
+ * Uses a .zip file stored in an S3 bucket as the source for the destination bucket contents.
48
+ * @param bucket The S3 Bucket
49
+ * @param zipObjectKey The S3 object key of the zip file with contents
50
+ */
51
+ static bucket(bucket: s3.IBucket, zipObjectKey: string): ISource;
52
+ /**
53
+ * Uses a local asset as the deployment source.
54
+ * @param path The path to a local .zip file or a directory
55
+ */
56
+ static asset(path: string, options?: s3Assets.AssetOptions): ISource;
57
+ private constructor();
58
+ }
package/lib/source.js ADDED
@@ -0,0 +1,64 @@
1
+ import * as s3Assets from "aws-cdk-lib/aws-s3-assets";
2
+ /**
3
+ * Specifies bucket deployment source.
4
+ *
5
+ * Usage:
6
+ *
7
+ * Source.bucket(bucket, key)
8
+ * Source.asset('/local/path/to/directory')
9
+ * Source.asset('/local/path/to/a/file.zip')
10
+ *
11
+ */
12
+ export class Source {
13
+ /**
14
+ * Uses a .zip file stored in an S3 bucket as the source for the destination bucket contents.
15
+ * @param bucket The S3 Bucket
16
+ * @param zipObjectKey The S3 object key of the zip file with contents
17
+ */
18
+ static bucket(bucket, zipObjectKey) {
19
+ return {
20
+ bind: (_, context) => {
21
+ if (!context) {
22
+ throw new Error("To use a Source.bucket(), context must be provided");
23
+ }
24
+ if (context.handlerRole) {
25
+ bucket.grantRead(context.handlerRole);
26
+ }
27
+ return { bucket, zipObjectKey };
28
+ },
29
+ };
30
+ }
31
+ /**
32
+ * Uses a local asset as the deployment source.
33
+ * @param path The path to a local .zip file or a directory
34
+ */
35
+ static asset(path, options) {
36
+ return {
37
+ bind(scope, context) {
38
+ if (!context) {
39
+ throw new Error("To use a Source.asset(), context must be provided");
40
+ }
41
+ let id = 1;
42
+ while (scope.node.tryFindChild(`Asset${id}`)) {
43
+ id++;
44
+ }
45
+ const asset = new s3Assets.Asset(scope, `Asset${id}`, {
46
+ path,
47
+ ...options,
48
+ });
49
+ if (!asset.isZipArchive) {
50
+ throw new Error("Asset path must be either a .zip file or a directory");
51
+ }
52
+ if (context.handlerRole) {
53
+ asset.grantRead(context.handlerRole);
54
+ }
55
+ return {
56
+ bucket: asset.bucket,
57
+ zipObjectKey: asset.s3ObjectKey,
58
+ };
59
+ },
60
+ };
61
+ }
62
+ constructor() { }
63
+ }
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3NvdXJjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEtBQUssUUFBUSxNQUFNLDJCQUEyQixDQUFBO0FBc0NyRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8sTUFBTTtJQUNqQjs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFrQixFQUFFLFlBQW9CO1FBQzNELE9BQU87WUFDTCxJQUFJLEVBQUUsQ0FBQyxDQUF1QixFQUFFLE9BQXVCLEVBQUUsRUFBRTtnQkFDekQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNiLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQTtnQkFDdkUsQ0FBQztnQkFFRCxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztvQkFDeEIsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUE7Z0JBQ3ZDLENBQUM7Z0JBRUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsQ0FBQTtZQUNqQyxDQUFDO1NBQ0YsQ0FBQTtJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQVksRUFBRSxPQUErQjtRQUMvRCxPQUFPO1lBQ0wsSUFBSSxDQUFDLEtBQTJCLEVBQUUsT0FBdUI7Z0JBQ3ZELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDYixNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUE7Z0JBQ3RFLENBQUM7Z0JBRUQsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFBO2dCQUNWLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQzdDLEVBQUUsRUFBRSxDQUFBO2dCQUNOLENBQUM7Z0JBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFO29CQUNwRCxJQUFJO29CQUNKLEdBQUcsT0FBTztpQkFDWCxDQUFDLENBQUE7Z0JBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztvQkFDeEIsTUFBTSxJQUFJLEtBQUssQ0FDYixzREFBc0QsQ0FDdkQsQ0FBQTtnQkFDSCxDQUFDO2dCQUVELElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUN4QixLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQTtnQkFDdEMsQ0FBQztnQkFFRCxPQUFPO29CQUNMLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtvQkFDcEIsWUFBWSxFQUFFLEtBQUssQ0FBQyxXQUFXO2lCQUNoQyxDQUFBO1lBQ0gsQ0FBQztTQUNGLENBQUE7SUFDSCxDQUFDO0lBRUQsZ0JBQXVCLENBQUM7Q0FDekIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCAqIGFzIGlhbSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiXG5pbXBvcnQgKiBhcyBzMyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCJcbmltcG9ydCAqIGFzIHMzQXNzZXRzIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtYXNzZXRzXCJcblxuLy8gVGhpcyBpcyBtb3N0bHkgYmFzZWQgb24gYXdzLXMzLWRlcGxveW1lbnQgZnJvbSBhd3MtY2RrLlxuXG5leHBvcnQgaW50ZXJmYWNlIFNvdXJjZUNvbmZpZyB7XG4gIC8qKlxuICAgKiBUaGUgc291cmNlIGJ1Y2tldCB0byBkZXBsb3kgZnJvbS5cbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldDogczMuSUJ1Y2tldFxuXG4gIC8qKlxuICAgKiBBbiBTMyBvYmplY3Qga2V5IGluIHRoZSBzb3VyY2UgYnVja2V0IHRoYXQgcG9pbnRzIHRvIGEgemlwIGZpbGUuXG4gICAqL1xuICByZWFkb25seSB6aXBPYmplY3RLZXk6IHN0cmluZ1xufVxuXG4vKipcbiAqIEJpbmQgY29udGV4dCBmb3IgSVNvdXJjZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTb3VyY2VDb250ZXh0IHtcbiAgLyoqXG4gICAqIFRoZSByb2xlIGZvciB0aGUgaGFuZGxlclxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHBvbGljeSBpcyBtb2RpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgaGFuZGxlclJvbGU/OiBpYW0uSVJvbGVcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgc291cmNlIGZvciBidWNrZXQgZGVwbG95bWVudHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVNvdXJjZSB7XG4gIC8qKlxuICAgKiBCaW5kcyB0aGUgc291cmNlIHRvIGEgYnVja2V0IGRlcGxveW1lbnQuXG4gICAqL1xuICBiaW5kKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgY29udGV4dD86IFNvdXJjZUNvbnRleHQpOiBTb3VyY2VDb25maWdcbn1cblxuLyoqXG4gKiBTcGVjaWZpZXMgYnVja2V0IGRlcGxveW1lbnQgc291cmNlLlxuICpcbiAqIFVzYWdlOlxuICpcbiAqICAgICBTb3VyY2UuYnVja2V0KGJ1Y2tldCwga2V5KVxuICogICAgIFNvdXJjZS5hc3NldCgnL2xvY2FsL3BhdGgvdG8vZGlyZWN0b3J5JylcbiAqICAgICBTb3VyY2UuYXNzZXQoJy9sb2NhbC9wYXRoL3RvL2EvZmlsZS56aXAnKVxuICpcbiAqL1xuZXhwb3J0IGNsYXNzIFNvdXJjZSB7XG4gIC8qKlxuICAgKiBVc2VzIGEgLnppcCBmaWxlIHN0b3JlZCBpbiBhbiBTMyBidWNrZXQgYXMgdGhlIHNvdXJjZSBmb3IgdGhlIGRlc3RpbmF0aW9uIGJ1Y2tldCBjb250ZW50cy5cbiAgICogQHBhcmFtIGJ1Y2tldCBUaGUgUzMgQnVja2V0XG4gICAqIEBwYXJhbSB6aXBPYmplY3RLZXkgVGhlIFMzIG9iamVjdCBrZXkgb2YgdGhlIHppcCBmaWxlIHdpdGggY29udGVudHNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYnVja2V0KGJ1Y2tldDogczMuSUJ1Y2tldCwgemlwT2JqZWN0S2V5OiBzdHJpbmcpOiBJU291cmNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgYmluZDogKF86IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBjb250ZXh0PzogU291cmNlQ29udGV4dCkgPT4ge1xuICAgICAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUbyB1c2UgYSBTb3VyY2UuYnVja2V0KCksIGNvbnRleHQgbXVzdCBiZSBwcm92aWRlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbnRleHQuaGFuZGxlclJvbGUpIHtcbiAgICAgICAgICBidWNrZXQuZ3JhbnRSZWFkKGNvbnRleHQuaGFuZGxlclJvbGUpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBidWNrZXQsIHppcE9iamVjdEtleSB9XG4gICAgICB9LFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VzIGEgbG9jYWwgYXNzZXQgYXMgdGhlIGRlcGxveW1lbnQgc291cmNlLlxuICAgKiBAcGFyYW0gcGF0aCBUaGUgcGF0aCB0byBhIGxvY2FsIC56aXAgZmlsZSBvciBhIGRpcmVjdG9yeVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3NldChwYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiBzM0Fzc2V0cy5Bc3NldE9wdGlvbnMpOiBJU291cmNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgYmluZChzY29wZTogY29uc3RydWN0cy5Db25zdHJ1Y3QsIGNvbnRleHQ/OiBTb3VyY2VDb250ZXh0KTogU291cmNlQ29uZmlnIHtcbiAgICAgICAgaWYgKCFjb250ZXh0KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG8gdXNlIGEgU291cmNlLmFzc2V0KCksIGNvbnRleHQgbXVzdCBiZSBwcm92aWRlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGlkID0gMVxuICAgICAgICB3aGlsZSAoc2NvcGUubm9kZS50cnlGaW5kQ2hpbGQoYEFzc2V0JHtpZH1gKSkge1xuICAgICAgICAgIGlkKytcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhc3NldCA9IG5ldyBzM0Fzc2V0cy5Bc3NldChzY29wZSwgYEFzc2V0JHtpZH1gLCB7XG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICB9KVxuICAgICAgICBpZiAoIWFzc2V0LmlzWmlwQXJjaGl2ZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIFwiQXNzZXQgcGF0aCBtdXN0IGJlIGVpdGhlciBhIC56aXAgZmlsZSBvciBhIGRpcmVjdG9yeVwiLFxuICAgICAgICAgIClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250ZXh0LmhhbmRsZXJSb2xlKSB7XG4gICAgICAgICAgYXNzZXQuZ3JhbnRSZWFkKGNvbnRleHQuaGFuZGxlclJvbGUpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGJ1Y2tldDogYXNzZXQuYnVja2V0LFxuICAgICAgICAgIHppcE9iamVjdEtleTogYXNzZXQuczNPYmplY3RLZXksXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG59XG4iXX0=
@@ -0,0 +1,64 @@
1
+ import * as constructs from "constructs";
2
+ import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
3
+ import * as lambda from "aws-cdk-lib/aws-lambda";
4
+ import * as s3 from "aws-cdk-lib/aws-s3";
5
+ import * as cdk from "aws-cdk-lib";
6
+ import { ISource } from "./source";
7
+ export interface WebappDeployProps {
8
+ /**
9
+ * Optional S3 bucket that can be used for deployment from outside CDK.
10
+ *
11
+ * If specified a policy is added so the deploy function can read from
12
+ * the bucket.
13
+ *
14
+ * @default - none
15
+ */
16
+ buildsBucket?: s3.IBucket;
17
+ /**
18
+ * CloudFront Distribution to be invalidated after deploy.
19
+ *
20
+ * @default - none
21
+ */
22
+ distribution?: cloudfront.IDistribution;
23
+ /**
24
+ * Regex for patterns of files to be discarded during deployment.
25
+ *
26
+ * Example: `\.map$` will exclude `js/myapp-1b22c248f.js.map`.
27
+ *
28
+ * @default - none
29
+ */
30
+ excludePattern?: string;
31
+ /**
32
+ * The time when a deployment is considered old and will be deleted
33
+ * unless it is the newest old deployment.
34
+ *
35
+ * @default - 5 days
36
+ */
37
+ pruneDeploymentsOlderThan?: cdk.Duration;
38
+ /**
39
+ * Name of the lambda function to be created.
40
+ *
41
+ * @default cdk.PhysicalName.GENERATE_IF_NEEDED
42
+ */
43
+ functionName?: string;
44
+ /**
45
+ * Name of S3 bucket where the contents of the artifacts will be deployed.
46
+ * The files will be deployed under the key "web", which is then expected
47
+ * to be the origin for the CloudFront distribution
48
+ */
49
+ webBucket: s3.IBucket;
50
+ /**
51
+ * Specific artifact to be deployed to the bucket during CDK deployment.
52
+ *
53
+ * @default - none
54
+ */
55
+ source?: ISource;
56
+ }
57
+ /**
58
+ * Resource to deploy a webapp from a build artifact into an existing
59
+ * S3 Bucket and CloudFront Distribution.
60
+ */
61
+ export declare class WebappDeploy extends constructs.Construct {
62
+ readonly deployFn: lambda.Function;
63
+ constructor(scope: constructs.Construct, id: string, props: WebappDeployProps);
64
+ }
@@ -0,0 +1,66 @@
1
+ import * as constructs from "constructs";
2
+ import * as iam from "aws-cdk-lib/aws-iam";
3
+ import * as lambda from "aws-cdk-lib/aws-lambda";
4
+ import * as cdk from "aws-cdk-lib";
5
+ import { Provider } from "aws-cdk-lib/custom-resources";
6
+ import * as path from "path";
7
+ import { fileURLToPath } from "url";
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ /**
10
+ * Resource to deploy a webapp from a build artifact into an existing
11
+ * S3 Bucket and CloudFront Distribution.
12
+ */
13
+ export class WebappDeploy extends constructs.Construct {
14
+ deployFn;
15
+ constructor(scope, id, props) {
16
+ super(scope, id);
17
+ const environment = {
18
+ DEPLOY_LOG_BUCKET_URL: `s3://${props.webBucket.bucketName}/deployments.log`,
19
+ EXPIRE_SECONDS: (props.pruneDeploymentsOlderThan ?? cdk.Duration.days(5))
20
+ .toSeconds()
21
+ .toString(),
22
+ TARGET_BUCKET_URL: `s3://${props.webBucket.bucketName}/web`,
23
+ };
24
+ if (props.distribution != null) {
25
+ environment.CF_DISTRIBUTION_ID = props.distribution.distributionId;
26
+ }
27
+ if (props.excludePattern != null) {
28
+ environment.EXCLUDE_PATTERN = props.excludePattern;
29
+ }
30
+ this.deployFn = new lambda.Function(this, "WebappDeployResource", {
31
+ code: lambda.Code.fromAsset(path.join(__dirname, "../dist")),
32
+ environment,
33
+ functionName: props.functionName ?? cdk.PhysicalName.GENERATE_IF_NEEDED,
34
+ handler: "webapp_deploy.main.handler",
35
+ reservedConcurrentExecutions: 1,
36
+ runtime: lambda.Runtime.PYTHON_3_12,
37
+ timeout: cdk.Duration.minutes(2),
38
+ initialPolicy: [
39
+ new iam.PolicyStatement({
40
+ actions: ["cloudfront:CreateInvalidation"],
41
+ // Cannot be restricted
42
+ resources: ["*"],
43
+ }),
44
+ ],
45
+ });
46
+ const provider = new Provider(this, "Provider", {
47
+ onEventHandler: this.deployFn,
48
+ });
49
+ props.webBucket.grantReadWrite(this.deployFn);
50
+ if (props.buildsBucket) {
51
+ props.buildsBucket.grantRead(this.deployFn);
52
+ }
53
+ if (props.source) {
54
+ const source = props.source.bind(this, {
55
+ handlerRole: this.deployFn.role,
56
+ });
57
+ new cdk.CustomResource(this, "CustomResource", {
58
+ serviceToken: provider.serviceToken,
59
+ properties: {
60
+ artifactS3Url: `s3://${source.bucket.bucketName}/${source.zipObjectKey}`,
61
+ },
62
+ });
63
+ }
64
+ }
65
+ }
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViYXBwLWRlcGxveS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy93ZWJhcHAtZGVwbG95LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBRXhDLE9BQU8sS0FBSyxHQUFHLE1BQU0scUJBQXFCLENBQUE7QUFDMUMsT0FBTyxLQUFLLE1BQU0sTUFBTSx3QkFBd0IsQ0FBQTtBQUVoRCxPQUFPLEtBQUssR0FBRyxNQUFNLGFBQWEsQ0FBQTtBQUNsQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sOEJBQThCLENBQUE7QUFDdkQsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUE7QUFFNUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUVuQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFxRDlEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxZQUFhLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFDM0MsUUFBUSxDQUFpQjtJQUVsQyxZQUNFLEtBQTJCLEVBQzNCLEVBQVUsRUFDVixLQUF3QjtRQUV4QixLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRWhCLE1BQU0sV0FBVyxHQUEyQjtZQUMxQyxxQkFBcUIsRUFBRSxRQUFRLEtBQUssQ0FBQyxTQUFTLENBQUMsVUFBVSxrQkFBa0I7WUFDM0UsY0FBYyxFQUFFLENBQUMsS0FBSyxDQUFDLHlCQUF5QixJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUN0RSxTQUFTLEVBQUU7aUJBQ1gsUUFBUSxFQUFFO1lBQ2IsaUJBQWlCLEVBQUUsUUFBUSxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsTUFBTTtTQUM1RCxDQUFBO1FBRUQsSUFBSSxLQUFLLENBQUMsWUFBWSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQy9CLFdBQVcsQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQTtRQUNwRSxDQUFDO1FBRUQsSUFBSSxLQUFLLENBQUMsY0FBYyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ2pDLFdBQVcsQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQTtRQUNwRCxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLHNCQUFzQixFQUFFO1lBQ2hFLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUM1RCxXQUFXO1lBQ1gsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxrQkFBa0I7WUFDdkUsT0FBTyxFQUFFLDRCQUE0QjtZQUNyQyw0QkFBNEIsRUFBRSxDQUFDO1lBQy9CLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVc7WUFDbkMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNoQyxhQUFhLEVBQUU7Z0JBQ2IsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDO29CQUN0QixPQUFPLEVBQUUsQ0FBQywrQkFBK0IsQ0FBQztvQkFDMUMsdUJBQXVCO29CQUN2QixTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsQ0FBQTtRQUVGLE1BQU0sUUFBUSxHQUFHLElBQUksUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDOUMsY0FBYyxFQUFFLElBQUksQ0FBQyxRQUFRO1NBQzlCLENBQUMsQ0FBQTtRQUVGLEtBQUssQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUU3QyxJQUFJLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN2QixLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDN0MsQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2pCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDckMsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSzthQUNqQyxDQUFDLENBQUE7WUFDRixJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFO2dCQUM3QyxZQUFZLEVBQUUsUUFBUSxDQUFDLFlBQVk7Z0JBQ25DLFVBQVUsRUFBRTtvQkFDVixhQUFhLEVBQUUsUUFBUSxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFO2lCQUN6RTthQUNGLENBQUMsQ0FBQTtRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCAqIGFzIGNsb3VkZnJvbnQgZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250XCJcbmltcG9ydCAqIGFzIGlhbSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiXG5pbXBvcnQgKiBhcyBsYW1iZGEgZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIlxuaW1wb3J0ICogYXMgczMgZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiXG5pbXBvcnQgKiBhcyBjZGsgZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSBcImF3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXNcIlxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQgeyBJU291cmNlIH0gZnJvbSBcIi4vc291cmNlXCJcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tIFwidXJsXCJcblxuY29uc3QgX19kaXJuYW1lID0gcGF0aC5kaXJuYW1lKGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKSlcblxuZXhwb3J0IGludGVyZmFjZSBXZWJhcHBEZXBsb3lQcm9wcyB7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBTMyBidWNrZXQgdGhhdCBjYW4gYmUgdXNlZCBmb3IgZGVwbG95bWVudCBmcm9tIG91dHNpZGUgQ0RLLlxuICAgKlxuICAgKiBJZiBzcGVjaWZpZWQgYSBwb2xpY3kgaXMgYWRkZWQgc28gdGhlIGRlcGxveSBmdW5jdGlvbiBjYW4gcmVhZCBmcm9tXG4gICAqIHRoZSBidWNrZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgYnVpbGRzQnVja2V0PzogczMuSUJ1Y2tldFxuICAvKipcbiAgICogQ2xvdWRGcm9udCBEaXN0cmlidXRpb24gdG8gYmUgaW52YWxpZGF0ZWQgYWZ0ZXIgZGVwbG95LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vbmVcbiAgICovXG4gIGRpc3RyaWJ1dGlvbj86IGNsb3VkZnJvbnQuSURpc3RyaWJ1dGlvblxuICAvKipcbiAgICogUmVnZXggZm9yIHBhdHRlcm5zIG9mIGZpbGVzIHRvIGJlIGRpc2NhcmRlZCBkdXJpbmcgZGVwbG95bWVudC5cbiAgICpcbiAgICogRXhhbXBsZTogYFxcLm1hcCRgIHdpbGwgZXhjbHVkZSBganMvbXlhcHAtMWIyMmMyNDhmLmpzLm1hcGAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgZXhjbHVkZVBhdHRlcm4/OiBzdHJpbmdcbiAgLyoqXG4gICAqIFRoZSB0aW1lIHdoZW4gYSBkZXBsb3ltZW50IGlzIGNvbnNpZGVyZWQgb2xkIGFuZCB3aWxsIGJlIGRlbGV0ZWRcbiAgICogdW5sZXNzIGl0IGlzIHRoZSBuZXdlc3Qgb2xkIGRlcGxveW1lbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gNSBkYXlzXG4gICAqL1xuICBwcnVuZURlcGxveW1lbnRzT2xkZXJUaGFuPzogY2RrLkR1cmF0aW9uXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBsYW1iZGEgZnVuY3Rpb24gdG8gYmUgY3JlYXRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgY2RrLlBoeXNpY2FsTmFtZS5HRU5FUkFURV9JRl9ORUVERURcbiAgICovXG4gIGZ1bmN0aW9uTmFtZT86IHN0cmluZ1xuICAvKipcbiAgICogTmFtZSBvZiBTMyBidWNrZXQgd2hlcmUgdGhlIGNvbnRlbnRzIG9mIHRoZSBhcnRpZmFjdHMgd2lsbCBiZSBkZXBsb3llZC5cbiAgICogVGhlIGZpbGVzIHdpbGwgYmUgZGVwbG95ZWQgdW5kZXIgdGhlIGtleSBcIndlYlwiLCB3aGljaCBpcyB0aGVuIGV4cGVjdGVkXG4gICAqIHRvIGJlIHRoZSBvcmlnaW4gZm9yIHRoZSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvblxuICAgKi9cbiAgd2ViQnVja2V0OiBzMy5JQnVja2V0XG4gIC8qKlxuICAgKiBTcGVjaWZpYyBhcnRpZmFjdCB0byBiZSBkZXBsb3llZCB0byB0aGUgYnVja2V0IGR1cmluZyBDREsgZGVwbG95bWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICBzb3VyY2U/OiBJU291cmNlXG59XG5cbi8qKlxuICogUmVzb3VyY2UgdG8gZGVwbG95IGEgd2ViYXBwIGZyb20gYSBidWlsZCBhcnRpZmFjdCBpbnRvIGFuIGV4aXN0aW5nXG4gKiBTMyBCdWNrZXQgYW5kIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgV2ViYXBwRGVwbG95IGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3Qge1xuICByZWFkb25seSBkZXBsb3lGbjogbGFtYmRhLkZ1bmN0aW9uXG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IFdlYmFwcERlcGxveVByb3BzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBjb25zdCBlbnZpcm9ubWVudDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIERFUExPWV9MT0dfQlVDS0VUX1VSTDogYHMzOi8vJHtwcm9wcy53ZWJCdWNrZXQuYnVja2V0TmFtZX0vZGVwbG95bWVudHMubG9nYCxcbiAgICAgIEVYUElSRV9TRUNPTkRTOiAocHJvcHMucHJ1bmVEZXBsb3ltZW50c09sZGVyVGhhbiA/PyBjZGsuRHVyYXRpb24uZGF5cyg1KSlcbiAgICAgICAgLnRvU2Vjb25kcygpXG4gICAgICAgIC50b1N0cmluZygpLFxuICAgICAgVEFSR0VUX0JVQ0tFVF9VUkw6IGBzMzovLyR7cHJvcHMud2ViQnVja2V0LmJ1Y2tldE5hbWV9L3dlYmAsXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRpc3RyaWJ1dGlvbiAhPSBudWxsKSB7XG4gICAgICBlbnZpcm9ubWVudC5DRl9ESVNUUklCVVRJT05fSUQgPSBwcm9wcy5kaXN0cmlidXRpb24uZGlzdHJpYnV0aW9uSWRcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuZXhjbHVkZVBhdHRlcm4gIT0gbnVsbCkge1xuICAgICAgZW52aXJvbm1lbnQuRVhDTFVERV9QQVRURVJOID0gcHJvcHMuZXhjbHVkZVBhdHRlcm5cbiAgICB9XG5cbiAgICB0aGlzLmRlcGxveUZuID0gbmV3IGxhbWJkYS5GdW5jdGlvbih0aGlzLCBcIldlYmFwcERlcGxveVJlc291cmNlXCIsIHtcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCBcIi4uL2Rpc3RcIikpLFxuICAgICAgZW52aXJvbm1lbnQsXG4gICAgICBmdW5jdGlvbk5hbWU6IHByb3BzLmZ1bmN0aW9uTmFtZSA/PyBjZGsuUGh5c2ljYWxOYW1lLkdFTkVSQVRFX0lGX05FRURFRCxcbiAgICAgIGhhbmRsZXI6IFwid2ViYXBwX2RlcGxveS5tYWluLmhhbmRsZXJcIixcbiAgICAgIHJlc2VydmVkQ29uY3VycmVudEV4ZWN1dGlvbnM6IDEsXG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5QWVRIT05fM18xMixcbiAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5taW51dGVzKDIpLFxuICAgICAgaW5pdGlhbFBvbGljeTogW1xuICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgYWN0aW9uczogW1wiY2xvdWRmcm9udDpDcmVhdGVJbnZhbGlkYXRpb25cIl0sXG4gICAgICAgICAgLy8gQ2Fubm90IGJlIHJlc3RyaWN0ZWRcbiAgICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICAgIH0pLFxuICAgICAgXSxcbiAgICB9KVxuXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgXCJQcm92aWRlclwiLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogdGhpcy5kZXBsb3lGbixcbiAgICB9KVxuXG4gICAgcHJvcHMud2ViQnVja2V0LmdyYW50UmVhZFdyaXRlKHRoaXMuZGVwbG95Rm4pXG5cbiAgICBpZiAocHJvcHMuYnVpbGRzQnVja2V0KSB7XG4gICAgICBwcm9wcy5idWlsZHNCdWNrZXQuZ3JhbnRSZWFkKHRoaXMuZGVwbG95Rm4pXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnNvdXJjZSkge1xuICAgICAgY29uc3Qgc291cmNlID0gcHJvcHMuc291cmNlLmJpbmQodGhpcywge1xuICAgICAgICBoYW5kbGVyUm9sZTogdGhpcy5kZXBsb3lGbi5yb2xlISxcbiAgICAgIH0pXG4gICAgICBuZXcgY2RrLkN1c3RvbVJlc291cmNlKHRoaXMsIFwiQ3VzdG9tUmVzb3VyY2VcIiwge1xuICAgICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIGFydGlmYWN0UzNVcmw6IGBzMzovLyR7c291cmNlLmJ1Y2tldC5idWNrZXROYW1lfS8ke3NvdXJjZS56aXBPYmplY3RLZXl9YCxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfVxuICB9XG59XG4iXX0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capraconsulting/webapp-deploy-lambda",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "CDK construct for deploying a webapp release to S3 and CloudFront",
5
5
  "type": "module",
6
6
  "repository": {
@@ -10,7 +10,7 @@
10
10
  "scripts": {
11
11
  "build": "./build.sh && tsc",
12
12
  "watch": "tsc -w",
13
- "test": "jest",
13
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest",
14
14
  "lint": "eslint .",
15
15
  "lint:fix": "eslint --fix .",
16
16
  "prepare": "npm run build && husky",
@@ -40,27 +40,27 @@
40
40
  },
41
41
  "devDependencies": {
42
42
  "@aws-cdk/assert": "2.68.0",
43
- "@commitlint/cli": "19.6.0",
43
+ "@commitlint/cli": "19.6.1",
44
44
  "@commitlint/config-conventional": "19.6.0",
45
45
  "@eslint/eslintrc": "3.2.0",
46
- "@eslint/js": "9.16.0",
46
+ "@eslint/js": "9.18.0",
47
47
  "@types/jest": "29.5.14",
48
- "@types/node": "22.10.2",
49
- "@typescript-eslint/eslint-plugin": "8.18.0",
50
- "@typescript-eslint/parser": "8.18.0",
51
- "aws-cdk-lib": "2.173.0",
48
+ "@types/node": "22.10.5",
49
+ "@typescript-eslint/eslint-plugin": "8.19.1",
50
+ "@typescript-eslint/parser": "8.19.1",
51
+ "aws-cdk-lib": "2.173.4",
52
52
  "constructs": "10.4.2",
53
- "eslint": "9.16.0",
53
+ "eslint": "9.18.0",
54
54
  "eslint-config-prettier": "9.1.0",
55
55
  "eslint-plugin-prettier": "5.2.1",
56
56
  "husky": "9.1.7",
57
57
  "jest": "29.7.0",
58
58
  "jest-cdk-snapshot": "2.2.5",
59
59
  "prettier": "3.4.2",
60
- "semantic-release": "24.2.0",
60
+ "semantic-release": "24.2.1",
61
61
  "ts-jest": "29.2.5",
62
62
  "tsx": "4.19.2",
63
- "typescript": "5.7.2"
63
+ "typescript": "5.7.3"
64
64
  },
65
65
  "peerDependencies": {
66
66
  "aws-cdk-lib": "^2.0.0",