cdk-nuxt 0.3.2 → 0.3.6

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 CHANGED
@@ -1,5 +1,175 @@
1
- # Easy Nuxt deployments on AWS via CDK
1
+ # CDK Nuxt Plugin
2
2
 
3
- This package allows deployments of Nuxt applications via CDK on AWS by using Route53, API Gateway, Cloudfront, Lambda and S3.
3
+ <p>
4
+ <a href="https://github.com/ferdinandfrank/cdk-nuxt/actions/workflows/publish.yml"><img alt="Build" src="https://img.shields.io/github/workflow/status/ferdinandfrank/cdk-nuxt/Publish?logo=github" /></a>
5
+ <a href="https://www.npmjs.com/package/cdk-nuxt"><img alt="Version" src="https://img.shields.io/npm/v/cdk-nuxt.svg" /></a>
6
+ <a href="https://www.npmjs.com/package/cdk-nuxt"><img alt="License" src="https://img.shields.io/npm/l/cdk-nuxt.svg" /></a>
7
+ </p>
4
8
 
5
- This package is currently in development and will be published with a full Readme shortly.
9
+ Easily deploy a dynamic universal Nuxt application via CDK on AWS including the following features:
10
+
11
+ - Fast responses via [Lambda](https://aws.amazon.com/lambda/)
12
+ - Publicly available by a custom domain (or subdomain) via [Route53](https://aws.amazon.com/route53/) and [API Gateway](https://aws.amazon.com/api-gateway/)
13
+ - Automatic redirects from HTTP to HTTPS via [CloudFront](https://aws.amazon.com/cloudfront/)
14
+ - Automatic upload of the `client` build files for CSR and static assets to [S3](https://aws.amazon.com/s3/) with optimized caching rules
15
+ - Scheduled pings of the Nuxt app to keep the Lambda warm for fast responses via [EventBridge](https://aws.amazon.com/eventbridge/) rules
16
+ - Automatic cleanup of outdated static assets and build files
17
+
18
+ > :warning: **This package might not support every Nuxt config yet.** But feel free to give it a try and open an issue or a PR if necessary.
19
+
20
+ ## Prerequisites
21
+
22
+ - This package currently relies on using [yarn](https://yarnpkg.com/) instead of npm for deployment. Therefore, make sure to have yarn available on the deployment system.
23
+ - You need an [AWS account](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/?nc1=h_ls) to create and deploy the required resources for the Nuxt app on AWS.
24
+
25
+ ## Installation
26
+
27
+ 1. Install the package and its required dependencies:
28
+ ```bash
29
+ yarn add cdk-nuxt --dev # The package itself
30
+ yarn add ts-node typescript --dev # To compile the CDK stacks via typescript
31
+ yarn add aws-cdk@2.10.0 --dev # CDK cli with this exact version for the deployment
32
+ yarn add nuxt-aws-lambda nuxt-start # To make the Nuxt app renderable via AWS Lambda
33
+ ```
34
+
35
+ 2. Move the `nuxt` dependency to `devDependencies` as we installed `nuxt-start` to start our Nuxt app.<br/>Also, make sure that only the dependencies required for server-side rendering (SSR) are listed under `dependencies` to have the Lambda function and its layer as small as possible for better performance and to respect the [Lambda size limits](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html). Every other dependency should be under `devDependencies`.
36
+
37
+ 3. Move the `devDependencies` section in the `package.json` file above the `dependencies` section. This enables the deployment code to fully remove the `devDependencies` section while installing the Lambda layer for the `node_modules` to only keep the modules required for SSR and to keep it as small as possible.
38
+
39
+ After the installation steps the `package.json` file should look something like this:
40
+
41
+ ```json
42
+ {
43
+ "name": "nuxt-app",
44
+ "devDependencies": {
45
+ "aws-cdk": "2.10.0",
46
+ "cdk-nuxt": "^X.X.X",
47
+ "nuxt": "^X.X.X",
48
+ "ts-node": "^X.X.X",
49
+ "typescript": "^X.X.X"
50
+ },
51
+ "dependencies": {
52
+ "nuxt-aws-lambda": "^X.X.X",
53
+ "nuxt-start": "^X.X.X"
54
+ }
55
+ }
56
+ ```
57
+
58
+ ## Setup
59
+
60
+ 1. Replace the `export default` part of your Nuxt configuration file (`nuxt.config.js`) with `module.exports =`, so it fits the following format:
61
+ ```js
62
+ // Change "export default" => "module.exports ="
63
+ module.exports = {
64
+ target: 'server',
65
+ ...
66
+ }
67
+ ```
68
+ 2. [Create an AWS account](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/?nc1=h_ls), if you don't have one yet. Then login into the AWS console and note the `Account ID`. You will need it in step 5.
69
+ 3. [Create a hosted zone in Route53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/AboutHZWorkingWith.html) for the desired domain, if you don't have one yet.<br/>This is required to create DNS records for the domain to make the Nuxt app publicly available on that domain.<br/>On the hosted zone details you should see the `Hosted zone ID` of the hosted zone. You will need it in step 5.
70
+ 4. [Request a public certificate in the AWS Certificate Manager (ACM)](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html) for the desired domain in `us-east-1` (global) and validate it, if you don't have one yet.<br/>This is required to provide the Nuxt app via HTTPS on the public internet.<br/>Take note of the displayed `ARN` for the certificate. You will need it in step 5.<br/>**Important: The certificate must be issued in us-east-1 (global) regardless of the region used for the Nuxt app itself as it will be attached to the Cloudfront distribution which works globally.**
71
+ 5. Run the following command to automatically create the required CDK stack entrypoint at `stack/index.ts`. This file defines the config how the Nuxt app will be deployed via CDK. You should adapt the file to the project's needs, especially the props `env.account` (setup step 2), `hostedZoneId` (setup step 3) and `globalTlsCertificateArn` (setup step 4).
72
+
73
+ ```bash
74
+ node_modules/.bin/cdk-nuxt-init
75
+ ```
76
+
77
+ > :warning: It's recommended using a `.env` file or another secrets file to import the sensitive secrets into the `stack/index.ts` file.
78
+
79
+ ## Build and Deploy
80
+
81
+ After the installation and the setup you are already good to go to build the Nuxt app and to deploy it to AWS with this package.
82
+
83
+ 1. Install the dependencies for the Nuxt app including the `devDependencies` as these are required to successfully build the app:
84
+ ```bash
85
+ yarn install --production=false
86
+ ```
87
+ 2. Build the Nuxt app with the build settings you need for the app:
88
+ ```bash
89
+ yarn build
90
+ ```
91
+ 3. Run the CDK deployment:
92
+ ```bash
93
+ node_modules/.bin/cdk-nuxt-deploy
94
+ ```
95
+ The deployment script will take care of installing only the dependencies that are required for the Nuxt app and deploying the Nuxt build files to AWS according to the stack settings in `stack/index.ts`.<br/>See the section Used AWS Resources for details on which resources will exactly be created on AWS.
96
+
97
+ ## Optional: Automatically deploy on every push (CD) via [GitHub Actions](https://github.com/features/actions)
98
+
99
+ Feel free to copy the following GitHub Actions YAML file content into a YAML file at `.github/workflows/deploy.yml` to automatically build and deploy the Nuxt app to AWS on every push to a specific branch.<br/>This only works if you're using GitHub for the project's VCS repository.
100
+
101
+ ```yaml
102
+ name: Deploy
103
+
104
+ on:
105
+ push:
106
+ branches:
107
+ - master # Feel free to use another branch name
108
+
109
+ jobs:
110
+ build:
111
+ runs-on: ubuntu-latest
112
+ strategy:
113
+ matrix:
114
+ node-version: [ 14.x ]
115
+ steps:
116
+ - name: Checkout source code
117
+ uses: actions/checkout@v2
118
+
119
+ - name: Use Node.js ${{ matrix.node-version }}
120
+ uses: actions/setup-node@v1
121
+ with:
122
+ node-version: ${{ matrix.node-version }}
123
+
124
+ # Init cache to speed up yarn install
125
+ - name: Get yarn cache directory path
126
+ id: yarn-cache-dir-path
127
+ run: echo "::set-output name=dir::$(yarn cache dir)"
128
+
129
+ - uses: actions/cache@v2
130
+ with:
131
+ path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
132
+ key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }}
133
+ restore-keys: |
134
+ ${{ runner.os }}-node-
135
+
136
+ # Optionally copy any secrets from the GitHub repository secrets to the deployment project directory right here
137
+
138
+ - name: Install dependencies
139
+ run: yarn install --production=false # Important to install devDependencies for the build
140
+
141
+ - name: Build project
142
+ run: yarn build # Should trigger 'nuxt build' according to the package.json
143
+
144
+ - name: Deploy to AWS
145
+ run: node_modules/.bin/nuxt-deploy
146
+ env:
147
+ # Create an IAM user on AWS for the deployment and create the appropriate secrets in the GitHub repository secrets
148
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
149
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
150
+ AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
151
+ ```
152
+
153
+ ## Advanced: Used AWS Resources
154
+
155
+ Two CDK stacks will be deployed to AWS using this package:
156
+
157
+ ### NuxtAppStack
158
+
159
+ This is the main stack that is responsible for uploading all assets of the Nuxt app to AWS and to make it publicly reachable.
160
+ The following AWS resources will be created by this stack:
161
+
162
+ - [Lambda](https://aws.amazon.com/lambda/): A Lambda function to render the Nuxt app including a separated Lambda layer to provide the `node_modules` of the Nuxt app required for server-side rendering.
163
+ - [S3](https://aws.amazon.com/s3/): A bucket to store the client files of the Nuxt build (`.nuxt/dist/client`) and the custom static files of the Nuxt app (`static`) with optimized cache settings.
164
+ - [Route53](https://aws.amazon.com/route53/): Two DNS records (`A` for IPv4 and `AAAA` for IPv6) in the configured hosted zone to make the Nuxt app available on the internet via the configured custom domain.
165
+ - [API Gateway](https://aws.amazon.com/api-gateway/): An HTTP API to make the Nuxt Lambda function publicly available.
166
+ - [CloudFront](https://aws.amazon.com/cloudfront/): A distribution to route incoming requests to the Nuxt Lambda function (via the API Gateway) and the S3 bucket to serve the static assets for the Nuxt app.
167
+ - [EventBridge](https://aws.amazon.com/eventbridge/): A scheduled rule to ping the Nuxt app's Lambda function every 5 minutes in order to keep it warm and to speed up initial SSR requests.
168
+
169
+ ### NuxtAppAssetsCleanupStack
170
+
171
+ This stack is responsible for deleting outdated static assets from the S3 deployment bucket created by the NuxtAppStack.
172
+ The following AWS resources will be created by this stack:
173
+
174
+ - [Lambda](https://aws.amazon.com/lambda/): A Lambda function that deletes the outdated static assets of the Nuxt app from S3.
175
+ - [EventBridge](https://aws.amazon.com/eventbridge/): A scheduled rule to trigger the stack's Lambda function every tuesday at 03:30 AM GMT.
package/lib/cli/deploy.js CHANGED
@@ -3,7 +3,7 @@
3
3
  const shell = require("shelljs");
4
4
  const path = require("path");
5
5
 
6
- const logPrefix = 'Nuxt Deployment';
6
+ const logPrefix = 'CDK Nuxt Deployment';
7
7
 
8
8
  shell.echo(`${logPrefix}: Starting deployment...`);
9
9
 
@@ -54,8 +54,15 @@ shell.cp('.yarnclean', deploymentLayerFolder);
54
54
  shell.cd(deploymentLayerFolder);
55
55
 
56
56
  // We do not want to install any dependencies listed under 'devDendencies'
57
- // Usually the --production flag should do the trick but somehow still installs more dependencies as required
58
- shell.exec('sed -i \'\' \'/\\"devDependencies\\"/,/}/ d\' package.json')
57
+ // Usually the --production flag should do the trick but somehow still installs some dev dependencies in some cases
58
+ const osSystem = shell.exec('echo $OSTYPE');
59
+ const isMac = osSystem.startsWith('darwin')
60
+ if (isMac) {
61
+ shell.exec('sed -i \'\' \'/\\"devDependencies\\"/,/}/ d\' package.json')
62
+ } else {
63
+ shell.exec('sed -i \'/\\"devDependencies\\"/,/}/ d\' package.json')
64
+ }
65
+
59
66
  if (shell.exec('yarn install --production --frozen-lockfile').code !== 0) {
60
67
  shell.echo(`${logPrefix} Error: Installation of lambda layer failed.`);
61
68
  shell.exit(1);
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+
3
+ const shell = require("shelljs");
4
+ const path = require("path");
5
+ const fs = require("fs");
6
+
7
+ const logPrefix = 'CDK Nuxt Init';
8
+
9
+ shell.echo(`${logPrefix}: Initializing CDK stack index file...`);
10
+
11
+ if (!fs.existsSync('stack')) {
12
+ shell.mkdir('-p', 'stack');
13
+ shell.cp(path.join(__dirname, '../templates/stack-index.ts'), 'stack/index.ts');
14
+ shell.echo(`${logPrefix}: CDK stack index file created. Please adapt the file at 'stack/index.ts' to the project's needs.`);
15
+ } else {
16
+ shell.echo(`${logPrefix}: CDK stack folder already exists.`);
17
+ }
@@ -9,9 +9,11 @@ const aws_cdk_lib_1 = require("aws-cdk-lib");
9
9
  */
10
10
  const getNuxtAppStaticAssetConfigs = (nuxtConfig) => {
11
11
  var _a, _b;
12
+ // The build assets required for CSR that are generated by 'nuxt build'
12
13
  const buildAssetsSourcePath = './.nuxt/dist/client';
13
14
  const buildAssetsTargetPath = (_b = (_a = nuxtConfig.build) === null || _a === void 0 ? void 0 : _a.publicPath) !== null && _b !== void 0 ? _b : '/_nuxt/'; // Must match 'build.publicPath' in nuxt.config.js
14
- const customAssetsSourcePath = `.${nuxtConfig.srcDir ? (nuxtConfig.srcDir + '/') : ''}/static`;
15
+ // The custom assets of the Nuxt app located in the src 'static' folder
16
+ const customAssetsSourcePath = `./${nuxtConfig.srcDir ? (nuxtConfig.srcDir + '/') : ''}static`;
15
17
  const customAssetsTargetPath = '/';
16
18
  return [
17
19
  // Build Assets
@@ -91,13 +93,15 @@ const getNuxtAppStaticAssetConfigs = (nuxtConfig) => {
91
93
  cacheControl: [aws_s3_deployment_1.CacheControl.setPublic(), aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.days(1))],
92
94
  },
93
95
  {
94
- pattern: 'sw.js',
96
+ pattern: '*.js',
95
97
  source: customAssetsSourcePath,
96
98
  target: customAssetsTargetPath,
97
99
  contentType: 'application/javascript; charset=UTF-8',
100
+ // The js files in the custom static directory are usually not versionized
101
+ // whereby we want to prevent any caching issues when updating them -> cache for only 2 days
98
102
  cacheControl: [aws_s3_deployment_1.CacheControl.setPublic(), aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.days(2))],
99
103
  },
100
104
  ];
101
105
  };
102
106
  exports.getNuxtAppStaticAssetConfigs = getNuxtAppStaticAssetConfigs;
103
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnV4dC1hcHAtc3RhdGljLWFzc2V0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm51eHQtYXBwLXN0YXRpYy1hc3NldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQTJEO0FBQzNELDZDQUFxQztBQStCckM7OztHQUdHO0FBQ0ksTUFBTSw0QkFBNEIsR0FBRyxDQUFDLFVBQXNCLEVBQXVCLEVBQUU7O0lBRXhGLE1BQU0scUJBQXFCLEdBQUcscUJBQXFCLENBQUM7SUFDcEQsTUFBTSxxQkFBcUIsR0FBRyxNQUFBLE1BQUEsVUFBVSxDQUFDLEtBQUssMENBQUUsVUFBVSxtQ0FBSSxTQUFTLENBQUMsQ0FBQyxrREFBa0Q7SUFFM0gsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUM7SUFDL0YsTUFBTSxzQkFBc0IsR0FBRyxHQUFHLENBQUM7SUFFbkMsT0FBTztRQUVILGVBQWU7UUFDZjtZQUNJLE9BQU8sRUFBRSxNQUFNO1lBQ2YsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLFdBQVcsRUFBRSx1Q0FBdUM7U0FDdkQ7UUFDRDtZQUNJLE9BQU8sRUFBRSxVQUFVO1lBQ25CLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixXQUFXLEVBQUUsaUNBQWlDO1NBQ2pEO1FBQ0Q7WUFDSSxPQUFPLEVBQUUsT0FBTztZQUNoQixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsV0FBVyxFQUFFLHlCQUF5QjtTQUN6QztRQUVELGlDQUFpQztRQUNqQztZQUNJLE9BQU8sRUFBRSxpQkFBaUI7WUFDMUIsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLFdBQVcsRUFBRSxpQ0FBaUM7U0FDakQ7UUFDRDtZQUNJLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixXQUFXLEVBQUUsZUFBZTtTQUMvQjtRQUNEO1lBQ0ksT0FBTyxFQUFFLE9BQU87WUFDaEIsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLFdBQVcsRUFBRSwrQkFBK0I7U0FDL0M7UUFDRDtZQUNJLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixXQUFXLEVBQUUsdUJBQXVCO1NBQ3ZDO1FBQ0Q7WUFDSSxPQUFPLEVBQUUsUUFBUTtZQUNqQixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsV0FBVyxFQUFFLFdBQVc7U0FDM0I7UUFDRDtZQUNJLE9BQU8sRUFBRSxTQUFTO1lBQ2xCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixXQUFXLEVBQUUsWUFBWTtTQUM1QjtRQUVELHVCQUF1QjtRQUN2QjtZQUNJLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxzQkFBc0I7WUFDOUIsTUFBTSxFQUFFLHNCQUFzQjtZQUM5QixXQUFXLEVBQUUsV0FBVztTQUMzQjtRQUNEO1lBQ0ksT0FBTyxFQUFFLE9BQU87WUFDaEIsTUFBTSxFQUFFLHNCQUFzQjtZQUM5QixNQUFNLEVBQUUsc0JBQXNCO1lBQzlCLFdBQVcsRUFBRSxXQUFXO1NBQzNCO1FBQ0Q7WUFDSSxPQUFPLEVBQUUsWUFBWTtZQUNyQixNQUFNLEVBQUUsc0JBQXNCO1lBQzlCLE1BQU0sRUFBRSxzQkFBc0I7WUFDOUIsV0FBVyxFQUFFLDJCQUEyQjtZQUN4QyxZQUFZLEVBQUUsQ0FBQyxnQ0FBWSxDQUFDLFNBQVMsRUFBRSxFQUFFLGdDQUFZLENBQUMsTUFBTSxDQUFDLHNCQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDbEY7UUFDRDtZQUNJLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxzQkFBc0I7WUFDOUIsTUFBTSxFQUFFLHNCQUFzQjtZQUM5QixXQUFXLEVBQUUsdUNBQXVDO1lBQ3BELFlBQVksRUFBRSxDQUFDLGdDQUFZLENBQUMsU0FBUyxFQUFFLEVBQUUsZ0NBQVksQ0FBQyxNQUFNLENBQUMsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNsRjtLQUNKLENBQUE7QUFDTCxDQUFDLENBQUM7QUFoR1csUUFBQSw0QkFBNEIsZ0NBZ0d2QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2FjaGVDb250cm9sfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnRcIjtcbmltcG9ydCB7RHVyYXRpb259IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHtOdXh0Q29uZmlnfSBmcm9tIFwiLi9udXh0LWNvbmZpZ1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRpY0Fzc2V0Q29uZmlnIHtcbiAgICAvKipcbiAgICAgKiBUaGUgZmlsZSBwYXR0ZXJuIGZvciB0aGUgaW5jb21pbmcgcmVxdWVzdHMgdGhhdCBzaG91bGQgYmUgZm9yd2FyZGVkIHRvIHRoZSB0YXJnZXQgcGF0aCBpbiB0aGUgc3RhdGljIGFzc2V0cyBTMyBidWNrZXRcbiAgICAgKiB3aXRoIHRoZSBhcHByb3ByaWF0ZSBjYWNoZSBhbmQgY29udGVudCBzZXR0aW5ncyBkZWZpbmVkIGluIHRoZSBzYW1lIG9iamVjdC5cbiAgICAgKi9cbiAgICBwYXR0ZXJuOiBzdHJpbmcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgbG9jYWwgZGlyZWN0b3J5IHRvIHVwbG9hZCB0aGUgZmlsZXMgZnJvbS5cbiAgICAgKi9cbiAgICBzb3VyY2U6IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIFRoZSByZW1vdGUgcGF0aCBhdCB3aGljaCB0byBtYWtlIHRoZSB1cGxvYWRlZCBmaWxlcyBmcm9tIHNvdXJjZSBhY2Nlc3NpYmxlLlxuICAgICAqL1xuICAgIHRhcmdldDogc3RyaW5nLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnQgdHlwZSB0byBzZXQgZm9yIHRoZSBmaWxlcyBpbiB0aGUgc291cmNlIGZvbGRlciB3aGVuIHVwbG9hZGluZyB0aGVtIHRvIHRoZSB0YXJnZXQuXG4gICAgICovXG4gICAgY29udGVudFR5cGU6IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIFRoZSBjYWNoZSBzZXR0aW5ncyB0byB1c2UgZm9yIHRoZSB1cGxvYWRlZCBzb3VyY2UgZmlsZXMgd2hlbiBhY2Nlc3NpbmcgdGhlbSBvbiB0aGUgdGFyZ2V0IHBhdGggd2l0aCB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uXG4gICAgICovXG4gICAgY2FjaGVDb250cm9sPzogQ2FjaGVDb250cm9sW11cbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIHN0YXRpYyBhc3NldHMgb2YgdGhlIE51eHQgYXBwIHRoYXQgc2hhbGwgYmUgcHVibGljbHkgYXZhaWxhYmxlLlxuICogVGhlc2Ugc2hvdWxkIG1hdGNoIHRoZSBmaWxlcyBpbiAnLm51eHQvZGlzdC9jbGllbnQnIGFuZCAnc3RhdGljJy5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldE51eHRBcHBTdGF0aWNBc3NldENvbmZpZ3MgPSAobnV4dENvbmZpZzogTnV4dENvbmZpZyk6IFN0YXRpY0Fzc2V0Q29uZmlnW10gPT4ge1xuXG4gICAgY29uc3QgYnVpbGRBc3NldHNTb3VyY2VQYXRoID0gJy4vLm51eHQvZGlzdC9jbGllbnQnO1xuICAgIGNvbnN0IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCA9IG51eHRDb25maWcuYnVpbGQ/LnB1YmxpY1BhdGggPz8gJy9fbnV4dC8nOyAvLyBNdXN0IG1hdGNoICdidWlsZC5wdWJsaWNQYXRoJyBpbiBudXh0LmNvbmZpZy5qc1xuXG4gICAgY29uc3QgY3VzdG9tQXNzZXRzU291cmNlUGF0aCA9IGAuJHtudXh0Q29uZmlnLnNyY0RpciA/IChudXh0Q29uZmlnLnNyY0RpciArICcvJykgOiAnJ30vc3RhdGljYDtcbiAgICBjb25zdCBjdXN0b21Bc3NldHNUYXJnZXRQYXRoID0gJy8nO1xuXG4gICAgcmV0dXJuIFtcblxuICAgICAgICAvLyBCdWlsZCBBc3NldHNcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyouanMnLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD1VVEYtOCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLmpzLm1hcCcsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyouY3NzJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ3RleHQvY3NzOyBjaGFyc2V0PVVURi04JyxcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBNYW5pZmVzdCBjcmVhdGVkIGJ5IFBXQSBtb2R1bGVcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJ21hbmlmZXN0LiouanNvbicsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04J1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5zdmcnLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnaW1hZ2Uvc3ZnK3htbCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLmVvdCcsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi92bmQubXMtZm9udG9iamVjdCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLnR0ZicsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9mb250LXNmbnQnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi53b2ZmJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2ZvbnQvd29mZicsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLndvZmYyJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2ZvbnQvd29mZjInLFxuICAgICAgICB9LFxuXG4gICAgICAgIC8vIEN1c3RvbSBTdGF0aWMgQXNzZXRzXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLnBuZycsXG4gICAgICAgICAgICBzb3VyY2U6IGN1c3RvbUFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICB0YXJnZXQ6IGN1c3RvbUFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2ltYWdlL3BuZycsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLmpwZycsXG4gICAgICAgICAgICBzb3VyY2U6IGN1c3RvbUFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICB0YXJnZXQ6IGN1c3RvbUFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2ltYWdlL2pwZycsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICdyb2JvdHMudHh0JyxcbiAgICAgICAgICAgIHNvdXJjZTogY3VzdG9tQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIHRhcmdldDogY3VzdG9tQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAndGV4dC9wbGFpbjsgY2hhcnNldD1VVEYtOCcsXG4gICAgICAgICAgICBjYWNoZUNvbnRyb2w6IFtDYWNoZUNvbnRyb2wuc2V0UHVibGljKCksIENhY2hlQ29udHJvbC5tYXhBZ2UoRHVyYXRpb24uZGF5cygxKSldLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnc3cuanMnLFxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PVVURi04JyxcbiAgICAgICAgICAgIGNhY2hlQ29udHJvbDogW0NhY2hlQ29udHJvbC5zZXRQdWJsaWMoKSwgQ2FjaGVDb250cm9sLm1heEFnZShEdXJhdGlvbi5kYXlzKDIpKV0sXG4gICAgICAgIH0sXG4gICAgXVxufTsiXX0=
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnV4dC1hcHAtc3RhdGljLWFzc2V0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm51eHQtYXBwLXN0YXRpYy1hc3NldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBQTJEO0FBQzNELDZDQUFxQztBQStCckM7OztHQUdHO0FBQ0ksTUFBTSw0QkFBNEIsR0FBRyxDQUFDLFVBQXNCLEVBQXVCLEVBQUU7O0lBRXhGLHVFQUF1RTtJQUN2RSxNQUFNLHFCQUFxQixHQUFHLHFCQUFxQixDQUFDO0lBQ3BELE1BQU0scUJBQXFCLEdBQUcsTUFBQSxNQUFBLFVBQVUsQ0FBQyxLQUFLLDBDQUFFLFVBQVUsbUNBQUksU0FBUyxDQUFDLENBQUMsa0RBQWtEO0lBRTNILHVFQUF1RTtJQUN2RSxNQUFNLHNCQUFzQixHQUFHLEtBQUssVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQztJQUMvRixNQUFNLHNCQUFzQixHQUFHLEdBQUcsQ0FBQztJQUVuQyxPQUFPO1FBRUgsZUFBZTtRQUNmO1lBQ0ksT0FBTyxFQUFFLE1BQU07WUFDZixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsV0FBVyxFQUFFLHVDQUF1QztTQUN2RDtRQUNEO1lBQ0ksT0FBTyxFQUFFLFVBQVU7WUFDbkIsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLFdBQVcsRUFBRSxpQ0FBaUM7U0FDakQ7UUFDRDtZQUNJLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixXQUFXLEVBQUUseUJBQXlCO1NBQ3pDO1FBRUQsaUNBQWlDO1FBQ2pDO1lBQ0ksT0FBTyxFQUFFLGlCQUFpQjtZQUMxQixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsV0FBVyxFQUFFLGlDQUFpQztTQUNqRDtRQUNEO1lBQ0ksT0FBTyxFQUFFLE9BQU87WUFDaEIsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLFdBQVcsRUFBRSxlQUFlO1NBQy9CO1FBQ0Q7WUFDSSxPQUFPLEVBQUUsT0FBTztZQUNoQixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsV0FBVyxFQUFFLCtCQUErQjtTQUMvQztRQUNEO1lBQ0ksT0FBTyxFQUFFLE9BQU87WUFDaEIsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLFdBQVcsRUFBRSx1QkFBdUI7U0FDdkM7UUFDRDtZQUNJLE9BQU8sRUFBRSxRQUFRO1lBQ2pCLE1BQU0sRUFBRSxxQkFBcUI7WUFDN0IsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixXQUFXLEVBQUUsV0FBVztTQUMzQjtRQUNEO1lBQ0ksT0FBTyxFQUFFLFNBQVM7WUFDbEIsTUFBTSxFQUFFLHFCQUFxQjtZQUM3QixNQUFNLEVBQUUscUJBQXFCO1lBQzdCLFdBQVcsRUFBRSxZQUFZO1NBQzVCO1FBRUQsdUJBQXVCO1FBQ3ZCO1lBQ0ksT0FBTyxFQUFFLE9BQU87WUFDaEIsTUFBTSxFQUFFLHNCQUFzQjtZQUM5QixNQUFNLEVBQUUsc0JBQXNCO1lBQzlCLFdBQVcsRUFBRSxXQUFXO1NBQzNCO1FBQ0Q7WUFDSSxPQUFPLEVBQUUsT0FBTztZQUNoQixNQUFNLEVBQUUsc0JBQXNCO1lBQzlCLE1BQU0sRUFBRSxzQkFBc0I7WUFDOUIsV0FBVyxFQUFFLFdBQVc7U0FDM0I7UUFDRDtZQUNJLE9BQU8sRUFBRSxZQUFZO1lBQ3JCLE1BQU0sRUFBRSxzQkFBc0I7WUFDOUIsTUFBTSxFQUFFLHNCQUFzQjtZQUM5QixXQUFXLEVBQUUsMkJBQTJCO1lBQ3hDLFlBQVksRUFBRSxDQUFDLGdDQUFZLENBQUMsU0FBUyxFQUFFLEVBQUUsZ0NBQVksQ0FBQyxNQUFNLENBQUMsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNsRjtRQUNEO1lBQ0ksT0FBTyxFQUFFLE1BQU07WUFDZixNQUFNLEVBQUUsc0JBQXNCO1lBQzlCLE1BQU0sRUFBRSxzQkFBc0I7WUFDOUIsV0FBVyxFQUFFLHVDQUF1QztZQUNwRCwwRUFBMEU7WUFDMUUsNEZBQTRGO1lBQzVGLFlBQVksRUFBRSxDQUFDLGdDQUFZLENBQUMsU0FBUyxFQUFFLEVBQUUsZ0NBQVksQ0FBQyxNQUFNLENBQUMsc0JBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNsRjtLQUNKLENBQUE7QUFDTCxDQUFDLENBQUM7QUFwR1csUUFBQSw0QkFBNEIsZ0NBb0d2QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2FjaGVDb250cm9sfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnRcIjtcbmltcG9ydCB7RHVyYXRpb259IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHtOdXh0Q29uZmlnfSBmcm9tIFwiLi9udXh0LWNvbmZpZ1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRpY0Fzc2V0Q29uZmlnIHtcbiAgICAvKipcbiAgICAgKiBUaGUgZmlsZSBwYXR0ZXJuIGZvciB0aGUgaW5jb21pbmcgcmVxdWVzdHMgdGhhdCBzaG91bGQgYmUgZm9yd2FyZGVkIHRvIHRoZSB0YXJnZXQgcGF0aCBpbiB0aGUgc3RhdGljIGFzc2V0cyBTMyBidWNrZXRcbiAgICAgKiB3aXRoIHRoZSBhcHByb3ByaWF0ZSBjYWNoZSBhbmQgY29udGVudCBzZXR0aW5ncyBkZWZpbmVkIGluIHRoZSBzYW1lIG9iamVjdC5cbiAgICAgKi9cbiAgICBwYXR0ZXJuOiBzdHJpbmcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgbG9jYWwgZGlyZWN0b3J5IHRvIHVwbG9hZCB0aGUgZmlsZXMgZnJvbS5cbiAgICAgKi9cbiAgICBzb3VyY2U6IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIFRoZSByZW1vdGUgcGF0aCBhdCB3aGljaCB0byBtYWtlIHRoZSB1cGxvYWRlZCBmaWxlcyBmcm9tIHNvdXJjZSBhY2Nlc3NpYmxlLlxuICAgICAqL1xuICAgIHRhcmdldDogc3RyaW5nLFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnQgdHlwZSB0byBzZXQgZm9yIHRoZSBmaWxlcyBpbiB0aGUgc291cmNlIGZvbGRlciB3aGVuIHVwbG9hZGluZyB0aGVtIHRvIHRoZSB0YXJnZXQuXG4gICAgICovXG4gICAgY29udGVudFR5cGU6IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIFRoZSBjYWNoZSBzZXR0aW5ncyB0byB1c2UgZm9yIHRoZSB1cGxvYWRlZCBzb3VyY2UgZmlsZXMgd2hlbiBhY2Nlc3NpbmcgdGhlbSBvbiB0aGUgdGFyZ2V0IHBhdGggd2l0aCB0aGUgc3BlY2lmaWVkIHBhdHRlcm4uXG4gICAgICovXG4gICAgY2FjaGVDb250cm9sPzogQ2FjaGVDb250cm9sW11cbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIHN0YXRpYyBhc3NldHMgb2YgdGhlIE51eHQgYXBwIHRoYXQgc2hhbGwgYmUgcHVibGljbHkgYXZhaWxhYmxlLlxuICogVGhlc2Ugc2hvdWxkIG1hdGNoIHRoZSBmaWxlcyBpbiAnLm51eHQvZGlzdC9jbGllbnQnIGFuZCAnc3RhdGljJy5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldE51eHRBcHBTdGF0aWNBc3NldENvbmZpZ3MgPSAobnV4dENvbmZpZzogTnV4dENvbmZpZyk6IFN0YXRpY0Fzc2V0Q29uZmlnW10gPT4ge1xuXG4gICAgLy8gVGhlIGJ1aWxkIGFzc2V0cyByZXF1aXJlZCBmb3IgQ1NSIHRoYXQgYXJlIGdlbmVyYXRlZCBieSAnbnV4dCBidWlsZCdcbiAgICBjb25zdCBidWlsZEFzc2V0c1NvdXJjZVBhdGggPSAnLi8ubnV4dC9kaXN0L2NsaWVudCc7XG4gICAgY29uc3QgYnVpbGRBc3NldHNUYXJnZXRQYXRoID0gbnV4dENvbmZpZy5idWlsZD8ucHVibGljUGF0aCA/PyAnL19udXh0Lyc7IC8vIE11c3QgbWF0Y2ggJ2J1aWxkLnB1YmxpY1BhdGgnIGluIG51eHQuY29uZmlnLmpzXG5cbiAgICAvLyBUaGUgY3VzdG9tIGFzc2V0cyBvZiB0aGUgTnV4dCBhcHAgbG9jYXRlZCBpbiB0aGUgc3JjICdzdGF0aWMnIGZvbGRlclxuICAgIGNvbnN0IGN1c3RvbUFzc2V0c1NvdXJjZVBhdGggPSBgLi8ke251eHRDb25maWcuc3JjRGlyID8gKG51eHRDb25maWcuc3JjRGlyICsgJy8nKSA6ICcnfXN0YXRpY2A7XG4gICAgY29uc3QgY3VzdG9tQXNzZXRzVGFyZ2V0UGF0aCA9ICcvJztcblxuICAgIHJldHVybiBbXG5cbiAgICAgICAgLy8gQnVpbGQgQXNzZXRzXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLmpzJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQ7IGNoYXJzZXQ9VVRGLTgnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5qcy5tYXAnLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICcqLmNzcycsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICd0ZXh0L2NzczsgY2hhcnNldD1VVEYtOCcsXG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gTWFuaWZlc3QgY3JlYXRlZCBieSBQV0EgbW9kdWxlXG4gICAgICAgIHtcbiAgICAgICAgICAgIHBhdHRlcm46ICdtYW5pZmVzdC4qLmpzb24nLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCdcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyouc3ZnJyxcbiAgICAgICAgICAgIHRhcmdldDogYnVpbGRBc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgc291cmNlOiBidWlsZEFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ2ltYWdlL3N2Zyt4bWwnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5lb3QnLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24vdm5kLm1zLWZvbnRvYmplY3QnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi50dGYnLFxuICAgICAgICAgICAgdGFyZ2V0OiBidWlsZEFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBzb3VyY2U6IGJ1aWxkQXNzZXRzU291cmNlUGF0aCxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24vZm9udC1zZm50JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyoud29mZicsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdmb250L3dvZmYnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi53b2ZmMicsXG4gICAgICAgICAgICB0YXJnZXQ6IGJ1aWxkQXNzZXRzVGFyZ2V0UGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogYnVpbGRBc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdmb250L3dvZmYyJyxcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBDdXN0b20gU3RhdGljIEFzc2V0c1xuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5wbmcnLFxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdpbWFnZS9wbmcnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAnKi5qcGcnLFxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdpbWFnZS9qcGcnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwYXR0ZXJuOiAncm9ib3RzLnR4dCcsXG4gICAgICAgICAgICBzb3VyY2U6IGN1c3RvbUFzc2V0c1NvdXJjZVBhdGgsXG4gICAgICAgICAgICB0YXJnZXQ6IGN1c3RvbUFzc2V0c1RhcmdldFBhdGgsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogJ3RleHQvcGxhaW47IGNoYXJzZXQ9VVRGLTgnLFxuICAgICAgICAgICAgY2FjaGVDb250cm9sOiBbQ2FjaGVDb250cm9sLnNldFB1YmxpYygpLCBDYWNoZUNvbnRyb2wubWF4QWdlKER1cmF0aW9uLmRheXMoMSkpXSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcGF0dGVybjogJyouanMnLFxuICAgICAgICAgICAgc291cmNlOiBjdXN0b21Bc3NldHNTb3VyY2VQYXRoLFxuICAgICAgICAgICAgdGFyZ2V0OiBjdXN0b21Bc3NldHNUYXJnZXRQYXRoLFxuICAgICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PVVURi04JyxcbiAgICAgICAgICAgIC8vIFRoZSBqcyBmaWxlcyBpbiB0aGUgY3VzdG9tIHN0YXRpYyBkaXJlY3RvcnkgYXJlIHVzdWFsbHkgbm90IHZlcnNpb25pemVkXG4gICAgICAgICAgICAvLyB3aGVyZWJ5IHdlIHdhbnQgdG8gcHJldmVudCBhbnkgY2FjaGluZyBpc3N1ZXMgd2hlbiB1cGRhdGluZyB0aGVtIC0+IGNhY2hlIGZvciBvbmx5IDIgZGF5c1xuICAgICAgICAgICAgY2FjaGVDb250cm9sOiBbQ2FjaGVDb250cm9sLnNldFB1YmxpYygpLCBDYWNoZUNvbnRyb2wubWF4QWdlKER1cmF0aW9uLmRheXMoMikpXSxcbiAgICAgICAgfSxcbiAgICBdXG59OyJdfQ==
@@ -36,10 +36,12 @@ export interface StaticAssetConfig {
36
36
  */
37
37
  export const getNuxtAppStaticAssetConfigs = (nuxtConfig: NuxtConfig): StaticAssetConfig[] => {
38
38
 
39
+ // The build assets required for CSR that are generated by 'nuxt build'
39
40
  const buildAssetsSourcePath = './.nuxt/dist/client';
40
41
  const buildAssetsTargetPath = nuxtConfig.build?.publicPath ?? '/_nuxt/'; // Must match 'build.publicPath' in nuxt.config.js
41
42
 
42
- const customAssetsSourcePath = `.${nuxtConfig.srcDir ? (nuxtConfig.srcDir + '/') : ''}/static`;
43
+ // The custom assets of the Nuxt app located in the src 'static' folder
44
+ const customAssetsSourcePath = `./${nuxtConfig.srcDir ? (nuxtConfig.srcDir + '/') : ''}static`;
43
45
  const customAssetsTargetPath = '/';
44
46
 
45
47
  return [
@@ -123,10 +125,12 @@ export const getNuxtAppStaticAssetConfigs = (nuxtConfig: NuxtConfig): StaticAsse
123
125
  cacheControl: [CacheControl.setPublic(), CacheControl.maxAge(Duration.days(1))],
124
126
  },
125
127
  {
126
- pattern: 'sw.js',
128
+ pattern: '*.js',
127
129
  source: customAssetsSourcePath,
128
130
  target: customAssetsTargetPath,
129
131
  contentType: 'application/javascript; charset=UTF-8',
132
+ // The js files in the custom static directory are usually not versionized
133
+ // whereby we want to prevent any caching issues when updating them -> cache for only 2 days
130
134
  cacheControl: [CacheControl.setPublic(), CacheControl.maxAge(Duration.days(2))],
131
135
  },
132
136
  ]
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ import {App} from "aws-cdk-lib";
3
+ import {NuxtAppStack, NuxtAppStackProps, NuxtAppAssetsCleanupProps, NuxtAppAssetsCleanupStack, AppStackProps} from "cdk-nuxt";
4
+ const NuxtConfig = require('../nuxt.config');
5
+
6
+ const app: App = new App();
7
+
8
+ const commonProps: AppStackProps = {
9
+ // The AWS environment (account/region) where this stack will be deployed.
10
+ env: {
11
+ // The ID of your AWS account on which to deploy the stack.
12
+ account: 'XXXXXXXX',
13
+
14
+ // The AWS region where to deploy the Nuxt app.
15
+ region: 'eu-central-1'
16
+ },
17
+ // A string identifier for the project the Nuxt app is part of. A project might have multiple different services.
18
+ project: 'my-project',
19
+ // A string identifier for the project's service the Nuxt app is created for. This can be seen as the name of the Nuxt app.
20
+ service: 'nuxt-app',
21
+ // A string to identify the environment of the Nuxt app.
22
+ environment: 'dev',
23
+ // Stack tags that will be applied to all the taggable resources and the stack itself.
24
+ tags: {
25
+ service: 'nuxt-app'
26
+ }
27
+ };
28
+
29
+ const appStackProps: NuxtAppStackProps = {
30
+ ...commonProps,
31
+ // The domain (without the protocol) at which the Nuxt app shall be publicly available.
32
+ domain: 'example.com',
33
+ // The ARN of the certificate to use for the Nuxt app to make it accessible via HTTPS.
34
+ // The certificate must be issued for the specified domain in us-east-1 (global) regardless of the region used for the Nuxt app itself.
35
+ globalTlsCertificateArn: 'arn:aws:acm:us-east-1:XXXXXXXXXX:certificate/XXXXXXXXXXXXXXXXX',
36
+ // The id of the hosted zone to create a DNS record for the specified domain.
37
+ hostedZoneId: 'XXXXXXXXXXXXX',
38
+
39
+ nuxtConfig: NuxtConfig
40
+ };
41
+ const appStack = new NuxtAppStack(app, `${appStackProps.project}-${appStackProps.service}-${appStackProps.environment}-stack`, appStackProps);
42
+
43
+ const cleanupStackProps: NuxtAppAssetsCleanupProps = {
44
+ ...commonProps,
45
+ service: `${appStackProps.service}-assets-cleanup`,
46
+ staticAssetsBucket: appStack.staticAssetsBucket,
47
+ };
48
+ new NuxtAppAssetsCleanupStack(app, `${cleanupStackProps.project}-${cleanupStackProps.service}-${cleanupStackProps.environment}-stack`, cleanupStackProps);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdk-nuxt",
3
- "version": "0.3.2",
3
+ "version": "0.3.6",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "lib",
@@ -9,7 +9,8 @@
9
9
  "main": "index.js",
10
10
  "types": "index.d.ts",
11
11
  "bin": {
12
- "nuxt-deploy": "./lib/cli/deploy.js"
12
+ "cdk-nuxt-init": "./lib/cli/init.js",
13
+ "cdk-nuxt-deploy": "./lib/cli/deploy.js"
13
14
  },
14
15
  "scripts": {
15
16
  "build": "tsc"
@@ -30,7 +31,7 @@
30
31
  "source-map-support": "^0.5.16"
31
32
  },
32
33
  "peerDependencies": {
33
- "aws-cdk": "^2.10.0",
34
+ "aws-cdk": "2.10.0",
34
35
  "nuxt-aws-lambda": "^1.5.0",
35
36
  "nuxt-start": "^2.15.8",
36
37
  "ts-node": "^10.5.0",