@codedrifters/constructs 0.0.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/README.md ADDED
@@ -0,0 +1 @@
1
+ # replace this
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./s3";
2
+ export * from "./static-hosting";
package/lib/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./s3"), exports);
18
+ __exportStar(require("./static-hosting"), exports);
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUFxQjtBQUNyQixtREFBaUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tIFwiLi9zM1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vc3RhdGljLWhvc3RpbmdcIjtcbiJdfQ==
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Returns the current full git branch name
3
+ *
4
+ * ie: feature/1234 returns feature/1234
5
+ *
6
+ */
7
+ export declare const findGitBranch: () => string;
8
+ export declare const findGitRepoName: () => string;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findGitRepoName = exports.findGitBranch = void 0;
4
+ const node_child_process_1 = require("node:child_process");
5
+ /**
6
+ * Returns the current full git branch name
7
+ *
8
+ * ie: feature/1234 returns feature/1234
9
+ *
10
+ */
11
+ const findGitBranch = () => {
12
+ return (0, node_child_process_1.execSync)("git rev-parse --abbrev-ref HEAD")
13
+ .toString("utf8")
14
+ .replace(/[\n\r\s]+$/, "");
15
+ };
16
+ exports.findGitBranch = findGitBranch;
17
+ const findGitRepoName = () => {
18
+ /**
19
+ * When running in github actions this will be populated.
20
+ */
21
+ if (process.env.GITHUB_REPOSITORY) {
22
+ return process.env.GITHUB_REPOSITORY;
23
+ }
24
+ /**
25
+ * locally, we need to extract the repo name from the git config.
26
+ */
27
+ const remote = (0, node_child_process_1.execSync)("git config --get remote.origin.url")
28
+ .toString("utf8")
29
+ .replace(/[\n\r\s]+$/, "")
30
+ .trim();
31
+ const match = remote.match(/[:\/]([^/]+\/[^/]+?)(?:\.git)?$/);
32
+ const repoName = match ? match[1] : "error-repo-name";
33
+ return repoName;
34
+ };
35
+ exports.findGitRepoName = findGitRepoName;
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0LXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9naXQtdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkRBQThDO0FBRTlDOzs7OztHQUtHO0FBQ0ksTUFBTSxhQUFhLEdBQUcsR0FBVyxFQUFFO0lBQ3hDLE9BQU8sSUFBQSw2QkFBUSxFQUFDLGlDQUFpQyxDQUFDO1NBQy9DLFFBQVEsQ0FBQyxNQUFNLENBQUM7U0FDaEIsT0FBTyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztBQUMvQixDQUFDLENBQUM7QUFKVyxRQUFBLGFBQWEsaUJBSXhCO0FBRUssTUFBTSxlQUFlLEdBQUcsR0FBVyxFQUFFO0lBQzFDOztPQUVHO0lBQ0gsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDbEMsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sTUFBTSxHQUFHLElBQUEsNkJBQVEsRUFBQyxvQ0FBb0MsQ0FBQztTQUMxRCxRQUFRLENBQUMsTUFBTSxDQUFDO1NBQ2hCLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDO1NBQ3pCLElBQUksRUFBRSxDQUFDO0lBRVYsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQzlELE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQztJQUV0RCxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDLENBQUM7QUFwQlcsUUFBQSxlQUFlLG1CQW9CMUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGVjU3luYyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjdXJyZW50IGZ1bGwgZ2l0IGJyYW5jaCBuYW1lXG4gKlxuICogaWU6IGZlYXR1cmUvMTIzNCByZXR1cm5zIGZlYXR1cmUvMTIzNFxuICpcbiAqL1xuZXhwb3J0IGNvbnN0IGZpbmRHaXRCcmFuY2ggPSAoKTogc3RyaW5nID0+IHtcbiAgcmV0dXJuIGV4ZWNTeW5jKFwiZ2l0IHJldi1wYXJzZSAtLWFiYnJldi1yZWYgSEVBRFwiKVxuICAgIC50b1N0cmluZyhcInV0ZjhcIilcbiAgICAucmVwbGFjZSgvW1xcblxcclxcc10rJC8sIFwiXCIpO1xufTtcblxuZXhwb3J0IGNvbnN0IGZpbmRHaXRSZXBvTmFtZSA9ICgpOiBzdHJpbmcgPT4ge1xuICAvKipcbiAgICogV2hlbiBydW5uaW5nIGluIGdpdGh1YiBhY3Rpb25zIHRoaXMgd2lsbCBiZSBwb3B1bGF0ZWQuXG4gICAqL1xuICBpZiAocHJvY2Vzcy5lbnYuR0lUSFVCX1JFUE9TSVRPUlkpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5lbnYuR0lUSFVCX1JFUE9TSVRPUlk7XG4gIH1cblxuICAvKipcbiAgICogbG9jYWxseSwgd2UgbmVlZCB0byBleHRyYWN0IHRoZSByZXBvIG5hbWUgZnJvbSB0aGUgZ2l0IGNvbmZpZy5cbiAgICovXG4gIGNvbnN0IHJlbW90ZSA9IGV4ZWNTeW5jKFwiZ2l0IGNvbmZpZyAtLWdldCByZW1vdGUub3JpZ2luLnVybFwiKVxuICAgIC50b1N0cmluZyhcInV0ZjhcIilcbiAgICAucmVwbGFjZSgvW1xcblxcclxcc10rJC8sIFwiXCIpXG4gICAgLnRyaW0oKTtcblxuICBjb25zdCBtYXRjaCA9IHJlbW90ZS5tYXRjaCgvWzpcXC9dKFteL10rXFwvW14vXSs/KSg/OlxcLmdpdCk/JC8pO1xuICBjb25zdCByZXBvTmFtZSA9IG1hdGNoID8gbWF0Y2hbMV0gOiBcImVycm9yLXJlcG8tbmFtZVwiO1xuXG4gIHJldHVybiByZXBvTmFtZTtcbn07XG4iXX0=
@@ -0,0 +1,14 @@
1
+ /**
2
+ *
3
+ * @param inString string to hash
4
+ * @param trimLength trim to this length (defaults to 999 chars)
5
+ * @returns
6
+ */
7
+ export declare const hashString: (inString: string, trimLength?: number) => string;
8
+ /**
9
+ *
10
+ * @param inputString string to truncate
11
+ * @param maxLength max length of this string
12
+ * @returns trimmed string
13
+ */
14
+ export declare const trimStringLength: (inputString: string, maxLength: number) => string;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.trimStringLength = exports.hashString = void 0;
37
+ const crypto = __importStar(require("node:crypto"));
38
+ /**
39
+ *
40
+ * @param inString string to hash
41
+ * @param trimLength trim to this length (defaults to 999 chars)
42
+ * @returns
43
+ */
44
+ const hashString = (inString, trimLength = 999) => {
45
+ return crypto
46
+ .createHash("sha256")
47
+ .update(inString)
48
+ .digest("hex")
49
+ .substring(0, trimLength);
50
+ };
51
+ exports.hashString = hashString;
52
+ /**
53
+ *
54
+ * @param inputString string to truncate
55
+ * @param maxLength max length of this string
56
+ * @returns trimmed string
57
+ */
58
+ const trimStringLength = (inputString, maxLength) => {
59
+ return inputString.length < maxLength
60
+ ? inputString
61
+ : inputString.substring(0, maxLength);
62
+ };
63
+ exports.trimStringLength = trimStringLength;
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyaW5nLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9zdHJpbmctdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsb0RBQXNDO0FBRXRDOzs7OztHQUtHO0FBQ0ksTUFBTSxVQUFVLEdBQUcsQ0FBQyxRQUFnQixFQUFFLGFBQXFCLEdBQUcsRUFBRSxFQUFFO0lBQ3ZFLE9BQU8sTUFBTTtTQUNWLFVBQVUsQ0FBQyxRQUFRLENBQUM7U0FDcEIsTUFBTSxDQUFDLFFBQVEsQ0FBQztTQUNoQixNQUFNLENBQUMsS0FBSyxDQUFDO1NBQ2IsU0FBUyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM5QixDQUFDLENBQUM7QUFOVyxRQUFBLFVBQVUsY0FNckI7QUFFRjs7Ozs7R0FLRztBQUNJLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxXQUFtQixFQUFFLFNBQWlCLEVBQUUsRUFBRTtJQUN6RSxPQUFPLFdBQVcsQ0FBQyxNQUFNLEdBQUcsU0FBUztRQUNuQyxDQUFDLENBQUMsV0FBVztRQUNiLENBQUMsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUMxQyxDQUFDLENBQUM7QUFKVyxRQUFBLGdCQUFnQixvQkFJM0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjcnlwdG8gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5cbi8qKlxuICpcbiAqIEBwYXJhbSBpblN0cmluZyBzdHJpbmcgdG8gaGFzaFxuICogQHBhcmFtIHRyaW1MZW5ndGggdHJpbSB0byB0aGlzIGxlbmd0aCAoZGVmYXVsdHMgdG8gOTk5IGNoYXJzKVxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGNvbnN0IGhhc2hTdHJpbmcgPSAoaW5TdHJpbmc6IHN0cmluZywgdHJpbUxlbmd0aDogbnVtYmVyID0gOTk5KSA9PiB7XG4gIHJldHVybiBjcnlwdG9cbiAgICAuY3JlYXRlSGFzaChcInNoYTI1NlwiKVxuICAgIC51cGRhdGUoaW5TdHJpbmcpXG4gICAgLmRpZ2VzdChcImhleFwiKVxuICAgIC5zdWJzdHJpbmcoMCwgdHJpbUxlbmd0aCk7XG59O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0gaW5wdXRTdHJpbmcgc3RyaW5nIHRvIHRydW5jYXRlXG4gKiBAcGFyYW0gbWF4TGVuZ3RoIG1heCBsZW5ndGggb2YgdGhpcyBzdHJpbmdcbiAqIEByZXR1cm5zIHRyaW1tZWQgc3RyaW5nXG4gKi9cbmV4cG9ydCBjb25zdCB0cmltU3RyaW5nTGVuZ3RoID0gKGlucHV0U3RyaW5nOiBzdHJpbmcsIG1heExlbmd0aDogbnVtYmVyKSA9PiB7XG4gIHJldHVybiBpbnB1dFN0cmluZy5sZW5ndGggPCBtYXhMZW5ndGhcbiAgICA/IGlucHV0U3RyaW5nXG4gICAgOiBpbnB1dFN0cmluZy5zdWJzdHJpbmcoMCwgbWF4TGVuZ3RoKTtcbn07XG4iXX0=
@@ -0,0 +1 @@
1
+ export * from "./private-bucket";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./private-bucket"), exports);
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvczMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUFpQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL3ByaXZhdGUtYnVja2V0XCI7XG4iXX0=
@@ -0,0 +1,7 @@
1
+ import { Bucket, BucketProps } from "aws-cdk-lib/aws-s3";
2
+ import { Construct } from "constructs";
3
+ export interface PrivateBucketProps extends BucketProps {
4
+ }
5
+ export declare class PrivateBucket extends Bucket {
6
+ constructor(scope: Construct, id: string, props?: PrivateBucketProps);
7
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrivateBucket = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_s3_1 = require("aws-cdk-lib/aws-s3");
6
+ class PrivateBucket extends aws_s3_1.Bucket {
7
+ constructor(scope, id, props = {}) {
8
+ const defaultProps = {
9
+ removalPolicy: props.removalPolicy ?? aws_cdk_lib_1.RemovalPolicy.RETAIN,
10
+ autoDeleteObjects: props.removalPolicy === aws_cdk_lib_1.RemovalPolicy.DESTROY,
11
+ };
12
+ const requiredProps = {
13
+ publicReadAccess: false,
14
+ blockPublicAccess: aws_s3_1.BlockPublicAccess.BLOCK_ALL,
15
+ enforceSSL: true,
16
+ objectOwnership: aws_s3_1.ObjectOwnership.BUCKET_OWNER_ENFORCED,
17
+ };
18
+ super(scope, id, { ...defaultProps, ...props, ...requiredProps });
19
+ }
20
+ }
21
+ exports.PrivateBucket = PrivateBucket;
22
+ // foo
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZS1idWNrZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvczMvcHJpdmF0ZS1idWNrZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQTRDO0FBQzVDLCtDQUs0QjtBQUs1QixNQUFhLGFBQWMsU0FBUSxlQUFNO0lBQ3ZDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsUUFBNEIsRUFBRTtRQUN0RSxNQUFNLFlBQVksR0FBRztZQUNuQixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWEsSUFBSSwyQkFBYSxDQUFDLE1BQU07WUFDMUQsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGFBQWEsS0FBSywyQkFBYSxDQUFDLE9BQU87U0FDakUsQ0FBQztRQUVGLE1BQU0sYUFBYSxHQUFHO1lBQ3BCLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsaUJBQWlCLEVBQUUsMEJBQWlCLENBQUMsU0FBUztZQUM5QyxVQUFVLEVBQUUsSUFBSTtZQUNoQixlQUFlLEVBQUUsd0JBQWUsQ0FBQyxxQkFBcUI7U0FDdkQsQ0FBQztRQUVGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxZQUFZLEVBQUUsR0FBRyxLQUFLLEVBQUUsR0FBRyxhQUFhLEVBQUUsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7Q0FDRjtBQWhCRCxzQ0FnQkM7QUFDRCxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUmVtb3ZhbFBvbGljeSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHtcbiAgQmxvY2tQdWJsaWNBY2Nlc3MsXG4gIEJ1Y2tldCxcbiAgQnVja2V0UHJvcHMsXG4gIE9iamVjdE93bmVyc2hpcCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBQcml2YXRlQnVja2V0UHJvcHMgZXh0ZW5kcyBCdWNrZXRQcm9wcyB7fVxuXG5leHBvcnQgY2xhc3MgUHJpdmF0ZUJ1Y2tldCBleHRlbmRzIEJ1Y2tldCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBQcml2YXRlQnVja2V0UHJvcHMgPSB7fSkge1xuICAgIGNvbnN0IGRlZmF1bHRQcm9wcyA9IHtcbiAgICAgIHJlbW92YWxQb2xpY3k6IHByb3BzLnJlbW92YWxQb2xpY3kgPz8gUmVtb3ZhbFBvbGljeS5SRVRBSU4sXG4gICAgICBhdXRvRGVsZXRlT2JqZWN0czogcHJvcHMucmVtb3ZhbFBvbGljeSA9PT0gUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgIH07XG5cbiAgICBjb25zdCByZXF1aXJlZFByb3BzID0ge1xuICAgICAgcHVibGljUmVhZEFjY2VzczogZmFsc2UsXG4gICAgICBibG9ja1B1YmxpY0FjY2VzczogQmxvY2tQdWJsaWNBY2Nlc3MuQkxPQ0tfQUxMLFxuICAgICAgZW5mb3JjZVNTTDogdHJ1ZSxcbiAgICAgIG9iamVjdE93bmVyc2hpcDogT2JqZWN0T3duZXJzaGlwLkJVQ0tFVF9PV05FUl9FTkZPUkNFRCxcbiAgICB9O1xuXG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7IC4uLmRlZmF1bHRQcm9wcywgLi4ucHJvcHMsIC4uLnJlcXVpcmVkUHJvcHMgfSk7XG4gIH1cbn1cbi8vIGZvb1xuIl19
@@ -0,0 +1,2 @@
1
+ export * from "./static-content";
2
+ export * from "./static-hosting";
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./static-content"), exports);
18
+ __exportStar(require("./static-hosting"), exports);
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGljLWhvc3RpbmcvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUFpQztBQUNqQyxtREFBaUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tIFwiLi9zdGF0aWMtY29udGVudFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vc3RhdGljLWhvc3RpbmdcIjtcbiJdfQ==
@@ -0,0 +1,49 @@
1
+ import { Construct } from "constructs";
2
+ /*******************************************************************************
3
+ *
4
+ * STATIC CONTENT UPLOADER
5
+ *
6
+ * This construct uploads a directory of content from a local location into S3.
7
+ *
8
+ * To support PR and branch specific builds, each S3 bucket can store content
9
+ * for multiple domains and builds, using the following format:
10
+ *
11
+ * S3-bucket/domain/*
12
+ *
13
+ * A bucket used to store content for stage.openhi.org might have the
14
+ * following directory structure (all in the same bucket).
15
+ *
16
+ * /stage.openhi.org/* -> serves content to stage.openhi.org
17
+ * /feature-7.stage.openhi.org/* -> serves content to feature-7.stage.openhi.org
18
+ * /pr-123.stage.openhi.org/* -> serves content to pr-123.stage.openhi.org
19
+ *
20
+ ******************************************************************************/
21
+ export interface StaticContentProps {
22
+ /**
23
+ * Parameter name to use when storing the static hosting bucket's ARN.
24
+ * This is needed in other later steps when deploying hosted content to S3.
25
+ */
26
+ readonly bucketArnParamName?: string;
27
+ /**
28
+ * Absolute path to directory containing content for the website.
29
+ */
30
+ readonly contentSourceDirectory: string;
31
+ /**
32
+ * Directory to place content into. Should start with a slash.
33
+ * Example: '/widget'
34
+ */
35
+ readonly contentDestinationDirectory: string;
36
+ /**
37
+ * The sub domain prefix (ie: images)
38
+ *
39
+ * @default git branch name
40
+ */
41
+ readonly subDomain?: string;
42
+ /**
43
+ * The full domain (ie: staging.codedrifters.com)
44
+ */
45
+ readonly fullDomain: string;
46
+ }
47
+ export declare class StaticContent extends Construct {
48
+ constructor(scope: Construct, id: string, props: StaticContentProps);
49
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StaticContent = void 0;
4
+ const aws_s3_1 = require("aws-cdk-lib/aws-s3");
5
+ const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
6
+ const aws_ssm_1 = require("aws-cdk-lib/aws-ssm");
7
+ const change_case_1 = require("change-case");
8
+ const constructs_1 = require("constructs");
9
+ const git_utils_1 = require("../lib/git-utils");
10
+ class StaticContent extends constructs_1.Construct {
11
+ constructor(scope, id, props) {
12
+ super(scope, id);
13
+ /***************************************************************************
14
+ *
15
+ * Initial Setup
16
+ *
17
+ * Set some defaults, build domain information.
18
+ *
19
+ **************************************************************************/
20
+ const { bucketArnParamName, contentSourceDirectory, contentDestinationDirectory, subDomain, fullDomain, } = {
21
+ bucketArnParamName: "/STATIC_WEBSITE/BUCKET_ARN",
22
+ subDomain: (0, git_utils_1.findGitBranch)(),
23
+ ...props,
24
+ };
25
+ /***************************************************************************
26
+ *
27
+ * Import and build some values from Param Store during deployment.
28
+ *
29
+ **************************************************************************/
30
+ const keyPrefix = [(0, change_case_1.paramCase)(subDomain), fullDomain].join(".");
31
+ const bucketArn = aws_ssm_1.StringParameter.valueForStringParameter(this, bucketArnParamName);
32
+ const bucket = aws_s3_1.Bucket.fromBucketArn(this, "bucket", bucketArn);
33
+ /***************************************************************************
34
+ *
35
+ * Gather the sources we'll be deploying. We need to have an empty source
36
+ * for tests since it will change all the time and bork up the test
37
+ * snapshots if we don't.
38
+ *
39
+ **************************************************************************/
40
+ const sources = process.env.JEST_WORKER_ID
41
+ ? []
42
+ : [aws_s3_deployment_1.Source.asset(contentSourceDirectory)];
43
+ new aws_s3_deployment_1.BucketDeployment(this, "deploy", {
44
+ sources,
45
+ destinationBucket: bucket,
46
+ retainOnDelete: false,
47
+ destinationKeyPrefix: `${keyPrefix}${contentDestinationDirectory}`,
48
+ });
49
+ }
50
+ }
51
+ exports.StaticContent = StaticContent;
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLWNvbnRlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGljLWhvc3Rpbmcvc3RhdGljLWNvbnRlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0NBQTRDO0FBQzVDLHFFQUF5RTtBQUN6RSxpREFBc0Q7QUFDdEQsNkNBQXdDO0FBQ3hDLDJDQUF1QztBQUN2QyxnREFBaUQ7QUFxRGpELE1BQWEsYUFBYyxTQUFRLHNCQUFTO0lBQzFDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBeUI7UUFDakUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQjs7Ozs7O29GQU00RTtRQUU1RSxNQUFNLEVBQ0osa0JBQWtCLEVBQ2xCLHNCQUFzQixFQUN0QiwyQkFBMkIsRUFDM0IsU0FBUyxFQUNULFVBQVUsR0FDWCxHQUFHO1lBQ0Ysa0JBQWtCLEVBQUUsNEJBQTRCO1lBQ2hELFNBQVMsRUFBRSxJQUFBLHlCQUFhLEdBQUU7WUFDMUIsR0FBRyxLQUFLO1NBQ1QsQ0FBQztRQUVGOzs7O29GQUk0RTtRQUU1RSxNQUFNLFNBQVMsR0FBRyxDQUFDLElBQUEsdUJBQVMsRUFBQyxTQUFTLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFL0QsTUFBTSxTQUFTLEdBQUcseUJBQWUsQ0FBQyx1QkFBdUIsQ0FDdkQsSUFBSSxFQUNKLGtCQUFrQixDQUNuQixDQUFDO1FBQ0YsTUFBTSxNQUFNLEdBQUcsZUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRS9EOzs7Ozs7b0ZBTTRFO1FBRTVFLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYztZQUN4QyxDQUFDLENBQUMsRUFBRTtZQUNKLENBQUMsQ0FBQyxDQUFDLDBCQUFNLENBQUMsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQztRQUUzQyxJQUFJLG9DQUFnQixDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7WUFDbkMsT0FBTztZQUNQLGlCQUFpQixFQUFFLE1BQU07WUFDekIsY0FBYyxFQUFFLEtBQUs7WUFDckIsb0JBQW9CLEVBQUUsR0FBRyxTQUFTLEdBQUcsMkJBQTJCLEVBQUU7U0FDbkUsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBekRELHNDQXlEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IEJ1Y2tldERlcGxveW1lbnQsIFNvdXJjZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0IHsgU3RyaW5nUGFyYW1ldGVyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zc21cIjtcbmltcG9ydCB7IHBhcmFtQ2FzZSB9IGZyb20gXCJjaGFuZ2UtY2FzZVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IGZpbmRHaXRCcmFuY2ggfSBmcm9tIFwiLi4vbGliL2dpdC11dGlsc1wiO1xuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICpcbiAqICBTVEFUSUMgQ09OVEVOVCBVUExPQURFUlxuICpcbiAqICBUaGlzIGNvbnN0cnVjdCB1cGxvYWRzIGEgZGlyZWN0b3J5IG9mIGNvbnRlbnQgZnJvbSBhIGxvY2FsIGxvY2F0aW9uIGludG8gUzMuXG4gKlxuICogIFRvIHN1cHBvcnQgUFIgYW5kIGJyYW5jaCBzcGVjaWZpYyBidWlsZHMsIGVhY2ggUzMgYnVja2V0IGNhbiBzdG9yZSBjb250ZW50XG4gKiAgZm9yIG11bHRpcGxlIGRvbWFpbnMgYW5kIGJ1aWxkcywgdXNpbmcgdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gKlxuICogIFMzLWJ1Y2tldC9kb21haW4vKlxuICpcbiAqICBBIGJ1Y2tldCB1c2VkIHRvIHN0b3JlIGNvbnRlbnQgZm9yIHN0YWdlLm9wZW5oaS5vcmcgbWlnaHQgaGF2ZSB0aGVcbiAqICBmb2xsb3dpbmcgZGlyZWN0b3J5IHN0cnVjdHVyZSAoYWxsIGluIHRoZSBzYW1lIGJ1Y2tldCkuXG4gKlxuICogIC9zdGFnZS5vcGVuaGkub3JnLyogLT4gc2VydmVzIGNvbnRlbnQgdG8gc3RhZ2Uub3BlbmhpLm9yZ1xuICogIC9mZWF0dXJlLTcuc3RhZ2Uub3BlbmhpLm9yZy8qIC0+IHNlcnZlcyBjb250ZW50IHRvIGZlYXR1cmUtNy5zdGFnZS5vcGVuaGkub3JnXG4gKiAgL3ByLTEyMy5zdGFnZS5vcGVuaGkub3JnLyogLT4gc2VydmVzIGNvbnRlbnQgdG8gcHItMTIzLnN0YWdlLm9wZW5oaS5vcmdcbiAqXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRpY0NvbnRlbnRQcm9wcyB7XG4gIC8qKlxuICAgKiBQYXJhbWV0ZXIgbmFtZSB0byB1c2Ugd2hlbiBzdG9yaW5nIHRoZSBzdGF0aWMgaG9zdGluZyBidWNrZXQncyBBUk4uXG4gICAqIFRoaXMgaXMgbmVlZGVkIGluIG90aGVyIGxhdGVyIHN0ZXBzIHdoZW4gZGVwbG95aW5nIGhvc3RlZCBjb250ZW50IHRvIFMzLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0QXJuUGFyYW1OYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiAgQWJzb2x1dGUgcGF0aCB0byBkaXJlY3RvcnkgY29udGFpbmluZyBjb250ZW50IGZvciB0aGUgd2Vic2l0ZS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbnRlbnRTb3VyY2VEaXJlY3Rvcnk6IHN0cmluZztcblxuICAvKipcbiAgICogIERpcmVjdG9yeSB0byBwbGFjZSBjb250ZW50IGludG8uIFNob3VsZCBzdGFydCB3aXRoIGEgc2xhc2guXG4gICAqICBFeGFtcGxlOiAnL3dpZGdldCdcbiAgICovXG4gIHJlYWRvbmx5IGNvbnRlbnREZXN0aW5hdGlvbkRpcmVjdG9yeTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiAgVGhlIHN1YiBkb21haW4gcHJlZml4IChpZTogaW1hZ2VzKVxuICAgKlxuICAgKiBAZGVmYXVsdCBnaXQgYnJhbmNoIG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IHN1YkRvbWFpbj86IHN0cmluZztcblxuICAvKipcbiAgICogIFRoZSBmdWxsIGRvbWFpbiAoaWU6IHN0YWdpbmcuY29kZWRyaWZ0ZXJzLmNvbSlcbiAgICovXG4gIHJlYWRvbmx5IGZ1bGxEb21haW46IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFN0YXRpY0NvbnRlbnQgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU3RhdGljQ29udGVudFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgKlxuICAgICAqIEluaXRpYWwgU2V0dXBcbiAgICAgKlxuICAgICAqIFNldCBzb21lIGRlZmF1bHRzLCBidWlsZCBkb21haW4gaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbiAgICBjb25zdCB7XG4gICAgICBidWNrZXRBcm5QYXJhbU5hbWUsXG4gICAgICBjb250ZW50U291cmNlRGlyZWN0b3J5LFxuICAgICAgY29udGVudERlc3RpbmF0aW9uRGlyZWN0b3J5LFxuICAgICAgc3ViRG9tYWluLFxuICAgICAgZnVsbERvbWFpbixcbiAgICB9ID0ge1xuICAgICAgYnVja2V0QXJuUGFyYW1OYW1lOiBcIi9TVEFUSUNfV0VCU0lURS9CVUNLRVRfQVJOXCIsXG4gICAgICBzdWJEb21haW46IGZpbmRHaXRCcmFuY2goKSxcbiAgICAgIC4uLnByb3BzLFxuICAgIH07XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICpcbiAgICAgKiBJbXBvcnQgYW5kIGJ1aWxkIHNvbWUgdmFsdWVzIGZyb20gUGFyYW0gU3RvcmUgZHVyaW5nIGRlcGxveW1lbnQuXG4gICAgICpcbiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbiAgICBjb25zdCBrZXlQcmVmaXggPSBbcGFyYW1DYXNlKHN1YkRvbWFpbiksIGZ1bGxEb21haW5dLmpvaW4oXCIuXCIpO1xuXG4gICAgY29uc3QgYnVja2V0QXJuID0gU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKFxuICAgICAgdGhpcyxcbiAgICAgIGJ1Y2tldEFyblBhcmFtTmFtZSxcbiAgICApO1xuICAgIGNvbnN0IGJ1Y2tldCA9IEJ1Y2tldC5mcm9tQnVja2V0QXJuKHRoaXMsIFwiYnVja2V0XCIsIGJ1Y2tldEFybik7XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICpcbiAgICAgKiBHYXRoZXIgdGhlIHNvdXJjZXMgd2UnbGwgYmUgZGVwbG95aW5nLiBXZSBuZWVkIHRvIGhhdmUgYW4gZW1wdHkgc291cmNlXG4gICAgICogZm9yIHRlc3RzIHNpbmNlIGl0IHdpbGwgY2hhbmdlIGFsbCB0aGUgdGltZSBhbmQgYm9yayB1cCB0aGUgdGVzdFxuICAgICAqIHNuYXBzaG90cyBpZiB3ZSBkb24ndC5cbiAgICAgKlxuICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIGNvbnN0IHNvdXJjZXMgPSBwcm9jZXNzLmVudi5KRVNUX1dPUktFUl9JRFxuICAgICAgPyBbXVxuICAgICAgOiBbU291cmNlLmFzc2V0KGNvbnRlbnRTb3VyY2VEaXJlY3RvcnkpXTtcblxuICAgIG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsIFwiZGVwbG95XCIsIHtcbiAgICAgIHNvdXJjZXMsXG4gICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogYnVja2V0LFxuICAgICAgcmV0YWluT25EZWxldGU6IGZhbHNlLFxuICAgICAgZGVzdGluYXRpb25LZXlQcmVmaXg6IGAke2tleVByZWZpeH0ke2NvbnRlbnREZXN0aW5hdGlvbkRpcmVjdG9yeX1gLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,49 @@
1
+ import { StackProps } from "aws-cdk-lib";
2
+ import { HostedZoneAttributes } from "aws-cdk-lib/aws-route53";
3
+ import { Construct } from "constructs";
4
+ import { PrivateBucketProps } from "../s3/private-bucket";
5
+ export interface StaticDomainProps {
6
+ /**
7
+ * The sub domain prefix (ie: images)
8
+ */
9
+ readonly subDomain: string;
10
+ /**
11
+ * The base domain (ie: codedrifters.com)
12
+ */
13
+ readonly baseDomain: string;
14
+ /**
15
+ * Hosted zone ID for the base domain.
16
+ */
17
+ readonly hostedZoneAttributes: HostedZoneAttributes;
18
+ }
19
+ export interface StaticHostingProps extends StackProps {
20
+ /**
21
+ * Values used to connect a domain name to the cloudfront distribution. If not
22
+ * supplied, cloudfront doesn't use a custom domain.
23
+ */
24
+ readonly staticDomainProps?: StaticDomainProps;
25
+ /**
26
+ * Parameter name to use when storing the static hosting bucket's ARN.
27
+ * This is needed in other later steps when deploying hosted content to S3.
28
+ */
29
+ readonly bucketArnParamName?: string;
30
+ /**
31
+ * Parameter name to use when storing the CloudFront Distribution Domain Name.
32
+ */
33
+ readonly distributionDomainParamName?: string;
34
+ /**
35
+ * Parameter name to use when storing the CloudFront Distribution ID.
36
+ */
37
+ readonly distributionIDParamName?: string;
38
+ /**
39
+ * Props to pass to the private S3 bucket.
40
+ */
41
+ readonly privateBucketProps?: PrivateBucketProps;
42
+ }
43
+ export declare class StaticHosting extends Construct {
44
+ /**
45
+ * Full domain name used as basis for hosting.
46
+ */
47
+ readonly fullDomain: string;
48
+ constructor(scope: Construct, id: string, props?: StaticHostingProps);
49
+ }
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StaticHosting = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_certificatemanager_1 = require("aws-cdk-lib/aws-certificatemanager");
6
+ const aws_cloudfront_1 = require("aws-cdk-lib/aws-cloudfront");
7
+ const aws_cloudfront_origins_1 = require("aws-cdk-lib/aws-cloudfront-origins");
8
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
9
+ const aws_lambda_nodejs_1 = require("aws-cdk-lib/aws-lambda-nodejs");
10
+ const aws_logs_1 = require("aws-cdk-lib/aws-logs");
11
+ const aws_route53_1 = require("aws-cdk-lib/aws-route53");
12
+ const aws_route53_targets_1 = require("aws-cdk-lib/aws-route53-targets");
13
+ const aws_ssm_1 = require("aws-cdk-lib/aws-ssm");
14
+ const constructs_1 = require("constructs");
15
+ const private_bucket_1 = require("../s3/private-bucket");
16
+ class StaticHosting extends constructs_1.Construct {
17
+ constructor(scope, id, props = {}) {
18
+ super(scope, id);
19
+ /***************************************************************************
20
+ *
21
+ * Initial Setup
22
+ *
23
+ * Set some defaults, build domain information.
24
+ *
25
+ **************************************************************************/
26
+ const { bucketArnParamName, distributionDomainParamName, distributionIDParamName, staticDomainProps, privateBucketProps, } = {
27
+ bucketArnParamName: "/STATIC_WEBSITE/BUCKET_ARN",
28
+ distributionDomainParamName: "/STATIC_WEBSITE/DISTRIBUTION_DOMAIN",
29
+ distributionIDParamName: "/STATIC_WEBSITE/DISTRIBUTION_ID",
30
+ ...props,
31
+ };
32
+ const { subDomain, baseDomain, hostedZoneAttributes } = staticDomainProps ?? {};
33
+ this.fullDomain = [subDomain, baseDomain].join(".");
34
+ /***************************************************************************
35
+ *
36
+ * PRIVATE BUCKET
37
+ *
38
+ * A bucket to store the files within.
39
+ * Save ARN for later deploys.
40
+ *
41
+ **************************************************************************/
42
+ const bucket = new private_bucket_1.PrivateBucket(this, "static-hosting-bucket", privateBucketProps);
43
+ /***************************************************************************
44
+ *
45
+ * DNS & Wildcard Certificate
46
+ *
47
+ * If a zone Id as passed in, find the hosted zone and create a wildcard
48
+ * certificate for the domain.
49
+ *
50
+ **************************************************************************/
51
+ let zone;
52
+ let certificate;
53
+ if (hostedZoneAttributes) {
54
+ zone = aws_route53_1.HostedZone.fromHostedZoneAttributes(this, "zone", hostedZoneAttributes);
55
+ certificate = new aws_certificatemanager_1.Certificate(this, "wildcard-certificate", {
56
+ domainName: `*.${this.fullDomain}`,
57
+ subjectAlternativeNames: [this.fullDomain],
58
+ validation: aws_certificatemanager_1.CertificateValidation.fromDnsMultiZone({
59
+ [`*.${this.fullDomain}`]: zone,
60
+ [this.fullDomain]: zone,
61
+ }),
62
+ });
63
+ }
64
+ /******************************************************************************
65
+ *
66
+ * LAMBDA@EDGE FUNCTION
67
+ *
68
+ * This handles rewriting the path from domain name.
69
+ *
70
+ *****************************************************************************/
71
+ const handler = new aws_lambda_nodejs_1.NodejsFunction(this, "viewer-request-handler", {
72
+ memorySize: 128,
73
+ runtime: aws_lambda_1.Runtime.NODEJS_24_X,
74
+ logGroup: new aws_logs_1.LogGroup(this, "viewer-request-handler-log-group", {
75
+ retention: aws_logs_1.RetentionDays.ONE_MONTH,
76
+ }),
77
+ });
78
+ /******************************************************************************
79
+ *
80
+ * CLOUDFRONT CONFIG
81
+ *
82
+ * Setup a CloudFront Distribution for the bucket.
83
+ *
84
+ *****************************************************************************/
85
+ const cachePolicy = new aws_cloudfront_1.CachePolicy(this, "cloudfront-policy", {
86
+ comment: "Relatively conservative TTL policy.",
87
+ maxTtl: aws_cdk_lib_1.Duration.seconds(300),
88
+ minTtl: aws_cdk_lib_1.Duration.seconds(0),
89
+ defaultTtl: aws_cdk_lib_1.Duration.seconds(60),
90
+ headerBehavior: aws_cloudfront_1.CacheHeaderBehavior.none(),
91
+ queryStringBehavior: aws_cloudfront_1.CacheQueryStringBehavior.none(),
92
+ cookieBehavior: aws_cloudfront_1.CacheCookieBehavior.none(),
93
+ enableAcceptEncodingGzip: true,
94
+ enableAcceptEncodingBrotli: true,
95
+ });
96
+ const oac = new aws_cloudfront_1.S3OriginAccessControl(this, "MyOAC", {
97
+ signing: aws_cloudfront_1.Signing.SIGV4_NO_OVERRIDE,
98
+ });
99
+ const origin = aws_cloudfront_origins_1.S3BucketOrigin.withOriginAccessControl(bucket, {
100
+ originAccessControl: oac,
101
+ originAccessLevels: [aws_cloudfront_1.AccessLevel.READ],
102
+ });
103
+ const distribution = new aws_cloudfront_1.Distribution(this, "cloudfront-distribution", {
104
+ comment: `Distribution for ${this.fullDomain}`,
105
+ /**
106
+ * Only if domain was supplied
107
+ */
108
+ ...(certificate
109
+ ? {
110
+ certificate,
111
+ domainNames: [this.fullDomain, `*.${this.fullDomain}`],
112
+ }
113
+ : {}),
114
+ defaultBehavior: {
115
+ origin,
116
+ viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
117
+ cachePolicy,
118
+ allowedMethods: aws_cloudfront_1.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
119
+ edgeLambdas: [
120
+ {
121
+ functionVersion: handler.currentVersion,
122
+ eventType: aws_cloudfront_1.LambdaEdgeEventType.VIEWER_REQUEST,
123
+ },
124
+ ],
125
+ },
126
+ defaultRootObject: "index.html",
127
+ });
128
+ /***************************************************************************
129
+ *
130
+ * DNS ENTRY
131
+ *
132
+ * Link cloudfront to both the root fulldomain and all possible subdomains.
133
+ *
134
+ **************************************************************************/
135
+ if (zone) {
136
+ new aws_route53_1.ARecord(this, "root-dns-entry", {
137
+ zone,
138
+ recordName: subDomain,
139
+ target: aws_route53_1.RecordTarget.fromAlias(new aws_route53_targets_1.CloudFrontTarget(distribution)),
140
+ });
141
+ new aws_route53_1.ARecord(this, "wc-dns-entry", {
142
+ zone,
143
+ recordName: `*.${subDomain}`,
144
+ target: aws_route53_1.RecordTarget.fromAlias(new aws_route53_targets_1.CloudFrontTarget(distribution)),
145
+ });
146
+ }
147
+ /***************************************************************************
148
+ *
149
+ * EXPORTS
150
+ *
151
+ * Used by content uploader later.
152
+ *
153
+ **************************************************************************/
154
+ new aws_ssm_1.StringParameter(this, "dist-domain", {
155
+ description: `GENERATED DO NOT CHANGE - CloudFront Distribution Details (${this.fullDomain}).`,
156
+ parameterName: distributionDomainParamName,
157
+ stringValue: distribution.domainName,
158
+ });
159
+ new aws_ssm_1.StringParameter(this, "dist-id", {
160
+ description: `GENERATED DO NOT CHANGE - CloudFront Distribution Details (${this.fullDomain}).`,
161
+ parameterName: distributionIDParamName,
162
+ stringValue: distribution.distributionId,
163
+ });
164
+ new aws_ssm_1.StringParameter(this, "bucket-arn", {
165
+ description: `GENERATED DO NOT CHANGE - S3 Bucket ARN for Static Website Hosting (${this.fullDomain}).`,
166
+ parameterName: bucketArnParamName,
167
+ stringValue: bucket.bucketArn,
168
+ });
169
+ }
170
+ }
171
+ exports.StaticHosting = StaticHosting;
172
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLWhvc3RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGljLWhvc3Rpbmcvc3RhdGljLWhvc3RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQW1EO0FBQ25ELCtFQUc0QztBQUM1QywrREFZb0M7QUFDcEMsK0VBQW9FO0FBQ3BFLHVEQUFpRDtBQUNqRCxxRUFBK0Q7QUFDL0QsbURBQStEO0FBQy9ELHlEQU1pQztBQUNqQyx5RUFBbUU7QUFDbkUsaURBQXNEO0FBQ3RELDJDQUF1QztBQUN2Qyx5REFBeUU7QUFnRHpFLE1BQWEsYUFBYyxTQUFRLHNCQUFTO0lBTTFDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsUUFBNEIsRUFBRTtRQUN0RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCOzs7Ozs7b0ZBTTRFO1FBRTVFLE1BQU0sRUFDSixrQkFBa0IsRUFDbEIsMkJBQTJCLEVBQzNCLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsa0JBQWtCLEdBQ25CLEdBQUc7WUFDRixrQkFBa0IsRUFBRSw0QkFBNEI7WUFDaEQsMkJBQTJCLEVBQUUscUNBQXFDO1lBQ2xFLHVCQUF1QixFQUFFLGlDQUFpQztZQUMxRCxHQUFHLEtBQUs7U0FDVCxDQUFDO1FBRUYsTUFBTSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsb0JBQW9CLEVBQUUsR0FDbkQsaUJBQWlCLElBQUksRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXBEOzs7Ozs7O29GQU80RTtRQUU1RSxNQUFNLE1BQU0sR0FBRyxJQUFJLDhCQUFhLENBQzlCLElBQUksRUFDSix1QkFBdUIsRUFDdkIsa0JBQWtCLENBQ25CLENBQUM7UUFFRjs7Ozs7OztvRkFPNEU7UUFFNUUsSUFBSSxJQUE2QixD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LENBQUMsU0FBUztTQUM5QixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFyTUQsc0NBcU1DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHVyYXRpb24sIFN0YWNrUHJvcHMgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7XG4gIENlcnRpZmljYXRlLFxuICBDZXJ0aWZpY2F0ZVZhbGlkYXRpb24sXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBBY2Nlc3NMZXZlbCxcbiAgQWxsb3dlZE1ldGhvZHMsXG4gIENhY2hlQ29va2llQmVoYXZpb3IsXG4gIENhY2hlSGVhZGVyQmVoYXZpb3IsXG4gIENhY2hlUG9saWN5LFxuICBDYWNoZVF1ZXJ5U3RyaW5nQmVoYXZpb3IsXG4gIERpc3RyaWJ1dGlvbixcbiAgTGFtYmRhRWRnZUV2ZW50VHlwZSxcbiAgUzNPcmlnaW5BY2Nlc3NDb250cm9sLFxuICBTaWduaW5nLFxuICBWaWV3ZXJQcm90b2NvbFBvbGljeSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250XCI7XG5pbXBvcnQgeyBTM0J1Y2tldE9yaWdpbiB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udC1vcmlnaW5zXCI7XG5pbXBvcnQgeyBSdW50aW1lIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIjtcbmltcG9ydCB7IE5vZGVqc0Z1bmN0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGEtbm9kZWpzXCI7XG5pbXBvcnQgeyBMb2dHcm91cCwgUmV0ZW50aW9uRGF5cyB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbG9nc1wiO1xuaW1wb3J0IHtcbiAgQVJlY29yZCxcbiAgSG9zdGVkWm9uZSxcbiAgSG9zdGVkWm9uZUF0dHJpYnV0ZXMsXG4gIElIb3N0ZWRab25lLFxuICBSZWNvcmRUYXJnZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1M1wiO1xuaW1wb3J0IHsgQ2xvdWRGcm9udFRhcmdldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzXCI7XG5pbXBvcnQgeyBTdHJpbmdQYXJhbWV0ZXIgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNzbVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IFByaXZhdGVCdWNrZXQsIFByaXZhdGVCdWNrZXRQcm9wcyB9IGZyb20gXCIuLi9zMy9wcml2YXRlLWJ1Y2tldFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRpY0RvbWFpblByb3BzIHtcbiAgLyoqXG4gICAqICBUaGUgc3ViIGRvbWFpbiBwcmVmaXggKGllOiBpbWFnZXMpXG4gICAqL1xuICByZWFkb25seSBzdWJEb21haW46IHN0cmluZztcblxuICAvKipcbiAgICogIFRoZSBiYXNlIGRvbWFpbiAoaWU6IGNvZGVkcmlmdGVycy5jb20pXG4gICAqL1xuICByZWFkb25seSBiYXNlRG9tYWluOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvc3RlZCB6b25lIElEIGZvciB0aGUgYmFzZSBkb21haW4uXG4gICAqL1xuICByZWFkb25seSBob3N0ZWRab25lQXR0cmlidXRlczogSG9zdGVkWm9uZUF0dHJpYnV0ZXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGljSG9zdGluZ1Byb3BzIGV4dGVuZHMgU3RhY2tQcm9wcyB7XG4gIC8qKlxuICAgKiBWYWx1ZXMgdXNlZCB0byBjb25uZWN0IGEgZG9tYWluIG5hbWUgdG8gdGhlIGNsb3VkZnJvbnQgZGlzdHJpYnV0aW9uLiBJZiBub3RcbiAgICogc3VwcGxpZWQsIGNsb3VkZnJvbnQgZG9lc24ndCB1c2UgYSBjdXN0b20gZG9tYWluLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdGljRG9tYWluUHJvcHM/OiBTdGF0aWNEb21haW5Qcm9wcztcblxuICAvKipcbiAgICogUGFyYW1ldGVyIG5hbWUgdG8gdXNlIHdoZW4gc3RvcmluZyB0aGUgc3RhdGljIGhvc3RpbmcgYnVja2V0J3MgQVJOLlxuICAgKiBUaGlzIGlzIG5lZWRlZCBpbiBvdGhlciBsYXRlciBzdGVwcyB3aGVuIGRlcGxveWluZyBob3N0ZWQgY29udGVudCB0byBTMy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldEFyblBhcmFtTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogUGFyYW1ldGVyIG5hbWUgdG8gdXNlIHdoZW4gc3RvcmluZyB0aGUgQ2xvdWRGcm9udCBEaXN0cmlidXRpb24gRG9tYWluIE5hbWUuXG4gICAqL1xuICByZWFkb25seSBkaXN0cmlidXRpb25Eb21haW5QYXJhbU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFBhcmFtZXRlciBuYW1lIHRvIHVzZSB3aGVuIHN0b3JpbmcgdGhlIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uIElELlxuICAgKi9cbiAgcmVhZG9ubHkgZGlzdHJpYnV0aW9uSURQYXJhbU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFByb3BzIHRvIHBhc3MgdG8gdGhlIHByaXZhdGUgUzMgYnVja2V0LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJpdmF0ZUJ1Y2tldFByb3BzPzogUHJpdmF0ZUJ1Y2tldFByb3BzO1xufVxuXG5leHBvcnQgY2xhc3MgU3RhdGljSG9zdGluZyBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBGdWxsIGRvbWFpbiBuYW1lIHVzZWQgYXMgYmFzaXMgZm9yIGhvc3RpbmcuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZnVsbERvbWFpbjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTdGF0aWNIb3N0aW5nUHJvcHMgPSB7fSkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICpcbiAgICAgKiBJbml0aWFsIFNldHVwXG4gICAgICpcbiAgICAgKiBTZXQgc29tZSBkZWZhdWx0cywgYnVpbGQgZG9tYWluIGluZm9ybWF0aW9uLlxuICAgICAqXG4gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgY29uc3Qge1xuICAgICAgYnVja2V0QXJuUGFyYW1OYW1lLFxuICAgICAgZGlzdHJpYnV0aW9uRG9tYWluUGFyYW1OYW1lLFxuICAgICAgZGlzdHJpYnV0aW9uSURQYXJhbU5hbWUsXG4gICAgICBzdGF0aWNEb21haW5Qcm9wcyxcbiAgICAgIHByaXZhdGVCdWNrZXRQcm9wcyxcbiAgICB9ID0ge1xuICAgICAgYnVja2V0QXJuUGFyYW1OYW1lOiBcIi9TVEFUSUNfV0VCU0lURS9CVUNLRVRfQVJOXCIsXG4gICAgICBkaXN0cmlidXRpb25Eb21haW5QYXJhbU5hbWU6IFwiL1NUQVRJQ19XRUJTSVRFL0RJU1RSSUJVVElPTl9ET01BSU5cIixcbiAgICAgIGRpc3RyaWJ1dGlvbklEUGFyYW1OYW1lOiBcIi9TVEFUSUNfV0VCU0lURS9ESVNUUklCVVRJT05fSURcIixcbiAgICAgIC4uLnByb3BzLFxuICAgIH07XG5cbiAgICBjb25zdCB7IHN1YkRvbWFpbiwgYmFzZURvbWFpbiwgaG9zdGVkWm9uZUF0dHJpYnV0ZXMgfSA9XG4gICAgICBzdGF0aWNEb21haW5Qcm9wcyA/PyB7fTtcbiAgICB0aGlzLmZ1bGxEb21haW4gPSBbc3ViRG9tYWluLCBiYXNlRG9tYWluXS5qb2luKFwiLlwiKTtcblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgKlxuICAgICAqIFBSSVZBVEUgQlVDS0VUXG4gICAgICpcbiAgICAgKiBBIGJ1Y2tldCB0byBzdG9yZSB0aGUgZmlsZXMgd2l0aGluLlxuICAgICAqIFNhdmUgQVJOIGZvciBsYXRlciBkZXBsb3lzLlxuICAgICAqXG4gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgY29uc3QgYnVja2V0ID0gbmV3IFByaXZhdGVCdWNrZXQoXG4gICAgICB0aGlzLFxuICAgICAgXCJzdGF0aWMtaG9zdGluZy1idWNrZXRcIixcbiAgICAgIHByaXZhdGVCdWNrZXRQcm9wcyxcbiAgICApO1xuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAqXG4gICAgICogRE5TICYgV2lsZGNhcmQgQ2VydGlmaWNhdGVcbiAgICAgKlxuICAgICAqIElmIGEgem9uZSBJZCBhcyBwYXNzZWQgaW4sIGZpbmQgdGhlIGhvc3RlZCB6b25lIGFuZCBjcmVhdGUgYSB3aWxkY2FyZFxuICAgICAqIGNlcnRpZmljYXRlIGZvciB0aGUgZG9tYWluLlxuICAgICAqXG4gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgbGV0IHpvbmU6IElIb3N0ZWRab25lIHwgdW5kZWZpbmVkO1xuICAgIGxldCBjZXJ0aWZpY2F0ZTogQ2VydGlmaWNhdGUgfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAoaG9zdGVkWm9uZUF0dHJpYnV0ZXMpIHtcbiAgICAgIHpvbmUgPSBIb3N0ZWRab25lLmZyb21Ib3N0ZWRab25lQXR0cmlidXRlcyhcbiAgICAgICAgdGhpcyxcbiAgICAgICAgXCJ6b25lXCIsXG4gICAgICAgIGhvc3RlZFpvbmVBdHRyaWJ1dGVzLFxuICAgICAgKTtcbiAgICAgIGNlcnRpZmljYXRlID0gbmV3IENlcnRpZmljYXRlKHRoaXMsIFwid2lsZGNhcmQtY2VydGlmaWNhdGVcIiwge1xuICAgICAgICBkb21haW5OYW1lOiBgKi4ke3RoaXMuZnVsbERvbWFpbn1gLFxuICAgICAgICBzdWJqZWN0QWx0ZXJuYXRpdmVOYW1lczogW3RoaXMuZnVsbERvbWFpbl0sXG4gICAgICAgIHZhbGlkYXRpb246IENlcnRpZmljYXRlVmFsaWRhdGlvbi5mcm9tRG5zTXVsdGlab25lKHtcbiAgICAgICAgICBbYCouJHt0aGlzLmZ1bGxEb21haW59YF06IHpvbmUsXG4gICAgICAgICAgW3RoaXMuZnVsbERvbWFpbl06IHpvbmUsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAqXG4gICAgICogTEFNQkRBQEVER0UgRlVOQ1RJT05cbiAgICAgKlxuICAgICAqIFRoaXMgaGFuZGxlcyByZXdyaXRpbmcgdGhlIHBhdGggZnJvbSBkb21haW4gbmFtZS5cbiAgICAgKlxuICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgXCJ2aWV3ZXItcmVxdWVzdC1oYW5kbGVyXCIsIHtcbiAgICAgIG1lbW9yeVNpemU6IDEyOCxcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzI0X1gsXG4gICAgICBsb2dHcm91cDogbmV3IExvZ0dyb3VwKHRoaXMsIFwidmlld2VyLXJlcXVlc3QtaGFuZGxlci1sb2ctZ3JvdXBcIiwge1xuICAgICAgICByZXRlbnRpb246IFJldGVudGlvbkRheXMuT05FX01PTlRILFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICpcbiAgICAgKiAgQ0xPVURGUk9OVCBDT05GSUdcbiAgICAgKlxuICAgICAqICBTZXR1cCBhIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uIGZvciB0aGUgYnVja2V0LlxuICAgICAqXG4gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgY29uc3QgY2FjaGVQb2xpY3kgPSBuZXcgQ2FjaGVQb2xpY3kodGhpcywgXCJjbG91ZGZyb250LXBvbGljeVwiLCB7XG4gICAgICBjb21tZW50OiBcIlJlbGF0aXZlbHkgY29uc2VydmF0aXZlIFRUTCBwb2xpY3kuXCIsXG4gICAgICBtYXhUdGw6IER1cmF0aW9uLnNlY29uZHMoMzAwKSxcbiAgICAgIG1pblR0bDogRHVyYXRpb24uc2Vjb25kcygwKSxcbiAgICAgIGRlZmF1bHRUdGw6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgaGVhZGVyQmVoYXZpb3I6IENhY2hlSGVhZGVyQmVoYXZpb3Iubm9uZSgpLFxuICAgICAgcXVlcnlTdHJpbmdCZWhhdmlvcjogQ2FjaGVRdWVyeVN0cmluZ0JlaGF2aW9yLm5vbmUoKSxcbiAgICAgIGNvb2tpZUJlaGF2aW9yOiBDYWNoZUNvb2tpZUJlaGF2aW9yLm5vbmUoKSxcbiAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nR3ppcDogdHJ1ZSxcbiAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nQnJvdGxpOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgb2FjID0gbmV3IFMzT3JpZ2luQWNjZXNzQ29udHJvbCh0aGlzLCBcIk15T0FDXCIsIHtcbiAgICAgIHNpZ25pbmc6IFNpZ25pbmcuU0lHVjRfTk9fT1ZFUlJJREUsXG4gICAgfSk7XG4gICAgY29uc3Qgb3JpZ2luID0gUzNCdWNrZXRPcmlnaW4ud2l0aE9yaWdpbkFjY2Vzc0NvbnRyb2woYnVja2V0LCB7XG4gICAgICBvcmlnaW5BY2Nlc3NDb250cm9sOiBvYWMsXG4gICAgICBvcmlnaW5BY2Nlc3NMZXZlbHM6IFtBY2Nlc3NMZXZlbC5SRUFEXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRpc3RyaWJ1dGlvbiA9IG5ldyBEaXN0cmlidXRpb24odGhpcywgXCJjbG91ZGZyb250LWRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICBjb21tZW50OiBgRGlzdHJpYnV0aW9uIGZvciAke3RoaXMuZnVsbERvbWFpbn1gLFxuXG4gICAgICAvKipcbiAgICAgICAqIE9ubHkgaWYgZG9tYWluIHdhcyBzdXBwbGllZFxuICAgICAgICovXG4gICAgICAuLi4oY2VydGlmaWNhdGVcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBjZXJ0aWZpY2F0ZSxcbiAgICAgICAgICAgIGRvbWFpbk5hbWVzOiBbdGhpcy5mdWxsRG9tYWluLCBgKi4ke3RoaXMuZnVsbERvbWFpbn1gXSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuXG4gICAgICBkZWZhdWx0QmVoYXZpb3I6IHtcbiAgICAgICAgb3JpZ2luLFxuICAgICAgICB2aWV3ZXJQcm90b2NvbFBvbGljeTogVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICAgIGNhY2hlUG9saWN5LFxuICAgICAgICBhbGxvd2VkTWV0aG9kczogQWxsb3dlZE1ldGhvZHMuQUxMT1dfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgICAgZWRnZUxhbWJkYXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBmdW5jdGlvblZlcnNpb246IGhhbmRsZXIuY3VycmVudFZlcnNpb24sXG4gICAgICAgICAgICBldmVudFR5cGU6IExhbWJkYUVkZ2VFdmVudFR5cGUuVklFV0VSX1JFUVVFU1QsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICBkZWZhdWx0Um9vdE9iamVjdDogXCJpbmRleC5odG1sXCIsXG4gICAgfSk7XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICpcbiAgICAgKiAgRE5TIEVOVFJZXG4gICAgICpcbiAgICAgKiBMaW5rIGNsb3VkZnJvbnQgdG8gYm90aCB0aGUgcm9vdCBmdWxsZG9tYWluIGFuZCBhbGwgcG9zc2libGUgc3ViZG9tYWlucy5cbiAgICAgKlxuICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIGlmICh6b25lKSB7XG4gICAgICBuZXcgQVJlY29yZCh0aGlzLCBcInJvb3QtZG5zLWVudHJ5XCIsIHtcbiAgICAgICAgem9uZSxcbiAgICAgICAgcmVjb3JkTmFtZTogc3ViRG9tYWluLFxuICAgICAgICB0YXJnZXQ6IFJlY29yZFRhcmdldC5mcm9tQWxpYXMobmV3IENsb3VkRnJvbnRUYXJnZXQoZGlzdHJpYnV0aW9uKSksXG4gICAgICB9KTtcblxuICAgICAgbmV3IEFSZWNvcmQodGhpcywgXCJ3Yy1kbnMtZW50cnlcIiwge1xuICAgICAgICB6b25lLFxuICAgICAgICByZWNvcmROYW1lOiBgKi4ke3N1YkRvbWFpbn1gLFxuICAgICAgICB0YXJnZXQ6IFJlY29yZFRhcmdldC5mcm9tQWxpYXMobmV3IENsb3VkRnJvbnRUYXJnZXQoZGlzdHJpYnV0aW9uKSksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICpcbiAgICAgKiBFWFBPUlRTXG4gICAgICpcbiAgICAgKiBVc2VkIGJ5IGNvbnRlbnQgdXBsb2FkZXIgbGF0ZXIuXG4gICAgICpcbiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbiAgICBuZXcgU3RyaW5nUGFyYW1ldGVyKHRoaXMsIFwiZGlzdC1kb21haW5cIiwge1xuICAgICAgZGVzY3JpcHRpb246IGBHRU5FUkFURUQgRE8gTk9UIENIQU5HRSAtIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uIERldGFpbHMgKCR7dGhpcy5mdWxsRG9tYWlufSkuYCxcbiAgICAgIHBhcmFtZXRlck5hbWU6IGRpc3RyaWJ1dGlvbkRvbWFpblBhcmFtTmFtZSxcbiAgICAgIHN0cmluZ1ZhbHVlOiBkaXN0cmlidXRpb24uZG9tYWluTmFtZSxcbiAgICB9KTtcblxuICAgIG5ldyBTdHJpbmdQYXJhbWV0ZXIodGhpcywgXCJkaXN0LWlkXCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBgR0VORVJBVEVEIERPIE5PVCBDSEFOR0UgLSBDbG91ZEZyb250IERpc3RyaWJ1dGlvbiBEZXRhaWxzICgke3RoaXMuZnVsbERvbWFpbn0pLmAsXG4gICAgICBwYXJhbWV0ZXJOYW1lOiBkaXN0cmlidXRpb25JRFBhcmFtTmFtZSxcbiAgICAgIHN0cmluZ1ZhbHVlOiBkaXN0cmlidXRpb24uZGlzdHJpYnV0aW9uSWQsXG4gICAgfSk7XG5cbiAgICBuZXcgU3RyaW5nUGFyYW1ldGVyKHRoaXMsIFwiYnVja2V0LWFyblwiLCB7XG4gICAgICBkZXNjcmlwdGlvbjogYEdFTkVSQVRFRCBETyBOT1QgQ0hBTkdFIC0gUzMgQnVja2V0IEFSTiBmb3IgU3RhdGljIFdlYnNpdGUgSG9zdGluZyAoJHt0aGlzLmZ1bGxEb21haW59KS5gLFxuICAgICAgcGFyYW1ldGVyTmFtZTogYnVja2V0QXJuUGFyYW1OYW1lLFxuICAgICAgc3RyaW5nVmFsdWU6IGJ1Y2tldC5idWNrZXRBcm4sXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,35 @@
1
+ import { CloudFrontRequest, CloudFrontRequestEvent } from "aws-lambda";
2
+ /**
3
+ *
4
+ * Viewer Request Handler
5
+ *
6
+ * Handles requests at the CloudFront viewer request stage.
7
+ *
8
+ * - Logs the request
9
+ * - Adds default document if needed
10
+ * - Prepends folder with domain
11
+ *
12
+ * @param event CloudFrontRequestEvent
13
+ * @returns CloudFrontRequest
14
+ */
15
+ export declare const handler: (event: CloudFrontRequestEvent) => Promise<CloudFrontRequest>;
16
+ /**
17
+ * This is a helper used in the main handler. It's split into it's own export
18
+ * to make testing easier.
19
+ *
20
+ * Adds default document to request URI if needed.
21
+ *
22
+ * @param request
23
+ * @returns
24
+ */
25
+ export declare const addDefaultDocument: (request: CloudFrontRequest) => CloudFrontRequest;
26
+ /**
27
+ * This is a helper used in the main handler. It's split into it's own export
28
+ * to make testing easier.
29
+ *
30
+ * Adds domain folder to request URI.
31
+ *
32
+ * @param request
33
+ * @returns
34
+ */
35
+ export declare const addDomainFolder: (request: CloudFrontRequest) => CloudFrontRequest;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addDomainFolder = exports.addDefaultDocument = exports.handler = void 0;
4
+ /**
5
+ *
6
+ * Viewer Request Handler
7
+ *
8
+ * Handles requests at the CloudFront viewer request stage.
9
+ *
10
+ * - Logs the request
11
+ * - Adds default document if needed
12
+ * - Prepends folder with domain
13
+ *
14
+ * @param event CloudFrontRequestEvent
15
+ * @returns CloudFrontRequest
16
+ */
17
+ const handler = async (event) => {
18
+ // log request
19
+ if (process.env.JEST_WORKER_ID === undefined) {
20
+ console.log("Request Event: ", JSON.stringify(event, null, 2));
21
+ }
22
+ let request = event.Records[0].cf.request;
23
+ // add index if needed
24
+ request = (0, exports.addDefaultDocument)(request);
25
+ // prepend folder with domain
26
+ request = (0, exports.addDomainFolder)(request);
27
+ if (process.env.JEST_WORKER_ID === undefined) {
28
+ console.log("Resulting Request: ", JSON.stringify(request, null, 2));
29
+ }
30
+ // return body
31
+ return request;
32
+ };
33
+ exports.handler = handler;
34
+ /**
35
+ * This is a helper used in the main handler. It's split into it's own export
36
+ * to make testing easier.
37
+ *
38
+ * Adds default document to request URI if needed.
39
+ *
40
+ * @param request
41
+ * @returns
42
+ */
43
+ const addDefaultDocument = (request) => {
44
+ if (request.uri !== "/") {
45
+ let paths = request.uri.split("/");
46
+ let lastPath = paths[paths.length - 1];
47
+ let isFile = lastPath.split(".").length > 1;
48
+ if (!isFile) {
49
+ if (lastPath != "") {
50
+ request.uri += "/";
51
+ }
52
+ request.uri += "index.html";
53
+ }
54
+ }
55
+ else {
56
+ request.uri = "/index.html";
57
+ }
58
+ return request;
59
+ };
60
+ exports.addDefaultDocument = addDefaultDocument;
61
+ /**
62
+ * This is a helper used in the main handler. It's split into it's own export
63
+ * to make testing easier.
64
+ *
65
+ * Adds domain folder to request URI.
66
+ *
67
+ * @param request
68
+ * @returns
69
+ */
70
+ const addDomainFolder = (request) => {
71
+ const hostHeader = request.headers.host[0].value;
72
+ request.uri = `/${hostHeader}${request.uri}`;
73
+ return request;
74
+ };
75
+ exports.addDomainFolder = addDomainFolder;
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLWhvc3Rpbmcudmlld2VyLXJlcXVlc3QtaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdGF0aWMtaG9zdGluZy9zdGF0aWMtaG9zdGluZy52aWV3ZXItcmVxdWVzdC1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBOzs7Ozs7Ozs7Ozs7R0FZRztBQUNJLE1BQU0sT0FBTyxHQUFHLEtBQUssRUFDMUIsS0FBNkIsRUFDRCxFQUFFO0lBQzlCLGNBQWM7SUFDZCxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzdDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQztJQUUxQyxzQkFBc0I7SUFDdEIsT0FBTyxHQUFHLElBQUEsMEJBQWtCLEVBQUMsT0FBTyxDQUFDLENBQUM7SUFFdEMsNkJBQTZCO0lBQzdCLE9BQU8sR0FBRyxJQUFBLHVCQUFlLEVBQUMsT0FBTyxDQUFDLENBQUM7SUFFbkMsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUM3QyxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxjQUFjO0lBQ2QsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQyxDQUFDO0FBdEJXLFFBQUEsT0FBTyxXQXNCbEI7QUFFRjs7Ozs7Ozs7R0FRRztBQUNJLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxPQUEwQixFQUFFLEVBQUU7SUFDL0QsSUFBSSxPQUFPLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ3hCLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUU1QyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixJQUFJLFFBQVEsSUFBSSxFQUFFLEVBQUUsQ0FBQztnQkFDbkIsT0FBTyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUM7WUFDckIsQ0FBQztZQUNELE9BQU8sQ0FBQyxHQUFHLElBQUksWUFBWSxDQUFDO1FBQzlCLENBQUM7SUFDSCxDQUFDO1NBQU0sQ0FBQztRQUNOLE9BQU8sQ0FBQyxHQUFHLEdBQUcsYUFBYSxDQUFDO0lBQzlCLENBQUM7SUFFRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDLENBQUM7QUFqQlcsUUFBQSxrQkFBa0Isc0JBaUI3QjtBQUVGOzs7Ozs7OztHQVFHO0FBQ0ksTUFBTSxlQUFlLEdBQUcsQ0FBQyxPQUEwQixFQUFFLEVBQUU7SUFDNUQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQ2pELE9BQU8sQ0FBQyxHQUFHLEdBQUcsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQzdDLE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMsQ0FBQztBQUpXLFFBQUEsZUFBZSxtQkFJMUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDbG91ZEZyb250UmVxdWVzdCwgQ2xvdWRGcm9udFJlcXVlc3RFdmVudCB9IGZyb20gXCJhd3MtbGFtYmRhXCI7XG5cbi8qKlxuICpcbiAqIFZpZXdlciBSZXF1ZXN0IEhhbmRsZXJcbiAqXG4gKiBIYW5kbGVzIHJlcXVlc3RzIGF0IHRoZSBDbG91ZEZyb250IHZpZXdlciByZXF1ZXN0IHN0YWdlLlxuICpcbiAqIC0gTG9ncyB0aGUgcmVxdWVzdFxuICogLSBBZGRzIGRlZmF1bHQgZG9jdW1lbnQgaWYgbmVlZGVkXG4gKiAtIFByZXBlbmRzIGZvbGRlciB3aXRoIGRvbWFpblxuICpcbiAqIEBwYXJhbSBldmVudCBDbG91ZEZyb250UmVxdWVzdEV2ZW50XG4gKiBAcmV0dXJucyBDbG91ZEZyb250UmVxdWVzdFxuICovXG5leHBvcnQgY29uc3QgaGFuZGxlciA9IGFzeW5jIChcbiAgZXZlbnQ6IENsb3VkRnJvbnRSZXF1ZXN0RXZlbnQsXG4pOiBQcm9taXNlPENsb3VkRnJvbnRSZXF1ZXN0PiA9PiB7XG4gIC8vIGxvZyByZXF1ZXN0XG4gIGlmIChwcm9jZXNzLmVudi5KRVNUX1dPUktFUl9JRCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc29sZS5sb2coXCJSZXF1ZXN0IEV2ZW50OiBcIiwgSlNPTi5zdHJpbmdpZnkoZXZlbnQsIG51bGwsIDIpKTtcbiAgfVxuXG4gIGxldCByZXF1ZXN0ID0gZXZlbnQuUmVjb3Jkc1swXS5jZi5yZXF1ZXN0O1xuXG4gIC8vIGFkZCBpbmRleCBpZiBuZWVkZWRcbiAgcmVxdWVzdCA9IGFkZERlZmF1bHREb2N1bWVudChyZXF1ZXN0KTtcblxuICAvLyBwcmVwZW5kIGZvbGRlciB3aXRoIGRvbWFpblxuICByZXF1ZXN0ID0gYWRkRG9tYWluRm9sZGVyKHJlcXVlc3QpO1xuXG4gIGlmIChwcm9jZXNzLmVudi5KRVNUX1dPUktFUl9JRCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc29sZS5sb2coXCJSZXN1bHRpbmcgUmVxdWVzdDogXCIsIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QsIG51bGwsIDIpKTtcbiAgfVxuXG4gIC8vIHJldHVybiBib2R5XG4gIHJldHVybiByZXF1ZXN0O1xufTtcblxuLyoqXG4gKiBUaGlzIGlzIGEgaGVscGVyIHVzZWQgaW4gdGhlIG1haW4gaGFuZGxlci4gSXQncyBzcGxpdCBpbnRvIGl0J3Mgb3duIGV4cG9ydFxuICogdG8gbWFrZSB0ZXN0aW5nIGVhc2llci5cbiAqXG4gKiBBZGRzIGRlZmF1bHQgZG9jdW1lbnQgdG8gcmVxdWVzdCBVUkkgaWYgbmVlZGVkLlxuICpcbiAqIEBwYXJhbSByZXF1ZXN0XG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgY29uc3QgYWRkRGVmYXVsdERvY3VtZW50ID0gKHJlcXVlc3Q6IENsb3VkRnJvbnRSZXF1ZXN0KSA9PiB7XG4gIGlmIChyZXF1ZXN0LnVyaSAhPT0gXCIvXCIpIHtcbiAgICBsZXQgcGF0aHMgPSByZXF1ZXN0LnVyaS5zcGxpdChcIi9cIik7XG4gICAgbGV0IGxhc3RQYXRoID0gcGF0aHNbcGF0aHMubGVuZ3RoIC0gMV07XG4gICAgbGV0IGlzRmlsZSA9IGxhc3RQYXRoLnNwbGl0KFwiLlwiKS5sZW5ndGggPiAxO1xuXG4gICAgaWYgKCFpc0ZpbGUpIHtcbiAgICAgIGlmIChsYXN0UGF0aCAhPSBcIlwiKSB7XG4gICAgICAgIHJlcXVlc3QudXJpICs9IFwiL1wiO1xuICAgICAgfVxuICAgICAgcmVxdWVzdC51cmkgKz0gXCJpbmRleC5odG1sXCI7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJlcXVlc3QudXJpID0gXCIvaW5kZXguaHRtbFwiO1xuICB9XG5cbiAgcmV0dXJuIHJlcXVlc3Q7XG59O1xuXG4vKipcbiAqIFRoaXMgaXMgYSBoZWxwZXIgdXNlZCBpbiB0aGUgbWFpbiBoYW5kbGVyLiBJdCdzIHNwbGl0IGludG8gaXQncyBvd24gZXhwb3J0XG4gKiB0byBtYWtlIHRlc3RpbmcgZWFzaWVyLlxuICpcbiAqIEFkZHMgZG9tYWluIGZvbGRlciB0byByZXF1ZXN0IFVSSS5cbiAqXG4gKiBAcGFyYW0gcmVxdWVzdFxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGNvbnN0IGFkZERvbWFpbkZvbGRlciA9IChyZXF1ZXN0OiBDbG91ZEZyb250UmVxdWVzdCkgPT4ge1xuICBjb25zdCBob3N0SGVhZGVyID0gcmVxdWVzdC5oZWFkZXJzLmhvc3RbMF0udmFsdWU7XG4gIHJlcXVlc3QudXJpID0gYC8ke2hvc3RIZWFkZXJ9JHtyZXF1ZXN0LnVyaX1gO1xuICByZXR1cm4gcmVxdWVzdDtcbn07XG4iXX0=
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@codedrifters/constructs",
3
+ "scripts": {
4
+ "build": "npx projen build",
5
+ "compile": "npx projen compile",
6
+ "default": "npx projen default",
7
+ "eslint": "npx projen eslint",
8
+ "package": "npx projen package",
9
+ "post-compile": "npx projen post-compile",
10
+ "post-upgrade": "npx projen post-upgrade",
11
+ "pre-compile": "npx projen pre-compile",
12
+ "test": "npx projen test",
13
+ "test:watch": "npx projen test:watch",
14
+ "upgrade": "npx projen upgrade",
15
+ "watch": "npx projen watch",
16
+ "projen": "npx projen"
17
+ },
18
+ "devDependencies": {
19
+ "@swc/core": "^1.15.2",
20
+ "@swc/jest": "^0.2.39",
21
+ "@types/jest": "^30.0.0",
22
+ "@types/node": "^24.10.1",
23
+ "@typescript-eslint/eslint-plugin": "^8",
24
+ "@typescript-eslint/parser": "^8",
25
+ "aws-cdk-lib": "2.232.1",
26
+ "constructs": "10.4.3",
27
+ "eslint": "^9",
28
+ "eslint-config-prettier": "^10.1.8",
29
+ "eslint-import-resolver-typescript": "^4.4.4",
30
+ "eslint-plugin-import": "^2.32.0",
31
+ "eslint-plugin-prettier": "^5.5.4",
32
+ "jest": "^30.2.0",
33
+ "jest-junit": "^16",
34
+ "prettier": "^3.6.2",
35
+ "typescript": "^5.9.3"
36
+ },
37
+ "peerDependencies": {
38
+ "aws-cdk-lib": "2.232.1",
39
+ "constructs": "10.4.3"
40
+ },
41
+ "dependencies": {
42
+ "@aws-sdk/client-dynamodb": "^3.936.0",
43
+ "@types/aws-lambda": "^8.10.159",
44
+ "change-case": "^4.0",
45
+ "esbuild": "^0.27.0",
46
+ "type-fest": "^4"
47
+ },
48
+ "main": "lib/index.js",
49
+ "license": "UNLICENSED",
50
+ "version": "0.0.0",
51
+ "types": "lib/index.d.ts",
52
+ "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
53
+ }