From b5e3225c9fe20cce1590c1fda640f08e569974be Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2020 17:35:11 +0000 Subject: [PATCH 01/28] chore(deps): bump source-map-support from 0.5.17 to 0.5.18 (#7486) Bumps [source-map-support](https://github.com/evanw/node-source-map-support) from 0.5.17 to 0.5.18. - [Release notes](https://github.com/evanw/node-source-map-support/releases) - [Commits](https://github.com/evanw/node-source-map-support/compare/v0.5.17...v0.5.18) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/aws-cdk/package.json | 2 +- yarn.lock | 126 +++------------------------------- 2 files changed, 12 insertions(+), 116 deletions(-) diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 04014182516d7..aa602768bdf23 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -77,7 +77,7 @@ "promptly": "^3.0.3", "proxy-agent": "^3.1.1", "semver": "^7.2.2", - "source-map-support": "^0.5.17", + "source-map-support": "^0.5.18", "table": "^5.4.6", "uuid": "^7.0.3", "yaml": "^1.9.2", diff --git a/yarn.lock b/yarn.lock index c9ad705030aea..607b917c81ee6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2461,11 +2461,6 @@ anymatch@^3.0.3: normalize-path "^3.0.0" picomatch "^2.0.4" -app-root-path@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" - integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== - append-transform@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" @@ -2716,7 +2711,7 @@ available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: dependencies: array-filter "^1.0.0" -aws-sdk-mock@^5.0.0, aws-sdk-mock@^5.1.0: +aws-sdk-mock@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/aws-sdk-mock/-/aws-sdk-mock-5.1.0.tgz#6f2c0bd670d7f378c906a8dd806f812124db71aa" integrity sha512-Wa5eCSo8HX0Snqb7FdBylaXMmfrAWoWZ+d7MFhiYsgHPvNvMEGjV945FF2qqE1U0Tolr1ALzik1fcwgaOhqUWQ== @@ -2725,21 +2720,6 @@ aws-sdk-mock@^5.0.0, aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" -aws-sdk@^2.596.0: - version "2.658.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.658.0.tgz#dd0b1225d2b42eebdf9c4347a9568f317c0b90b1" - integrity sha512-vb+CorOG2lod4ZztrVaE3hcSjTwnB9HhTOnD/2R9YJtIUGTJqL0CIDTwo0Q384GFROtDhp7j6SX7oKFwdzDEuA== - dependencies: - buffer "4.9.1" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.15.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - uuid "3.3.2" - xml2js "0.4.19" - aws-sdk@^2.637.0, aws-sdk@^2.659.0: version "2.659.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.659.0.tgz#3d14828d50e9a0fd8cd1001b8b1b469febd49302" @@ -4674,21 +4654,11 @@ dotenv-expand@^5.1.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== -dotenv-json@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dotenv-json/-/dotenv-json-1.0.0.tgz#fc7f672aafea04bed33818733b9f94662332815c" - integrity sha512-jAssr+6r4nKhKRudQ0HOzMskOFFi9+ubXWwmrSGJFgTvpjyPXCXsCsYbjif6mXp7uxA7xY3/LGaiTQukZzSbOQ== - dotenv@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== -dotenv@^8.0.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - dotgitignore@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/dotgitignore/-/dotgitignore-2.1.0.tgz#a4b15a4e4ef3cf383598aaf1dfa4a04bcc089b7b" @@ -4923,11 +4893,6 @@ escodegen@~1.9.0: optionalDependencies: source-map "~0.6.1" -eslint-config-standard@^14.1.0: - version "14.1.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" - integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg== - eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" @@ -4955,15 +4920,7 @@ eslint-module-utils@^2.4.1: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-es@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz#0f5f5da5f18aa21989feebe8a73eadefb3432976" - integrity sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ== - dependencies: - eslint-utils "^1.4.2" - regexpp "^3.0.0" - -eslint-plugin-import@^2.19.1, eslint-plugin-import@^2.20.2: +eslint-plugin-import@^2.20.2: version "2.20.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d" integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg== @@ -4981,28 +4938,6 @@ eslint-plugin-import@^2.19.1, eslint-plugin-import@^2.20.2: read-pkg-up "^2.0.0" resolve "^1.12.0" -eslint-plugin-node@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" - integrity sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ== - dependencies: - eslint-plugin-es "^2.0.0" - eslint-utils "^1.4.2" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - -eslint-plugin-promise@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== - -eslint-plugin-standard@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" - integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== - eslint-scope@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" @@ -5011,7 +4946,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.4.2, eslint-utils@^1.4.3: +eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== @@ -6213,11 +6148,6 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1: - version "5.1.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" - integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== - immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -7255,7 +7185,7 @@ jest-worker@^25.4.0: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^25.3.0, jest@^25.4.0: +jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest/-/jest-25.4.0.tgz#fb96892c5c4e4a6b9bcb12068849cddf4c5f8cc7" integrity sha512-XWipOheGB4wai5JfCYXd6vwsWNwM/dirjRoZgAa7H2wd8ODWbli2AiKjqG8AYhyx+8+5FBEdpO92VhGlBydzbw== @@ -7577,24 +7507,6 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -lambda-leak@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lambda-leak/-/lambda-leak-2.0.0.tgz#771985d3628487f6e885afae2b54510dcfb2cd7e" - integrity sha1-dxmF02KEh/boha+uK1RRDc+yzX4= - -lambda-tester@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/lambda-tester/-/lambda-tester-3.6.0.tgz#ceb7d4f4f0da768487a05cff37dcd088508b5247" - integrity sha512-F2ZTGWCLyIR95o/jWK46V/WnOCFAEUG/m/V7/CLhPJ7PCM+pror1rZ6ujP3TkItSGxUfpJi0kqwidw+M/nEqWw== - dependencies: - app-root-path "^2.2.1" - dotenv "^8.0.0" - dotenv-json "^1.0.0" - lambda-leak "^2.0.0" - semver "^6.1.1" - uuid "^3.3.2" - vandium-utils "^1.1.1" - lazystream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" @@ -8380,17 +8292,6 @@ nise@^4.0.1: just-extend "^4.0.2" path-to-regexp "^1.7.0" -nock@^11.7.0: - version "11.9.1" - resolved "https://registry.yarnpkg.com/nock/-/nock-11.9.1.tgz#2b026c5beb6d0dbcb41e7e4cefa671bc36db9c61" - integrity sha512-U5wPctaY4/ar2JJ5Jg4wJxlbBfayxgKbiAeGh+a1kk6Pwnc2ZEuKviLyDSG6t0uXl56q7AALIxoM6FJrBSsVXA== - dependencies: - debug "^4.1.0" - json-stringify-safe "^5.0.1" - lodash "^4.17.13" - mkdirp "^0.5.0" - propagate "^2.0.0" - nock@^12.0.3: version "12.0.3" resolved "https://registry.yarnpkg.com/nock/-/nock-12.0.3.tgz#83f25076dbc4c9aa82b5cdf54c9604c7a778d1c9" @@ -10437,7 +10338,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.x, resolve@^1.1.5, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.4.0: +resolve@1.x, resolve@^1.1.5, resolve@^1.10.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.4.0: version "1.16.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.16.1.tgz#49fac5d8bacf1fd53f200fa51247ae736175832c" integrity sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig== @@ -10606,7 +10507,7 @@ semver-intersect@^1.4.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -10874,10 +10775,10 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.10, source-map-support@^0.5.17, source-map-support@^0.5.6, source-map-support@~0.5.10, source-map-support@~0.5.12: - version "0.5.17" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.17.tgz#29fe1b3c98b9dbd5064ada89052ee8ff070cb46c" - integrity sha512-bwdKOBZ5L0gFRh4KOxNap/J/MpvX9Yxsq9lFDx65s3o7F/NiHy7JRaGIS8MwW6tZPAq9UXE207Il0cfcb5yu/Q== +source-map-support@^0.5.10, source-map-support@^0.5.18, source-map-support@^0.5.6, source-map-support@~0.5.10, source-map-support@~0.5.12: + version "0.5.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.18.tgz#f5f33489e270bd7f7d7e7b8debf283f3a4066960" + integrity sha512-9luZr/BZ2QeU6tO2uG8N2aZpVSli4TSAOAqFOyTO51AJcD9P99c0K1h6dD6r6qo5dyT44BR5exweOaLLeldTkQ== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -11764,7 +11665,7 @@ trivial-deferred@^1.0.1: resolved "https://registry.yarnpkg.com/trivial-deferred/-/trivial-deferred-1.0.1.tgz#376d4d29d951d6368a6f7a0ae85c2f4d5e0658f3" integrity sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM= -ts-jest@^25.3.1, ts-jest@^25.4.0: +ts-jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.4.0.tgz#5ad504299f8541d463a52e93e5e9d76876be0ba4" integrity sha512-+0ZrksdaquxGUBwSdTIcdX7VXdwLIlSRsyjivVA9gcO+Cvr6ByqDhu/mi5+HCcb6cMkiQp5xZ8qRO7/eCqLeyw== @@ -12197,11 +12098,6 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -vandium-utils@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/vandium-utils/-/vandium-utils-1.2.0.tgz#44735de4b7641a05de59ebe945f174e582db4f59" - integrity sha1-RHNd5LdkGgXeWevpRfF05YLbT1k= - vendors@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" From 92686e4cbe4922b041e5b2aed7377a757dc518b1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2020 19:16:43 +0000 Subject: [PATCH 02/28] chore(deps): bump aws-sdk from 2.659.0 to 2.660.0 (#7488) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.659.0 to 2.660.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.659.0...v2.660.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-cloudfront/package.json | 2 +- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- packages/@aws-cdk/aws-codebuild/package.json | 2 +- packages/@aws-cdk/aws-codecommit/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 2 +- packages/@aws-cdk/aws-events-targets/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-sqs/package.json | 2 +- packages/@aws-cdk/custom-resources/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- yarn.lock | 8 ++++---- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index 3602de754cf7d..547d045901823 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index fc72871d40fc1..9630eac937be6 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index bbd4bc194b63d..3d20e12b9a500 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -70,7 +70,7 @@ "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-sqs": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index a0387494d4f63..cb73512444adf 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -70,7 +70,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index 04bc87c8a9997..650f7a428fe9f 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/jest": "^25.2.1", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index 206fd3d756c49..53e0c177e6c23 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index eb91950196fcb..2f143e9564e5a 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -86,7 +86,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index fa16dd47cad46..99f435418410c 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -71,7 +71,7 @@ "@types/lodash": "^4.14.150", "@types/nodeunit": "^0.0.30", "@types/sinon": "^9.0.0", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index 287989a09036b..bceb659370360 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-sqs/package.json b/packages/@aws-cdk/aws-sqs/package.json index 1edf1c75eb5e3..9fd3d3e07af99 100644 --- a/packages/@aws-cdk/aws-sqs/package.json +++ b/packages/@aws-cdk/aws-sqs/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 7fe4a53f54dc2..e8e36478b5fba 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -73,7 +73,7 @@ "@types/aws-lambda": "^8.10.39", "@types/fs-extra": "^8.1.0", "@types/sinon": "^9.0.0", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index aa602768bdf23..392f52e29299c 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -65,7 +65,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/region-info": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "camelcase": "^6.0.0", "cdk-assets": "0.0.0", "colors": "^1.4.0", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index 6a383156009c5..483bc31e2e3d5 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -44,7 +44,7 @@ "dependencies": { "@aws-cdk/cdk-assets-schema": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.659.0", + "aws-sdk": "^2.660.0", "glob": "^7.1.6", "yargs": "^15.3.1" }, diff --git a/yarn.lock b/yarn.lock index 607b917c81ee6..7b07a6e0b4bb6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2720,10 +2720,10 @@ aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" -aws-sdk@^2.637.0, aws-sdk@^2.659.0: - version "2.659.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.659.0.tgz#3d14828d50e9a0fd8cd1001b8b1b469febd49302" - integrity sha512-gtMIHS0BL/ckq6tm6NpeJhI6+GIXI0YrDVkpbHP2lfazsno9TgRyGI/P19QOa8tWaAujgw+GustTtZCEi0LVDA== +aws-sdk@^2.637.0, aws-sdk@^2.660.0: + version "2.660.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.660.0.tgz#1be2f814ffdb1aadf859b252601974073a39a4b2" + integrity sha512-6FR91Jg1x9TuFglsdBHkRuE4X7sPRwqeTB2GwLk9XPX1giicdMvJrWbcw5rUnMKjXs9LVlkwaK5VI9AJ0d8dpw== dependencies: buffer "4.9.1" events "1.1.1" From 905ac8053aa0772b99a428dbf23197f332d31231 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Tue, 21 Apr 2020 22:52:06 +0300 Subject: [PATCH 03/28] chore(config): added notice of initial setup for config (#7480) Clarify to users that in order to use the module, one needs to first do an initial region setup. --- packages/@aws-cdk/aws-config/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/@aws-cdk/aws-config/README.md b/packages/@aws-cdk/aws-config/README.md index 0a84724e4e39d..c004579117aef 100644 --- a/packages/@aws-cdk/aws-config/README.md +++ b/packages/@aws-cdk/aws-config/README.md @@ -23,6 +23,19 @@ Not supported * Delivery channel * Aggregation +### Initial Setup + +Before using the constructs provided in this module, you need to setup +AWS Config in the region you plan on using it in. This setup includes: + +- `ConfigurationRecorder`: Configure which resources will be recorded for config changes. +- `DeliveryChannel`: Configure where to store the recorded data. + +Following are the guides to setup AWS Config: + +- [Using the AWS Console](https://docs.aws.amazon.com/config/latest/developerguide/gs-console.html) +- [Using the AWS CLI](https://docs.aws.amazon.com/config/latest/developerguide/gs-cli.html) + ### Rules #### AWS managed rules From 19134b34f9a40d26928fbd0829dc4b4ab66307d4 Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Tue, 21 Apr 2020 16:37:33 -0700 Subject: [PATCH 04/28] fix(cli): Javascript init-templates cannot be synthesized This was a result of switching the templates to use ES6 style imports in #7356, which Node does not support yet and not with our minimum of `10.12.0`. --- .../init-templates/app/javascript/bin/%name%.template.js | 4 ++-- .../app/javascript/lib/%name%-stack.template.js | 2 +- .../app/javascript/test/%name%.test.template.js | 6 +++--- .../sample-app/javascript/bin/%name%.template.js | 4 ++-- .../sample-app/javascript/lib/%name%-stack.template.js | 8 ++++---- .../sample-app/javascript/test/%name%.test.template.js | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/aws-cdk/lib/init-templates/app/javascript/bin/%name%.template.js b/packages/aws-cdk/lib/init-templates/app/javascript/bin/%name%.template.js index 1bdfc68885daa..7ef6ca7df55c0 100644 --- a/packages/aws-cdk/lib/init-templates/app/javascript/bin/%name%.template.js +++ b/packages/aws-cdk/lib/init-templates/app/javascript/bin/%name%.template.js @@ -1,7 +1,7 @@ #!/usr/bin/env node -import * as cdk from '@aws-cdk/core'; -import { %name.PascalCased%Stack } from '../lib/%name%-stack'; +const cdk = require('@aws-cdk/core'); +const { %name.PascalCased%Stack } = require('../lib/%name%-stack'); const app = new cdk.App(); new %name.PascalCased%Stack(app, '%name.PascalCased%Stack'); diff --git a/packages/aws-cdk/lib/init-templates/app/javascript/lib/%name%-stack.template.js b/packages/aws-cdk/lib/init-templates/app/javascript/lib/%name%-stack.template.js index fc502be4dff1c..2c52c5f65244c 100644 --- a/packages/aws-cdk/lib/init-templates/app/javascript/lib/%name%-stack.template.js +++ b/packages/aws-cdk/lib/init-templates/app/javascript/lib/%name%-stack.template.js @@ -1,4 +1,4 @@ -import * as cdk from '@aws-cdk/core'; +const cdk = require('@aws-cdk/core'); class %name.PascalCased%Stack extends cdk.Stack { /** diff --git a/packages/aws-cdk/lib/init-templates/app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/app/javascript/test/%name%.test.template.js index 5d5e8c354b61a..54e6bb172e0a9 100644 --- a/packages/aws-cdk/lib/init-templates/app/javascript/test/%name%.test.template.js +++ b/packages/aws-cdk/lib/init-templates/app/javascript/test/%name%.test.template.js @@ -1,6 +1,6 @@ -import { expect, matchTemplate, MatchStyle } from '@aws-cdk/assert'; -import * as cdk from '@aws-cdk/core'; -import * as %name.PascalCased% from '../lib/%name%-stack'; +const { expect, matchTemplate, MatchStyle } = require('@aws-cdk/assert'); +const cdk = require('@aws-cdk/core'); +const %name.PascalCased% = require('../lib/%name%-stack'); test('Empty Stack', () => { const app = new cdk.App(); diff --git a/packages/aws-cdk/lib/init-templates/sample-app/javascript/bin/%name%.template.js b/packages/aws-cdk/lib/init-templates/sample-app/javascript/bin/%name%.template.js index e5a8898954256..7b10196e54f23 100644 --- a/packages/aws-cdk/lib/init-templates/sample-app/javascript/bin/%name%.template.js +++ b/packages/aws-cdk/lib/init-templates/sample-app/javascript/bin/%name%.template.js @@ -1,6 +1,6 @@ #!/usr/bin/env node -import * as cdk from '@aws-cdk/core'; -import { %name.PascalCased%Stack } from '../lib/%name%-stack'; +const cdk = require('@aws-cdk/core'); +const { %name.PascalCased%Stack } = require('../lib/%name%-stack'); const app = new cdk.App(); new %name.PascalCased%Stack(app, '%name.PascalCased%Stack'); diff --git a/packages/aws-cdk/lib/init-templates/sample-app/javascript/lib/%name%-stack.template.js b/packages/aws-cdk/lib/init-templates/sample-app/javascript/lib/%name%-stack.template.js index e335ae411c8bb..ef14c40799701 100644 --- a/packages/aws-cdk/lib/init-templates/sample-app/javascript/lib/%name%-stack.template.js +++ b/packages/aws-cdk/lib/init-templates/sample-app/javascript/lib/%name%-stack.template.js @@ -1,7 +1,7 @@ -import * as sns from '@aws-cdk/aws-sns'; -import * as subs from '@aws-cdk/aws-sns-subscriptions'; -import * as sqs from '@aws-cdk/aws-sqs'; -import * as cdk from '@aws-cdk/core'; +const sns = require('@aws-cdk/aws-sns'); +const subs = require('@aws-cdk/aws-sns-subscriptions'); +const sqs = require('@aws-cdk/aws-sqs'); +const cdk = require('@aws-cdk/core'); class %name.PascalCased%Stack extends cdk.Stack { /** diff --git a/packages/aws-cdk/lib/init-templates/sample-app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/sample-app/javascript/test/%name%.test.template.js index a0779aab6f1ac..7e786e6ee3753 100644 --- a/packages/aws-cdk/lib/init-templates/sample-app/javascript/test/%name%.test.template.js +++ b/packages/aws-cdk/lib/init-templates/sample-app/javascript/test/%name%.test.template.js @@ -1,6 +1,6 @@ -import { expect, haveResource } from '@aws-cdk/assert'; -import * as cdk from '@aws-cdk/core'; -import * as %name.PascalCased% from '../lib/%name%-stack'; +const { expect, haveResource } = require('@aws-cdk/assert'); +const cdk = require('@aws-cdk/core'); +const %name.PascalCased% = require('../lib/%name%-stack'); test('SQS Queue Created', () => { const app = new cdk.App(); From ec80519cff2054abeae94e2d5708aef3aab18c55 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2020 03:33:21 +0000 Subject: [PATCH 05/28] chore(deps-dev): bump @types/node from 10.17.20 to 10.17.21 (#7499) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 10.17.20 to 10.17.21. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/core/package.json | 2 +- packages/@monocdk-experiment/rewrite-imports/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- packages/monocdk-experiment/package.json | 2 +- yarn.lock | 8 ++++---- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json index f5cf0300747f1..77a8adb5f1f5d 100644 --- a/packages/@aws-cdk/core/package.json +++ b/packages/@aws-cdk/core/package.json @@ -137,7 +137,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/lodash": "^4.14.150", - "@types/node": "^10.17.18", + "@types/node": "^10.17.21", "@types/nodeunit": "^0.0.30", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@monocdk-experiment/rewrite-imports/package.json b/packages/@monocdk-experiment/rewrite-imports/package.json index 32010a62f0138..ec52684f7fc12 100644 --- a/packages/@monocdk-experiment/rewrite-imports/package.json +++ b/packages/@monocdk-experiment/rewrite-imports/package.json @@ -33,7 +33,7 @@ "devDependencies": { "@types/glob": "^7.1.1", "@types/jest": "^25.2.1", - "@types/node": "^10.17.18", + "@types/node": "^10.17.21", "cdk-build-tools": "0.0.0", "pkglint": "0.0.0" }, diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 392f52e29299c..0b9536c028795 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -41,7 +41,7 @@ "@types/jest": "^25.2.1", "@types/minimatch": "^3.0.3", "@types/mockery": "^1.4.29", - "@types/node": "^10.17.18", + "@types/node": "^10.17.21", "@types/promptly": "^3.0.0", "@types/semver": "^7.1.0", "@types/sinon": "^9.0.0", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index 483bc31e2e3d5..4b1eccc76cfcd 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -32,7 +32,7 @@ "@types/glob": "^7.1.1", "@types/jest": "^25.2.1", "@types/mock-fs": "^4.10.0", - "@types/node": "^10.17.18", + "@types/node": "^10.17.21", "@types/yargs": "^15.0.4", "@types/jszip": "^3.1.7", "jszip": "^3.4.0", diff --git a/packages/monocdk-experiment/package.json b/packages/monocdk-experiment/package.json index 5c306908d629e..5d1ecec1e36d9 100644 --- a/packages/monocdk-experiment/package.json +++ b/packages/monocdk-experiment/package.json @@ -161,7 +161,7 @@ "@aws-cdk/custom-resources": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", - "@types/node": "^10.17.18", + "@types/node": "^10.17.21", "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/aws-chatbot": "0.0.0", "@aws-cdk/aws-codestarconnections": "0.0.0", diff --git a/yarn.lock b/yarn.lock index 7b07a6e0b4bb6..1777bed3a382d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2116,10 +2116,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.0.tgz#30d2d09f623fe32cde9cb582c7a6eda2788ce4a8" integrity sha512-WE4IOAC6r/yBZss1oQGM5zs2D7RuKR6Q+w+X2SouPofnWn+LbCqClRyhO3ZE7Ix8nmFgo/oVuuE01cJT2XB13A== -"@types/node@^10.17.18": - version "10.17.20" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.20.tgz#e6d8b3631af1e59bbb4fda04926b078acdd3c2ef" - integrity sha512-XgDgo6W10SeGEAM0k7FosJpvLCynOTYns4Xk3J5HGrA+UI/bKZ30PGMzOP5Lh2zs4259I71FSYLAtjnx3qhObw== +"@types/node@^10.17.21": + version "10.17.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.21.tgz#c00e9603399126925806bed2d9a1e37da506965e" + integrity sha512-PQKsydPxYxF1DsAFWmunaxd3sOi3iMt6Zmx/tgaagHYmwJ/9cRH91hQkeJZaUGWbvn0K5HlSVEXkn5U/llWPpQ== "@types/nodeunit@^0.0.30": version "0.0.30" From 32299ef2bc6fe73c96bffb14cbae9f766119bb38 Mon Sep 17 00:00:00 2001 From: flemjame-at-amazon <57235867+flemjame-at-amazon@users.noreply.github.com> Date: Wed, 22 Apr 2020 04:02:52 -0400 Subject: [PATCH 06/28] chore: reference default Vpc subnet selection strategy from modules that expose it (#7467) * Reference the 'Vpc default strategy' for subnet selection when it makes sense * Trailing whitespace Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts | 3 ++- packages/@aws-cdk/aws-efs/lib/efs-file-system.ts | 4 ++-- .../lib/shared/base-load-balancer.ts | 7 +++---- packages/@aws-cdk/aws-lambda/lib/function.ts | 2 +- packages/@aws-cdk/aws-rds/lib/cluster.ts | 2 ++ packages/@aws-cdk/aws-rds/lib/props.ts | 2 +- .../@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts | 2 +- 7 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index 916a7122e6508..5f2339f625fe9 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -347,7 +347,8 @@ abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGrou * It allows adding arbitrary commands to the startup scripts of the instances * in the fleet. * - * The ASG spans all availability zones. + * The ASG spans the availability zones specified by vpcSubnets, falling back to + * the Vpc default strategy if not specified. */ export class AutoScalingGroup extends AutoScalingGroupBase implements elb.ILoadBalancerTarget, diff --git a/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts b/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts index b546dcbc5b0ae..3b6337c838c79 100644 --- a/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts +++ b/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts @@ -101,9 +101,9 @@ export interface EfsFileSystemProps { readonly securityGroup?: ec2.ISecurityGroup; /** - * Where to place the mount target within the VPC. + * Which subnets to place the mount target in the VPC. * - * @default - Private subnets + * @default - the Vpc default strategy if not specified */ readonly vpcSubnets?: ec2.SubnetSelection; diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts index 1d21502f5acfa..15152b7fc89a5 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts @@ -29,11 +29,10 @@ export interface BaseLoadBalancerProps { readonly internetFacing?: boolean; /** - * Where in the VPC to place the load balancer + * Which subnets place the load balancer in + * + * @default - the Vpc default strategy. * - * @default - Public subnets if internetFacing, Private subnets if internal and - * there are Private subnets, Isolated subnets if internal and there are no - * Private subnets. */ readonly vpcSubnets?: ec2.SubnetSelection; diff --git a/packages/@aws-cdk/aws-lambda/lib/function.ts b/packages/@aws-cdk/aws-lambda/lib/function.ts index 4205819b9e573..f66a67f07e336 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function.ts @@ -119,7 +119,7 @@ export interface FunctionOptions extends EventInvokeConfigOptions { * Only used if 'vpc' is supplied. Note: internet access for Lambdas * requires a NAT gateway, so picking Public subnets is not allowed. * - * @default - Private subnets. + * @default - the Vpc default strategy if not specified */ readonly vpcSubnets?: ec2.SubnetSelection; diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index 357e1c19d10bf..a43cf1c6b87f0 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -332,6 +332,8 @@ export class DatabaseCluster extends DatabaseClusterBase { /** * The subnets used by the DB subnet group. + * + * @default - the Vpc default strategy if not specified. */ private readonly vpcSubnets?: ec2.SubnetSelection; diff --git a/packages/@aws-cdk/aws-rds/lib/props.ts b/packages/@aws-cdk/aws-rds/lib/props.ts index 8d3980a759242..5f198a2214e94 100644 --- a/packages/@aws-cdk/aws-rds/lib/props.ts +++ b/packages/@aws-cdk/aws-rds/lib/props.ts @@ -107,7 +107,7 @@ export interface InstanceProps { /** * Where to place the instances within the VPC * - * @default private subnets + * @default - the Vpc default strategy if not specified. */ readonly vpcSubnets?: ec2.SubnetSelection; diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts b/packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts index 6137ed99a1a2e..706894935299a 100644 --- a/packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts +++ b/packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts @@ -178,7 +178,7 @@ export interface SecretRotationProps { /** * The type of subnets in the VPC where the Lambda rotation function will run. * - * @default - Private subnets. + * @default - the Vpc default strategy if not specified. */ readonly vpcSubnets?: ec2.SubnetSelection; From feadd6cb643b415ae002191ba2cb4622221a5af6 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Wed, 22 Apr 2020 10:18:53 +0100 Subject: [PATCH 07/28] feat(cognito): user pool domain (#7224) Support for user pool domains in the Cognito module. Domains can be explicitly configured for either custom domain or Cognito hosted prefix domains. Added 'cloudFrontDomainName' property that gets the CloudFront domain name by calling `DescribeUserPoolDomain` API via a custom resource. closes #6787. --- packages/@aws-cdk/aws-cognito/README.md | 32 +++ packages/@aws-cdk/aws-cognito/lib/index.ts | 3 +- .../aws-cognito/lib/user-pool-client.ts | 2 +- .../aws-cognito/lib/user-pool-domain.ts | 129 +++++++++ .../@aws-cdk/aws-cognito/lib/user-pool.ts | 16 ++ packages/@aws-cdk/aws-cognito/package.json | 7 +- ...-pool-client-explicit-props.expected.json} | 0 ... integ.user-pool-client-explicit-props.ts} | 0 ...nteg.user-pool-domain-cfdist.expected.json | 254 ++++++++++++++++++ .../test/integ.user-pool-domain-cfdist.ts | 26 ++ ...teg.user-pool-explicit-props.expected.json | 26 ++ .../test/integ.user-pool-explicit-props.ts | 10 + .../aws-cognito/test/user-pool-domain.test.ts | 128 +++++++++ .../@aws-cdk/aws-route53-targets/README.md | 9 +- .../lib/cloudfront-target.ts | 14 +- .../@aws-cdk/aws-route53-targets/lib/index.ts | 1 + .../lib/userpool-domain.ts | 18 ++ .../@aws-cdk/aws-route53-targets/package.json | 2 + .../test/userpool-domain.test.ts | 33 +++ 19 files changed, 699 insertions(+), 11 deletions(-) create mode 100644 packages/@aws-cdk/aws-cognito/lib/user-pool-domain.ts rename packages/@aws-cdk/aws-cognito/test/{integ.user-pool-client-explcit-props.expected.json => integ.user-pool-client-explicit-props.expected.json} (100%) rename packages/@aws-cdk/aws-cognito/test/{integ.user-pool-client-explcit-props.ts => integ.user-pool-client-explicit-props.ts} (100%) create mode 100644 packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.expected.json create mode 100644 packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.ts create mode 100644 packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts create mode 100644 packages/@aws-cdk/aws-route53-targets/lib/userpool-domain.ts create mode 100644 packages/@aws-cdk/aws-route53-targets/test/userpool-domain.test.ts diff --git a/packages/@aws-cdk/aws-cognito/README.md b/packages/@aws-cdk/aws-cognito/README.md index ee9a2b93ace4b..e16a1ccaef3e6 100644 --- a/packages/@aws-cdk/aws-cognito/README.md +++ b/packages/@aws-cdk/aws-cognito/README.md @@ -37,6 +37,7 @@ This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aw - [Lambda Triggers](#lambda-triggers) - [Import](#importing-user-pools) - [App Clients](#app-clients) + - [Domains](#domains) ## User Pools @@ -398,3 +399,34 @@ pool.addClient('app-client', { } }); ``` + +### Domains + +After setting up an [app client](#app-clients), the address for the user pool's sign-up and sign-in webpages can be +configured using domains. There are two ways to set up a domain - either the Amazon Cognito hosted domain can be chosen +with an available domain prefix, or a custom domain name can be chosen. The custom domain must be one that is already +owned, and whose certificate is registered in AWS Certificate Manager. + +The following code sets up a user pool domain in Amazon Cognito hosted domain with the prefix 'my-awesome-app' - + +```ts +const pool = new UserPool(this, 'Pool'); +pool.addDomain('domain', { + domain: UserPoolDomainType.cognitoDomain({ + domainPrefix: 'my-awesome-app', + }), +}); +``` + +On the other hand, the following code sets up a user pool domain and use your own custom domain - + +```ts +const domainCert = new acm.Certificate.fromCertificateArn(this, 'domainCert', certificateArn); +const pool = new UserPool(this, 'Pool'); +pool.addDomain('domain', { + domain: UserPoolDomainType.customDomain({ + domainPrefix: 'my-awesome-app', + certificate: domainCert, + }), +}); +``` \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/lib/index.ts b/packages/@aws-cdk/aws-cognito/lib/index.ts index d19f4fc1882cf..c7f8ba6547ceb 100644 --- a/packages/@aws-cdk/aws-cognito/lib/index.ts +++ b/packages/@aws-cdk/aws-cognito/lib/index.ts @@ -2,4 +2,5 @@ export * from './cognito.generated'; export * from './user-pool'; export * from './user-pool-attr'; -export * from './user-pool-client'; \ No newline at end of file +export * from './user-pool-client'; +export * from './user-pool-domain'; \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts index 639de30001655..cde6bf72191ca 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts @@ -146,7 +146,7 @@ export class OAuthScope { } /** - * Properties for the UserPoolClient construct + * Options to create a UserPoolClient */ export interface UserPoolClientOptions { /** diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool-domain.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool-domain.ts new file mode 100644 index 0000000000000..b1518861e2fbb --- /dev/null +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool-domain.ts @@ -0,0 +1,129 @@ +import { ICertificate } from '@aws-cdk/aws-certificatemanager'; +import { Construct, IResource, Resource } from '@aws-cdk/core'; +import { AwsCustomResource, AwsCustomResourcePolicy, AwsSdkCall, PhysicalResourceId } from '@aws-cdk/custom-resources'; +import { CfnUserPoolDomain } from './cognito.generated'; +import { IUserPool } from './user-pool'; + +/** + * Represents a user pool domain. + */ +export interface IUserPoolDomain extends IResource { + /** + * The domain that was specified to be created. + * If `customDomain` was selected, this holds the full domain name that was specified. + * If the `cognitoDomain` was used, it contains the prefix to the Cognito hosted domain. + * @attribute + */ + readonly domainName: string; +} + +/** + * Options while specifying custom domain + * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-add-custom-domain.html + */ +export interface CustomDomainOptions { + /** + * The custom domain name that you would like to associate with this User Pool. + */ + readonly domainName: string; + + /** + * The certificate to associate with this domain. + */ + readonly certificate: ICertificate; +} + +/** + * Options while specifying a cognito prefix domain. + * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-assign-domain-prefix.html + */ +export interface CognitoDomainOptions { + /** + * The prefix to the Cognito hosted domain name that will be associated with the user pool. + */ + readonly domainPrefix: string; +} + +/** + * Options to create a UserPoolDomain + */ +export interface UserPoolDomainOptions { + /** + * Associate a custom domain with your user pool + * Either `customDomain` or `cognitoDomain` must be specified. + * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-add-custom-domain.html + * @default - not set if `cognitoDomain` is specified, otherwise, throws an error. + */ + readonly customDomain?: CustomDomainOptions; + + /** + * Associate a cognito prefix domain with your user pool + * Either `customDomain` or `cognitoDomain` must be specified. + * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-assign-domain-prefix.html + * @default - not set if `customDomain` is specified, otherwise, throws an error. + */ + readonly cognitoDomain?: CognitoDomainOptions; +} + +/** + * Props for UserPoolDomain construct + */ +export interface UserPoolDomainProps extends UserPoolDomainOptions { + /** + * The user pool to which this domain should be associated. + */ + readonly userPool: IUserPool; +} + +/** + * Define a user pool domain + */ +export class UserPoolDomain extends Resource implements IUserPoolDomain { + public readonly domainName: string; + + constructor(scope: Construct, id: string, props: UserPoolDomainProps) { + super(scope, id); + + if (!!props.customDomain === !!props.cognitoDomain) { + throw new Error('One of, and only one of, cognitoDomain or customDomain must be specified'); + } + + if (props.cognitoDomain?.domainPrefix && !/^[a-z0-9-]+$/.test(props.cognitoDomain.domainPrefix)) { + throw new Error('domainPrefix for cognitoDomain can contain only lowercase alphabets, numbers and hyphens'); + } + + const domainName = props.cognitoDomain?.domainPrefix || props.customDomain?.domainName!; + const resource = new CfnUserPoolDomain(this, 'Resource', { + userPoolId: props.userPool.userPoolId, + domain: domainName, + customDomainConfig: props.customDomain ? { certificateArn: props.customDomain.certificate.certificateArn } : undefined, + }); + + this.domainName = resource.ref; + } + + /** + * The domain name of the CloudFront distribution associated with the user pool domain. + */ + public get cloudFrontDomainName(): string { + const sdkCall: AwsSdkCall = { + service: 'CognitoIdentityServiceProvider', + action: 'describeUserPoolDomain', + parameters: { + Domain: this.domainName, + }, + physicalResourceId: PhysicalResourceId.of(this.domainName), + }; + const customResource = new AwsCustomResource(this, 'CloudFrontDomainName', { + resourceType: 'Custom::UserPoolCloudFrontDomainName', + onCreate: sdkCall, + onUpdate: sdkCall, + policy: AwsCustomResourcePolicy.fromSdkCalls({ + // DescribeUserPoolDomain only supports access level '*' + // https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazoncognitouserpools.html#amazoncognitouserpools-actions-as-permissions + resources: [ '*' ], + }), + }); + return customResource.getResponseField('DomainDescription.CloudFrontDistribution'); + } +} diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts index 8d73b9aa1f04a..b8ba8176be0a9 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts @@ -4,6 +4,7 @@ import { Construct, Duration, IResource, Lazy, Resource, Stack } from '@aws-cdk/ import { CfnUserPool } from './cognito.generated'; import { ICustomAttribute, RequiredAttributes } from './user-pool-attr'; import { IUserPoolClient, UserPoolClient, UserPoolClientOptions } from './user-pool-client'; +import { UserPoolDomain, UserPoolDomainOptions } from './user-pool-domain'; /** * The different ways in which users of this pool can sign up or sign in. @@ -658,6 +659,10 @@ export class UserPool extends Resource implements IUserPool { (this.triggers as any)[operation.operationName] = fn.functionArn; } + /** + * Add a new app client to this user pool. + * @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html + */ public addClient(id: string, options?: UserPoolClientOptions): IUserPoolClient { return new UserPoolClient(this, id, { userPool: this, @@ -665,6 +670,17 @@ export class UserPool extends Resource implements IUserPool { }); } + /** + * Associate a domain to this user pool. + * @see https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-assign-domain.html + */ + public addDomain(id: string, options: UserPoolDomainOptions): UserPoolDomain { + return new UserPoolDomain(this, id, { + userPool: this, + ...options, + }); + } + private addLambdaPermission(fn: lambda.IFunction, name: string): void { const capitalize = name.charAt(0).toUpperCase() + name.slice(1); fn.addPermission(`${capitalize}Cognito`, { diff --git a/packages/@aws-cdk/aws-cognito/package.json b/packages/@aws-cdk/aws-cognito/package.json index 120d28fb32dd3..e5306e9881b24 100644 --- a/packages/@aws-cdk/aws-cognito/package.json +++ b/packages/@aws-cdk/aws-cognito/package.json @@ -72,16 +72,20 @@ "pkglint": "0.0.0" }, "dependencies": { + "@aws-cdk/aws-certificatemanager": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/core": "0.0.0", + "@aws-cdk/custom-resources": "0.0.0", "constructs": "^3.0.2" }, "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { + "@aws-cdk/aws-certificatemanager": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/core": "0.0.0", + "@aws-cdk/custom-resources": "0.0.0", "constructs": "^3.0.2" }, "jest": {}, @@ -91,7 +95,8 @@ "awslint": { "exclude": [ "attribute-tag:@aws-cdk/aws-cognito.UserPoolClient.userPoolClientName", - "resource-attribute:@aws-cdk/aws-cognito.UserPoolClient.userPoolClientClientSecret" + "resource-attribute:@aws-cdk/aws-cognito.UserPoolClient.userPoolClientClientSecret", + "props-physical-name:@aws-cdk/aws-cognito.UserPoolDomainProps" ] }, "stability": "experimental", diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explcit-props.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.expected.json similarity index 100% rename from packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explcit-props.expected.json rename to packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.expected.json diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explcit-props.ts b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.ts similarity index 100% rename from packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explcit-props.ts rename to packages/@aws-cdk/aws-cognito/test/integ.user-pool-client-explicit-props.ts diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.expected.json new file mode 100644 index 0000000000000..b1e726042529a --- /dev/null +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.expected.json @@ -0,0 +1,254 @@ +{ + "Resources": { + "UserPoolsmsRole4EA729DD": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "sts:ExternalId": "integuserpooldomaincfdistUserPool17475E8A" + } + }, + "Effect": "Allow", + "Principal": { + "Service": "cognito-idp.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "sns:Publish", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "sns-publish" + } + ] + } + }, + "UserPool6BA7E5F2": { + "Type": "AWS::Cognito::UserPool", + "Properties": { + "AdminCreateUserConfig": { + "AllowAdminCreateUserOnly": true + }, + "EmailVerificationMessage": "Hello {username}, Your verification code is {####}", + "EmailVerificationSubject": "Verify your new account", + "SmsConfiguration": { + "ExternalId": "integuserpooldomaincfdistUserPool17475E8A", + "SnsCallerArn": { + "Fn::GetAtt": [ + "UserPoolsmsRole4EA729DD", + "Arn" + ] + } + }, + "SmsVerificationMessage": "The verification code to your new account is {####}", + "VerificationMessageTemplate": { + "DefaultEmailOption": "CONFIRM_WITH_CODE", + "EmailMessage": "Hello {username}, Your verification code is {####}", + "EmailSubject": "Verify your new account", + "SmsMessage": "The verification code to your new account is {####}" + } + } + }, + "UserPoolDomainD0EA232A": { + "Type": "AWS::Cognito::UserPoolDomain", + "Properties": { + "Domain": "cdk-integ-user-pool-domain", + "UserPoolId": { + "Ref": "UserPool6BA7E5F2" + } + } + }, + "UserPoolDomainCloudFrontDomainNameE213E594": { + "Type": "Custom::UserPoolCloudFrontDomainName", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "AWS679f53fac002430cb0da5b7982bd22872D164C4C", + "Arn" + ] + }, + "Create": { + "service": "CognitoIdentityServiceProvider", + "action": "describeUserPoolDomain", + "parameters": { + "Domain": { + "Ref": "UserPoolDomainD0EA232A" + } + }, + "physicalResourceId": { + "id": { + "Ref": "UserPoolDomainD0EA232A" + } + } + }, + "Update": { + "service": "CognitoIdentityServiceProvider", + "action": "describeUserPoolDomain", + "parameters": { + "Domain": { + "Ref": "UserPoolDomainD0EA232A" + } + }, + "physicalResourceId": { + "id": { + "Ref": "UserPoolDomainD0EA232A" + } + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleDefaultPolicyD28E1A5E": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "cognito-idp:DescribeUserPoolDomain", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleDefaultPolicyD28E1A5E", + "Roles": [ + { + "Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + } + ] + } + }, + "AWS679f53fac002430cb0da5b7982bd22872D164C4C": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5bS3BucketA3488101" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5bS3VersionKey23A2E46C" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5bS3VersionKey23A2E46C" + } + ] + } + ] + } + ] + ] + } + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2", + "Arn" + ] + }, + "Runtime": "nodejs12.x", + "Timeout": 120 + }, + "DependsOn": [ + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleDefaultPolicyD28E1A5E", + "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2" + ] + } + }, + "Outputs": { + "Domain": { + "Value": { + "Ref": "UserPoolDomainD0EA232A" + } + }, + "CloudFrontDomainName": { + "Value": { + "Fn::GetAtt": [ + "UserPoolDomainCloudFrontDomainNameE213E594", + "DomainDescription.CloudFrontDistribution" + ] + } + } + }, + "Parameters": { + "AssetParameters0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5bS3BucketA3488101": { + "Type": "String", + "Description": "S3 bucket for asset \"0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5b\"" + }, + "AssetParameters0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5bS3VersionKey23A2E46C": { + "Type": "String", + "Description": "S3 key for asset version \"0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5b\"" + }, + "AssetParameters0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5bArtifactHashF6409D44": { + "Type": "String", + "Description": "Artifact hash for asset \"0317970d7c7695dbb9076b70f5eaa0a840dabe9a56c3389439ae5018b5a4cc5b\"" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.ts b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.ts new file mode 100644 index 0000000000000..abde60a7cd12c --- /dev/null +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-domain-cfdist.ts @@ -0,0 +1,26 @@ +import { App, CfnOutput, Stack } from '@aws-cdk/core'; +import { UserPool } from '../lib'; + +/* + * Stack verification steps: + * * Verify that the CloudFrontDistribution stack output is of the format 'xxxxxxxxxxxxxx.cloudfront.net' + */ + +const app = new App(); +const stack = new Stack(app, 'integ-user-pool-domain-cfdist'); + +const userpool = new UserPool(stack, 'UserPool'); + +const domain = userpool.addDomain('Domain', { + cognitoDomain: { + domainPrefix: 'cdk-integ-user-pool-domain', + }, +}); + +new CfnOutput(stack, 'Domain', { + value: domain.domainName, +}); + +new CfnOutput(stack, 'CloudFrontDomainName', { + value: domain.cloudFrontDomainName, +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-explicit-props.expected.json b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-explicit-props.expected.json index 04093296c5700..82f29c93ead24 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-explicit-props.expected.json +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-explicit-props.expected.json @@ -838,6 +838,15 @@ "SmsMessage": "verification sms message from the integ test. Code is {####}." } } + }, + "myuserpoolmyuserpooldomainEE1E11AF": { + "Type": "AWS::Cognito::UserPoolDomain", + "Properties": { + "Domain": "myawesomeapp", + "UserPoolId": { + "Ref": "myuserpool01998219" + } + } } }, "Outputs": { @@ -845,6 +854,23 @@ "Value": { "Ref": "myuserpool01998219" } + }, + "cognitoDomainName": { + "Value": { + "Fn::Join": [ + "", + [ + { + "Ref": "myuserpoolmyuserpooldomainEE1E11AF" + }, + ".auth.", + { + "Ref": "AWS::Region" + }, + ".amazoncognito.com" + ] + ] + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-explicit-props.ts b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-explicit-props.ts index 9f35ba7405d82..262fbb8670638 100644 --- a/packages/@aws-cdk/aws-cognito/test/integ.user-pool-explicit-props.ts +++ b/packages/@aws-cdk/aws-cognito/test/integ.user-pool-explicit-props.ts @@ -69,10 +69,20 @@ const userpool = new UserPool(stack, 'myuserpool', { }, }); +const cognitoDomain = userpool.addDomain('myuserpooldomain', { + cognitoDomain: { + domainPrefix: 'myawesomeapp', + }, +}); + new CfnOutput(stack, 'userpoolId', { value: userpool.userPoolId, }); +new CfnOutput(stack, 'cognitoDomainName', { + value: `${cognitoDomain.domainName}.auth.${stack.region}.amazoncognito.com`, +}); + function dummyTrigger(name: string): IFunction { return new Function(stack, name, { functionName: name, diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts new file mode 100644 index 0000000000000..8aa2a7972732b --- /dev/null +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts @@ -0,0 +1,128 @@ +import '@aws-cdk/assert/jest'; +import { Certificate } from '@aws-cdk/aws-certificatemanager'; +import { Stack } from '@aws-cdk/core'; +import { UserPool, UserPoolDomain } from '../lib'; + +describe('User Pool Client', () => { + test('custom domain name', () => { + // GIVEN + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + + // WHEN + const certificate = Certificate.fromCertificateArn(stack, 'cert', + 'arn:aws:acm:eu-west-1:0123456789:certificate/7ec3e4ac-808a-4649-b805-66ae02346ad8'); + new UserPoolDomain(stack, 'Domain', { + userPool: pool, + customDomain: { + domainName: 'test-domain.example.com', + certificate, + }, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPoolDomain', { + UserPoolId: stack.resolve(pool.userPoolId), + Domain: 'test-domain.example.com', + CustomDomainConfig: { + CertificateArn: 'arn:aws:acm:eu-west-1:0123456789:certificate/7ec3e4ac-808a-4649-b805-66ae02346ad8', + }, + }); + }); + + test('cognito domain prefix', () => { + // GIVEN + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + + // WHEN + new UserPoolDomain(stack, 'Domain', { + userPool: pool, + cognitoDomain: { + domainPrefix: 'cognito-domain-prefix', + }, + }); + + // THEN + expect(stack).toHaveResource('AWS::Cognito::UserPoolDomain', { + UserPoolId: stack.resolve(pool.userPoolId), + Domain: 'cognito-domain-prefix', + }); + }); + + test('fails when neither cognitoDomain nor customDomain are specified', () => { + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + const certificate = Certificate.fromCertificateArn(stack, 'cert', + 'arn:aws:acm:eu-west-1:0123456789:certificate/7ec3e4ac-808a-4649-b805-66ae02346ad8'); + + expect(() => new UserPoolDomain(stack, 'Domain', { + userPool: pool, + cognitoDomain: { + domainPrefix: 'cognito-domain-prefix', + }, + customDomain: { + domainName: 'mydomain.com', + certificate, + }, + })).toThrow(/cognitoDomain or customDomain must be specified/); + }); + + test('fails when both cognitoDomain and customDomain are specified', () => { + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + + expect(() => new UserPoolDomain(stack, 'Domain', { + userPool: pool, + })).toThrow(/cognitoDomain or customDomain must be specified/); + }); + + test('fails when domainPrefix has characters outside the allowed charset', () => { + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + + expect(() => pool.addDomain('Domain1', { + cognitoDomain: { domainPrefix: 'domain.prefix' }, + })).toThrow(/lowercase alphabets, numbers and hyphens/); + expect(() => pool.addDomain('Domain2', { + cognitoDomain: { domainPrefix: 'Domain-Prefix' }, + })).toThrow(/lowercase alphabets, numbers and hyphens/); + expect(() => pool.addDomain('Domain3', { + cognitoDomain: { domainPrefix: 'dómäin-prefix' }, + })).toThrow(/lowercase alphabets, numbers and hyphens/); + }); + + test('custom resource is added when cloudFrontDistribution method is called', () => { + // GIVEN + const stack = new Stack(); + const pool = new UserPool(stack, 'Pool'); + const domain = pool.addDomain('Domain', { + cognitoDomain: { + domainPrefix: 'cognito-domain-prefix', + }, + }); + + // WHEN + const cfDomainName = domain.cloudFrontDomainName; + + // THEN + expect(stack.resolve(cfDomainName)).toEqual({ + 'Fn::GetAtt': [ + 'PoolDomainCloudFrontDomainName340BF87E', + 'DomainDescription.CloudFrontDistribution', + ], + }); + + expect(stack).toHaveResource('Custom::UserPoolCloudFrontDomainName'); + expect(stack).toHaveResource('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [{ + Action: 'cognito-idp:DescribeUserPoolDomain', + Effect: 'Allow', + Resource: '*', + }], + Version: '2012-10-17', + }, + }); + }); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-route53-targets/README.md b/packages/@aws-cdk/aws-route53-targets/README.md index a3679ddfc8bff..e3e8f99a0e5ba 100644 --- a/packages/@aws-cdk/aws-route53-targets/README.md +++ b/packages/@aws-cdk/aws-route53-targets/README.md @@ -48,7 +48,7 @@ This library contains Route53 Alias Record targets for: target: route53.RecordTarget.fromAlias(new alias.InterfaceVpcEndpointTarget(interfaceVpcEndpoint)) }); ``` -* S3 Bucket WebSite: +* S3 Bucket Website: **Important:** The Bucket name must strictly match the full DNS name. See [the Developer Guide](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started.html) for more info. @@ -69,5 +69,12 @@ See [the Developer Guide](https://docs.aws.amazon.com/Route53/latest/DeveloperGu target: route53.RecordTarget.fromAlias(new alias.BucketWebsiteTarget(bucket)), }); ``` +* User pool domain + ```ts + new route53.ARecord(this, 'AliasRecord', { + zone, + target: route53.RecordTarget.fromAlias(new alias.UserPoolDomainTarget(domain)), + }); + ``` See the documentation of `@aws-cdk/aws-route53` for more information. diff --git a/packages/@aws-cdk/aws-route53-targets/lib/cloudfront-target.ts b/packages/@aws-cdk/aws-route53-targets/lib/cloudfront-target.ts index a09a926ad7230..bb765702f5c87 100644 --- a/packages/@aws-cdk/aws-route53-targets/lib/cloudfront-target.ts +++ b/packages/@aws-cdk/aws-route53-targets/lib/cloudfront-target.ts @@ -1,22 +1,22 @@ import * as cloudfront from '@aws-cdk/aws-cloudfront'; import * as route53 from '@aws-cdk/aws-route53'; -/** - * The hosted zone Id if using an alias record in Route53. - * This value never changes. - */ -const CLOUDFRONT_ZONE_ID = 'Z2FDTNDATAQYW2'; - /** * Use a CloudFront Distribution as an alias record target */ export class CloudFrontTarget implements route53.IAliasRecordTarget { + /** + * The hosted zone Id if using an alias record in Route53. + * This value never changes. + */ + public static readonly CLOUDFRONT_ZONE_ID = 'Z2FDTNDATAQYW2'; + constructor(private readonly distribution: cloudfront.CloudFrontWebDistribution) { } public bind(_record: route53.IRecordSet): route53.AliasRecordTargetConfig { return { - hostedZoneId: CLOUDFRONT_ZONE_ID, + hostedZoneId: CloudFrontTarget.CLOUDFRONT_ZONE_ID, dnsName: this.distribution.domainName, }; } diff --git a/packages/@aws-cdk/aws-route53-targets/lib/index.ts b/packages/@aws-cdk/aws-route53-targets/lib/index.ts index 673f2e881f27d..6df1bd67d6037 100644 --- a/packages/@aws-cdk/aws-route53-targets/lib/index.ts +++ b/packages/@aws-cdk/aws-route53-targets/lib/index.ts @@ -4,3 +4,4 @@ export * from './classic-load-balancer-target'; export * from './cloudfront-target'; export * from './load-balancer-target'; export * from './interface-vpc-endpoint-target'; +export * from './userpool-domain'; diff --git a/packages/@aws-cdk/aws-route53-targets/lib/userpool-domain.ts b/packages/@aws-cdk/aws-route53-targets/lib/userpool-domain.ts new file mode 100644 index 0000000000000..f3b9f0a550ff1 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-targets/lib/userpool-domain.ts @@ -0,0 +1,18 @@ +import { UserPoolDomain } from '@aws-cdk/aws-cognito'; +import { AliasRecordTargetConfig, IAliasRecordTarget, IRecordSet } from '@aws-cdk/aws-route53'; +import { CloudFrontTarget } from './cloudfront-target'; + +/** + * Use a user pool domain as an alias record target + */ +export class UserPoolDomainTarget implements IAliasRecordTarget { + constructor(private readonly domain: UserPoolDomain) { + } + + public bind(_record: IRecordSet): AliasRecordTargetConfig { + return { + dnsName: this.domain.cloudFrontDomainName, + hostedZoneId: CloudFrontTarget.CLOUDFRONT_ZONE_ID, + }; + } +} diff --git a/packages/@aws-cdk/aws-route53-targets/package.json b/packages/@aws-cdk/aws-route53-targets/package.json index 43a960edb20fd..e80557c257da3 100644 --- a/packages/@aws-cdk/aws-route53-targets/package.json +++ b/packages/@aws-cdk/aws-route53-targets/package.json @@ -88,6 +88,7 @@ "dependencies": { "@aws-cdk/aws-apigateway": "0.0.0", "@aws-cdk/aws-cloudfront": "0.0.0", + "@aws-cdk/aws-cognito": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-elasticloadbalancing": "0.0.0", "@aws-cdk/aws-elasticloadbalancingv2": "0.0.0", @@ -102,6 +103,7 @@ "peerDependencies": { "@aws-cdk/aws-apigateway": "0.0.0", "@aws-cdk/aws-cloudfront": "0.0.0", + "@aws-cdk/aws-cognito": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-elasticloadbalancing": "0.0.0", "@aws-cdk/aws-elasticloadbalancingv2": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53-targets/test/userpool-domain.test.ts b/packages/@aws-cdk/aws-route53-targets/test/userpool-domain.test.ts new file mode 100644 index 0000000000000..9c8655a0e2e69 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-targets/test/userpool-domain.test.ts @@ -0,0 +1,33 @@ +import '@aws-cdk/assert/jest'; +import { UserPool, UserPoolDomain } from '@aws-cdk/aws-cognito'; +import { ARecord, PublicHostedZone, RecordTarget } from '@aws-cdk/aws-route53'; +import { Stack } from '@aws-cdk/core'; +import { UserPoolDomainTarget } from '../lib'; + +test('use user pool domain as record target', () => { + // GIVEN + const stack = new Stack(); + const zone = new PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' }); + const userPool = new UserPool(stack, 'UserPool'); + const domain = new UserPoolDomain(stack, 'UserPoolDomain', { + userPool, + cognitoDomain: { domainPrefix: 'domain-prefix' }, + }); + + // WHEN + new ARecord(zone, 'Alias', { + zone, + target: RecordTarget.fromAlias(new UserPoolDomainTarget(domain)), + }); + + // THEN + expect(stack).toHaveResource('AWS::Route53::RecordSet', { + AliasTarget: { + DNSName: { 'Fn::GetAtt': [ + 'UserPoolDomainCloudFrontDomainName0B254952', + 'DomainDescription.CloudFrontDistribution', + ] }, + HostedZoneId: 'Z2FDTNDATAQYW2', + }, + }); +}); \ No newline at end of file From 51aecde8a662528112eb88f90aa7cf06c49b48ae Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Wed, 22 Apr 2020 02:52:42 -0700 Subject: [PATCH 08/28] chore(route53-patterns): clear linter exclusions (#7489) --- .../@aws-cdk/aws-route53-patterns/lib/website-redirect.ts | 7 +++++++ packages/@aws-cdk/aws-route53-patterns/package.json | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk/aws-route53-patterns/lib/website-redirect.ts b/packages/@aws-cdk/aws-route53-patterns/lib/website-redirect.ts index bf45dd7c9cb8d..7fd4b85f8d4f6 100644 --- a/packages/@aws-cdk/aws-route53-patterns/lib/website-redirect.ts +++ b/packages/@aws-cdk/aws-route53-patterns/lib/website-redirect.ts @@ -6,6 +6,9 @@ import { Bucket, RedirectProtocol } from '@aws-cdk/aws-s3'; import { Construct, RemovalPolicy } from '@aws-cdk/core'; import * as crypto from 'crypto'; +/** + * Properties to configure an HTTPS Redirect + */ export interface HttpsRedirectProps { /** * HostedZone of the domain @@ -29,6 +32,10 @@ export interface HttpsRedirectProps { readonly certificate?: ICertificate; } +/** + * Allows creating a domainA -> domainB redirect using CloudFront and S3. + * You can specify multiple domains to be redirected. + */ export class HttpsRedirect extends Construct { constructor(scope: Construct, id: string, props: HttpsRedirectProps) { super(scope, id); diff --git a/packages/@aws-cdk/aws-route53-patterns/package.json b/packages/@aws-cdk/aws-route53-patterns/package.json index 9758b2b007bdf..4f2d979a4d519 100644 --- a/packages/@aws-cdk/aws-route53-patterns/package.json +++ b/packages/@aws-cdk/aws-route53-patterns/package.json @@ -111,12 +111,6 @@ }, "stability": "experimental", "maturity": "developer-preview", - "awslint": { - "exclude": [ - "docs-public-apis:@aws-cdk/aws-route53-patterns.HttpsRedirect", - "docs-public-apis:@aws-cdk/aws-route53-patterns.HttpsRedirectProps" - ] - }, "awscdkio": { "announce": false } From ac3b330c71ef258afd145b86fd90a06db5d1c990 Mon Sep 17 00:00:00 2001 From: andrestone Date: Wed, 22 Apr 2020 12:29:54 +0200 Subject: [PATCH 09/28] feat(stepfunctions): retrieve all reachable states from a given state in a state machine definition (#7324) A new method - `findReachableStates` - to retrieve all reachable states subsequent to a given initial state, including itself. Motivation With this method, developers can programatically modify their state definitions, given an initial state. For example, walk through the set of states and attach some of them to a 'ResumeTo' Choice state, so that state machine executions can jump directly to one of these states. closes #7256 --- packages/@aws-cdk/aws-stepfunctions/README.md | 4 ++ .../aws-stepfunctions/lib/states/state.ts | 21 +++++- .../test/states-language.test.ts | 72 +++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-stepfunctions/README.md b/packages/@aws-cdk/aws-stepfunctions/README.md index 6f92f68646923..534ce7e1f3aa1 100644 --- a/packages/@aws-cdk/aws-stepfunctions/README.md +++ b/packages/@aws-cdk/aws-stepfunctions/README.md @@ -728,6 +728,10 @@ new stepfunctions.Parallel(this, 'All jobs') .branch(new MyJob(this, 'Slow', { jobFlavor: 'slow' }).prefixStates()); ``` +A few utility functions are available to parse state machine fragments. +* `State.findReachableStates`: Retrieve the list of states reachable from a given state. +* `State.findReachableEndStates`: Retrieve the list of end or terminal states reachable from a given state. + ## Activity **Activities** represent work that is done on some non-Lambda worker pool. The diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts b/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts index e2df07b5d6fab..5f69d2af2d80b 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/states/state.ts @@ -73,10 +73,29 @@ export abstract class State extends cdk.Construct implements IChainable { } } + /** + * Find the set of states reachable through transitions from the given start state. + * This does not retrieve states from within sub-graphs, such as states within a Parallel state's branch. + */ + public static findReachableStates(start: State, options: FindStateOptions = {}): State[] { + const visited = new Set(); + const ret = new Set(); + const queue = [start]; + while (queue.length > 0) { + const state = queue.splice(0, 1)[0]!; + if (visited.has(state)) { continue; } + visited.add(state); + const outgoing = state.outgoingTransitions(options); + queue.push(...outgoing); + ret.add(state); + } + return Array.from(ret); + } + /** * Find the set of end states states reachable through transitions from the given start state */ - public static findReachableEndStates(start: State, options: FindStateOptions = {}) { + public static findReachableEndStates(start: State, options: FindStateOptions = {}): State[] { const visited = new Set(); const ret = new Set(); const queue = [start]; diff --git a/packages/@aws-cdk/aws-stepfunctions/test/states-language.test.ts b/packages/@aws-cdk/aws-stepfunctions/test/states-language.test.ts index 55adf75666207..de232deffd531 100644 --- a/packages/@aws-cdk/aws-stepfunctions/test/states-language.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions/test/states-language.test.ts @@ -614,6 +614,78 @@ describe('States Language', () => { expect(() => new stepfunctions.Parallel(stack, 'Parallel') .branch(state1.next(state2)) .branch(state2)).toThrow(); + }), + + describe('findReachableStates', () => { + + test('Can retrieve possible states from initial state', () => { + // GIVEN + const stack = new cdk.Stack(); + const state1 = new stepfunctions.Pass(stack, 'State1'); + const state2 = new stepfunctions.Pass(stack, 'State2'); + const state3 = new stepfunctions.Pass(stack, 'State3'); + + const definition = state1 + .next(state2) + .next(state3); + + // WHEN + const states = stepfunctions.State.findReachableStates(definition.startState); + + // THEN + expect(state1.id).toStrictEqual(states[0].id); + expect(state2.id).toStrictEqual(states[1].id); + expect(state3.id).toStrictEqual(states[2].id); + }); + + test('Does not retrieve unreachable states', () => { + // GIVEN + const stack = new cdk.Stack(); + const state1 = new stepfunctions.Pass(stack, 'State1'); + const state2 = new stepfunctions.Pass(stack, 'State2'); + const state3 = new stepfunctions.Pass(stack, 'State3'); + + state1.next(state2).next(state3); + + // WHEN + const states = stepfunctions.State.findReachableStates(state2); + + // THEN + expect(state2.id).toStrictEqual(states[0].id); + expect(state3.id).toStrictEqual(states[1].id); + expect(states.length).toStrictEqual(2); + }); + + test('Works with Choice and Parallel states', () => { + // GIVEN + const stack = new cdk.Stack(); + const state1 = new stepfunctions.Choice(stack, 'MainChoice'); + const stateCA = new stepfunctions.Pass(stack, 'StateA'); + const stateCB = new stepfunctions.Pass(stack, 'StateB'); + const statePA = new stepfunctions.Pass(stack, 'ParallelA'); + const statePB = new stepfunctions.Pass(stack, 'ParallelB'); + const state2 = new stepfunctions.Parallel(stack, 'RunParallel'); + const state3 = new stepfunctions.Pass(stack, 'FinalState'); + state2.branch(statePA); + state2.branch(statePB); + state1.when(stepfunctions.Condition.stringEquals('$.myInput', 'A' ), stateCA); + state1.when(stepfunctions.Condition.stringEquals('$.myInput', 'B'), stateCB); + stateCA.next(state2); + state2.next(state3); + + const definition = state1.otherwise(stateCA); + + // WHEN + const statesFromStateCB = stepfunctions.State.findReachableStates(stateCB); + const statesFromState1 = stepfunctions.State.findReachableStates(definition); + + // THEN + const expectedFromState1 = [state1, stateCA, stateCB, state2, state3]; + for (let i = 0; i < expectedFromState1.length; i++) { + expect(statesFromState1[i].id).toStrictEqual(expectedFromState1[i].id); + } + expect(statesFromStateCB[0].id).toStrictEqual(stateCB.id); + }); }); }); From 8f614e4bbbe02170f2ddfbbdd19f4feb19761bca Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 22 Apr 2020 16:40:40 +0200 Subject: [PATCH 10/28] chore: shrinkwrap CLI and cdk-assets tools The CLI and the `cdk-assets` tool present a security risk as they're being downloaded from NPM, as any of their dependencies can be compromised at any time and downloaded to any user's machine without a lockfile. Generate a lockfile (`npm-shrinkwrap.json`) that will be respected by NPM upon install. --- .../@aws-cdk/custom-resources/package.json | 2 +- packages/aws-cdk/.gitignore | 3 + packages/aws-cdk/package.json | 3 + .../test/integ/init/test-typescript.sh | 2 +- .../aws-cdk/test/integ/run-against-dist.bash | 129 +-- packages/cdk-assets/.gitignore | 1 + packages/cdk-assets/package.json | 3 + scripts/align-version.sh | 12 +- tools/cdk-build-tools/bin/cdk-package.ts | 10 + tools/cdk-build-tools/package.json | 3 +- tools/yarn-cling/.gitignore | 7 + tools/yarn-cling/.npmignore | 9 + tools/yarn-cling/LICENSE | 201 ++++ tools/yarn-cling/NOTICE | 2 + tools/yarn-cling/README.md | 78 ++ tools/yarn-cling/bin/yarn-cling | 2 + tools/yarn-cling/bin/yarn-cling.ts | 18 + tools/yarn-cling/lib/hoisting.ts | 51 ++ tools/yarn-cling/lib/index.ts | 153 ++++ tools/yarn-cling/lib/types.ts | 58 ++ tools/yarn-cling/package.json | 65 ++ tools/yarn-cling/test/cling.test.ts | 68 ++ tools/yarn-cling/test/hoisting.test.ts | 138 +++ tools/yarn-cling/test/test-fixture/.gitignore | 1 + .../package1/node_modules/package2 | 1 + .../registrydependency1/package.json | 7 + .../registrydependency2/package.json | 4 + .../test/test-fixture/package1/package.json | 8 + .../test/test-fixture/package2/package.json | 4 + tools/yarn-cling/test/test-fixture/yarn.lock | 9 + tools/yarn-cling/tsconfig.json | 20 + yarn.lock | 867 +++++++++++++++++- 32 files changed, 1792 insertions(+), 147 deletions(-) create mode 100644 tools/yarn-cling/.gitignore create mode 100644 tools/yarn-cling/.npmignore create mode 100644 tools/yarn-cling/LICENSE create mode 100644 tools/yarn-cling/NOTICE create mode 100644 tools/yarn-cling/README.md create mode 100755 tools/yarn-cling/bin/yarn-cling create mode 100644 tools/yarn-cling/bin/yarn-cling.ts create mode 100644 tools/yarn-cling/lib/hoisting.ts create mode 100644 tools/yarn-cling/lib/index.ts create mode 100644 tools/yarn-cling/lib/types.ts create mode 100644 tools/yarn-cling/package.json create mode 100644 tools/yarn-cling/test/cling.test.ts create mode 100644 tools/yarn-cling/test/hoisting.test.ts create mode 100644 tools/yarn-cling/test/test-fixture/.gitignore create mode 120000 tools/yarn-cling/test/test-fixture/package1/node_modules/package2 create mode 100644 tools/yarn-cling/test/test-fixture/package1/node_modules/registrydependency1/package.json create mode 100644 tools/yarn-cling/test/test-fixture/package1/node_modules/registrydependency2/package.json create mode 100644 tools/yarn-cling/test/test-fixture/package1/package.json create mode 100644 tools/yarn-cling/test/test-fixture/package2/package.json create mode 100644 tools/yarn-cling/test/test-fixture/yarn.lock create mode 100644 tools/yarn-cling/tsconfig.json diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index e8e36478b5fba..a0ceafa94114c 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -48,7 +48,7 @@ }, "cdk-build": { "pre": [ - "cp -f $(node -p 'require.resolve(\"aws-sdk/apis/metadata.json\")') lib/aws-custom-resource/sdk-api-metadata.json" + "cp -f $(node -p 'require.resolve(\"aws-sdk/apis/metadata.json\")') lib/aws-custom-resource/sdk-api-metadata.json && rm -rf test/aws-custom-resource/cdk.out" ] }, "keywords": [ diff --git a/packages/aws-cdk/.gitignore b/packages/aws-cdk/.gitignore index 210a11867f7cf..39e42b7816d39 100644 --- a/packages/aws-cdk/.gitignore +++ b/packages/aws-cdk/.gitignore @@ -17,6 +17,9 @@ nyc.config.js !test/integ/run-wrappers/dist !test/integ/cli/**/* +npm-shrinkwrap.json +# Might be created when running regression tests. +# But normally should be deleted after execution. test/integ/cli-backwards-tests-* !.eslintrc.js diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 0b9536c028795..017758e372b5e 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -27,6 +27,9 @@ "./generate.sh" ] }, + "cdk-package": { + "shrinkWrap": true + }, "author": { "name": "Amazon Web Services", "url": "https://aws.amazon.com", diff --git a/packages/aws-cdk/test/integ/init/test-typescript.sh b/packages/aws-cdk/test/integ/init/test-typescript.sh index 67a6cb2920729..14fa77d4463dd 100755 --- a/packages/aws-cdk/test/integ/init/test-typescript.sh +++ b/packages/aws-cdk/test/integ/init/test-typescript.sh @@ -22,7 +22,7 @@ for template in $templates; do setup cdk init -l typescript $template - npm ls # this will fail if we have unmet peer dependencies + npm prune && npm ls # this will fail if we have unmet peer dependencies npm run build npm run test diff --git a/packages/aws-cdk/test/integ/run-against-dist.bash b/packages/aws-cdk/test/integ/run-against-dist.bash index 1d0573ed688e1..d429bb3bee446 100644 --- a/packages/aws-cdk/test/integ/run-against-dist.bash +++ b/packages/aws-cdk/test/integ/run-against-dist.bash @@ -16,10 +16,9 @@ function header() { } function serve_npm_packages() { - if [ -n "${VERDACCIO_PID:-}" ]; then - log >&2 "verdaccio is already running" - use_verdaccio - return + if [ -n "${SERVE_NPM_TARBALLS_PID:-}" ]; then + log >&2 "Verdaccio is already running" + return 1 fi if [ ! -z "${USE_PUBLISHED_FRAMEWORK_VERSION:-}" ]; then @@ -29,7 +28,7 @@ function serve_npm_packages() { # when using latest published framework, only # install the cli and its dependencies. - cli_root=./package + cli_root=./package version=$(node -p "require('${cli_root}/package.json').version") @@ -37,138 +36,44 @@ function serve_npm_packages() { echo "Fetching @aws-cdk CLI dependencies from package.json" cli_deps=$(node -p "Object.entries(require('${cli_root}/package.json').dependencies).filter(x => x[0].includes('@aws-cdk')).map(x => x[0].replace('@aws-cdk/', '')).join(' ')") - tarballs=$dist_root/js/aws-cdk-${version}.tgz - package_names="aws-cdk" + # tarballs_glob is going to look like "{file,file,...}" + tarballs_glob="{$dist_root/js/aws-cdk-${version}.tgz" for dep in ${cli_deps}; do tarball=$dist_root/js/${dep}@${version}.jsii.tgz - package=@aws-cdk/${dep} if [ ! -f ${tarball} ]; then # not a jsii dependency, the tarball is different... - tarball=$dist_root/js/aws-cdk-${dep}-${version}.tgz - fi + tarball=$dist_root/js/aws-cdk-${dep}-${version}.tgz + fi - tarballs="${tarballs} ${tarball}" - package_names="${package_names} ${package}" + tarballs_glob="${tarballs_glob},${tarball}" done - # manually add cdk-assets since its not prefixed with @aws-cdk and + # manually add cdk-assets since its not prefixed with @aws-cdk and # hence isn't picked up from package.json echo "Adding cdk-assets to CLI dependencies" - tarballs="${tarballs} $dist_root/js/cdk-assets-${version}.tgz" - package_names="${package_names} cdk-assets" + tarballs_glob="${tarballs_glob},$dist_root/js/cdk-assets-${version}.tgz" # manually add @aws-cdk/cfnspec since its a transitive dependency via @aws-cdk/cloudformation-diff # hence isn't picked up from package.json echo "Adding @aws-cdk/cfnspec to CLI dependencies" - tarballs="${tarballs} $dist_root/js/aws-cdk-cfnspec-${version}.tgz" - package_names="${package_names} @aws-cdk/cfnspec" + tarballs_glob="${tarballs_glob},$dist_root/js/aws-cdk-cfnspec-${version}.tgz" + tarballs_glob="${tarballs_glob}}" else echo "Testing against local versions of the framework" - - tarballs=$dist_root/js/*.tgz - - log "Discovering local package names..." - # Read the package names from each tarball, so that we can generate - # a Verdaccio config that will keep each of these packages locally - # and not go to NPMJS for it. - package_names="" - for tgz in $tarballs; do - name=$(node -pe 'JSON.parse(process.argv[1]).name' "$(tar xOzf $tgz package/package.json)") - package_names="$package_names $name" - done - + tarballs_glob="$dist_root/js/*.tgz" fi #------------------------------------------------------------------------------ - # Start a local npm repository and install the CDK from the distribution to it + # Start a mock npm repository from the given tarballs #------------------------------------------------------------------------------ header "Starting local NPM Repository" - local verdaccio_config="${npmws}/config.yaml" - - verdacciobin=$(type -p verdaccio) || { - (cd $npmws && npm install --no-save verdaccio) - verdacciobin=$npmws/node_modules/.bin/verdaccio - } - - # start consumer verdaccio with npm - header "Starting verdaccio (with npm uplink)" - write_verdaccio_config "${verdaccio_config}" "$package_names" - $verdacciobin --config "${verdaccio_config}" & - local pid=$! - trap "echo 'shutting down verdaccio'; kill ${pid} || true" EXIT - log >&2 "waiting for verdaccio to start..." - sleep 1 - log "consumer verdaccio pid: ${pid}" - - export VERDACCIO_PID=$pid - - use_verdaccio - - log "Publishing NPM tarballs..." - for tgz in $tarballs; do - # Doesn't matter what directory it is, just shouldn't be the - # aws-cdk package directory. - (cd $npmws && npm --quiet publish $tgz) - done - -} - -function write_verdaccio_config() { - local verdaccio_config="$1" - local packages="${2:-}" - - cat > "${verdaccio_config}" <> "${verdaccio_config}" <> "${verdaccio_config}" <&2 ${verdaccio_config} -} - -function use_verdaccio() { - log >&2 "configuring npm to use verdaccio" - - # Token MUST be passed via .npmrc: https://github.com/npm/npm/issues/15565 - export npm_config_userconfig="${npmws}/.npmrc" - echo "//localhost:4873/:_authToken=none" >> ${npm_config_userconfig} - echo "" >> ${npm_config_userconfig} - - # Pass registry via environment variable, so that if this script gets run via 'npm run' - # and all $npm_config_xxx settings are passed via environment variables, we still - # get to override it (the file would normally be ignored in that case). - export npm_config_registry=http://localhost:4873/ + eval $(npx serve-npm-tarballs --glob "${tarballs_glob}" --daemon) + trap "kill $SERVE_NPM_TARBALLS_PID" EXIT } - # Make sure that installed CLI matches the build version function verify_installed_cli_version() { local expected_version="$(node -e "console.log(require('${dist_root}/build.json').version)")" diff --git a/packages/cdk-assets/.gitignore b/packages/cdk-assets/.gitignore index 9fcdcd500a5e0..7cf80fa42feb7 100644 --- a/packages/cdk-assets/.gitignore +++ b/packages/cdk-assets/.gitignore @@ -19,4 +19,5 @@ nyc.config.js !test/integ/cli/**/* .* assets.json +npm-shrinkwrap.json !.eslintrc.js diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index 4b1eccc76cfcd..4f5df0ef088b1 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -61,6 +61,9 @@ "engines": { "node": ">= 10.12.0" }, + "cdk-package": { + "shrinkWrap": true + }, "stability": "experimental", "maturity": "experimental", "jest": { diff --git a/scripts/align-version.sh b/scripts/align-version.sh index 2e6d00798e7f3..6ab4f97be95af 100755 --- a/scripts/align-version.sh +++ b/scripts/align-version.sh @@ -9,12 +9,20 @@ scriptdir=$(cd $(dirname $0) && pwd) # go to repo root cd ${scriptdir}/.. -files="$(find . -name package.json | grep -v node_modules | xargs)" +files="./package.json $(npx lerna ls -p -a | xargs -n1 -I@ echo @/package.json)" ${scriptdir}/align-version.js ${files} # validation marker=$(node -p "require('./scripts/get-version-marker').replace(/\./g, '\\\.')") -if find . -name package.json | grep -v node_modules | xargs grep -E "\"[\^~]?${marker}\""; then + +# Get a list of all package.json files. None of them shouldn contain 0.0.0 anymore. +# Exclude a couple of specific ones that we don't care about. +package_jsons=$(find . -name package.json |\ + grep -v node_modules |\ + grep -v packages/decdk/test/fixture/package.json |\ + grep -v .github/actions/prlinter/package.json) + +if grep -l "[^0-9]${marker}" $package_jsons; then echo "ERROR: unexpected version marker ${marker} in a package.json file" exit 1 fi diff --git a/tools/cdk-build-tools/bin/cdk-package.ts b/tools/cdk-build-tools/bin/cdk-package.ts index e6b814d5e3244..9ae3600a4babe 100644 --- a/tools/cdk-build-tools/bin/cdk-package.ts +++ b/tools/cdk-build-tools/bin/cdk-package.ts @@ -1,6 +1,7 @@ import * as fs from 'fs-extra'; import * as path from 'path'; import * as yargs from 'yargs'; +import * as yarnCling from 'yarn-cling'; import { shell } from '../lib/os'; import { Timers } from '../lib/timer'; @@ -31,6 +32,15 @@ async function main() { return; } + // If we need to shrinkwrap this, do so now. + const packageOptions = pkg['cdk-package'] ?? {}; + if (packageOptions.shrinkWrap) { + await yarnCling.generateShrinkwrap({ + packageJsonFile: 'package.json', + outputFile: 'npm-shrinkwrap.json', + }); + } + if (pkg.jsii) { const command = [args['jsii-pacmak'], args.verbose ? '-vvv' : '-v', diff --git a/tools/cdk-build-tools/package.json b/tools/cdk-build-tools/package.json index 404d013974e8f..2f54ebf8482d3 100644 --- a/tools/cdk-build-tools/package.json +++ b/tools/cdk-build-tools/package.json @@ -56,7 +56,8 @@ "ts-jest": "^25.4.0", "tslint": "^5.20.1", "typescript": "~3.8.3", - "yargs": "^15.3.1" + "yargs": "^15.3.1", + "yarn-cling": "0.0.0" }, "keywords": [ "aws", diff --git a/tools/yarn-cling/.gitignore b/tools/yarn-cling/.gitignore new file mode 100644 index 0000000000000..0f18fe477a6f5 --- /dev/null +++ b/tools/yarn-cling/.gitignore @@ -0,0 +1,7 @@ +*.js +*.js.map +*.d.ts +dist + +.LAST_BUILD +*.snk \ No newline at end of file diff --git a/tools/yarn-cling/.npmignore b/tools/yarn-cling/.npmignore new file mode 100644 index 0000000000000..89a519f1e02fe --- /dev/null +++ b/tools/yarn-cling/.npmignore @@ -0,0 +1,9 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +.LAST_BUILD +*.snk \ No newline at end of file diff --git a/tools/yarn-cling/LICENSE b/tools/yarn-cling/LICENSE new file mode 100644 index 0000000000000..b71ec1688783a --- /dev/null +++ b/tools/yarn-cling/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/tools/yarn-cling/NOTICE b/tools/yarn-cling/NOTICE new file mode 100644 index 0000000000000..bfccac9a7f69c --- /dev/null +++ b/tools/yarn-cling/NOTICE @@ -0,0 +1,2 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/tools/yarn-cling/README.md b/tools/yarn-cling/README.md new file mode 100644 index 0000000000000..a89fcb712b40a --- /dev/null +++ b/tools/yarn-cling/README.md @@ -0,0 +1,78 @@ +# yarn-cling + +Generate an NPM shrinkwrap file from a yarn-managed monorepo. + +## Why do we need an NPM shrinkwrap file? + +When vending JavaScript applications that are installed via NPM, an +`npm-shrinkwrap.json` is necessary to control the dependency tree of the +installed application, ensuring that all the dependencies have the +version that the application vendor expects. + +1. This prevents `npm install ` on the user's computer + from installing an untested combination of versions, one that may potentially + be broken. This *shouldn't* happen if everyone nicely keeps to semantic + versioning, but doing so relies on good intentions. + +2. Since most package's dependencies are written like `^1.2.0`, any application + in the NPM ecosystem can potentially be compromised by someone releasing a + minor or patch version of a library somewhere deep in the dependency tree + with malware in it. All subsequent `npm install `s would happily + install the new version of the now compromised library. + +The only way around both of these issues is an `npm-shrinkwrap.json`, which will +be respected by NPM on doing `npm install` (unlike `package-lock.json`, which +won't). + +Note that yarn doesn't support shrinkwrapping at all. We can't help those +people, but we can at least protect NPM users and tell people to use NPM to +install our applications if they want to have some semblance of installation +safety. + +## Okay fine. Why does this tool need to exist? + +There doesn't seem to be any existing tool that can generate the +`npm-shrinkwrap.json` file from our monorepo. + +### What about 'npm shrinkwrap' ? + +There is the command `npm shrinkwrap`. From various Googles, this command +varyingly used to accept arguments and not accept arguments. Its current +incarnation on my NPM (6.11.3) does not accept arguments, and simply +renames `package-lock.json => npm-shrinkwrap.json`. We don't have +a `package-lock.json` (because we manage our monorepo completely using +Yarn), so that obviously won't work. + +Nevertheless, if I run `npm shrinkwrap` a file IS generated. This file +contains SOME version information, but doesn't contain package integrity +checksums and breaks NPM when a subsequent `npm install` is run. NPM +exits with `npm ERR! Cannot read property 'match' of undefined`. + +### What about 'synp' ? + +There is a tool called synp which can convert `yarn.lock` to `package-lock.json` +(which is the same format as `npm-shrinkwrap.json`). + +Unfortunately, we only have one `yarn.lock` for the whole monorepo, whereas we +would need the subset of dependencies `yarn.lock` that apply to the application +we're trying to bundle. + +This tool does some inspired borrowing from `synp` but is monorepo-aware. + +## How does it work? + +Requires the monorepo dependency tree to have been bootstrapped, so that +we can look at the concrete `node_modules` directories of all packages involved +(because we need each package's `package.json` to separate production dependencies +from devDependencies). + +For all (production) dependencies of the package we're shrinkwrapping: + +- If the dependency is in `yarn.lock`, yarn resolved the version for us and + we copy that entry into the package lock file. +- If the dependency is not in `yarn.lock`, the dependency comes from the monorepo + and will be released at the same time as the current package. Unfortunately, + since it hasn't been downloaded yet we won't have an integrity for it. We simply + add an entry that contains the version number to the package lock. + +Recurse from the dependency's package directory. \ No newline at end of file diff --git a/tools/yarn-cling/bin/yarn-cling b/tools/yarn-cling/bin/yarn-cling new file mode 100755 index 0000000000000..f5e2c6552f2b5 --- /dev/null +++ b/tools/yarn-cling/bin/yarn-cling @@ -0,0 +1,2 @@ +#!/usr/bin/env node +require('./yarn-cling.js'); \ No newline at end of file diff --git a/tools/yarn-cling/bin/yarn-cling.ts b/tools/yarn-cling/bin/yarn-cling.ts new file mode 100644 index 0000000000000..844c852b15ebe --- /dev/null +++ b/tools/yarn-cling/bin/yarn-cling.ts @@ -0,0 +1,18 @@ +import { generateShrinkwrap } from '../lib'; + +async function main() { + // No arguments, just assume current directory + await generateShrinkwrap({ + packageJsonFile: 'package.json', + outputFile: 'npm-shrinkwrap.json', + }); + + // tslint:disable-next-line:no-console + console.error('Generated npm-shrinkwrap.json'); +} + +main().catch(e => { + // tslint:disable-next-line:no-console + console.error(e); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/tools/yarn-cling/lib/hoisting.ts b/tools/yarn-cling/lib/hoisting.ts new file mode 100644 index 0000000000000..5f920fe3ce7f1 --- /dev/null +++ b/tools/yarn-cling/lib/hoisting.ts @@ -0,0 +1,51 @@ +import { PackageLockPackage } from "./types"; + +/** + * Hoist package-lock dependencies in-place + */ +export function hoistDependencies(packageLockDeps: Record) { + let didChange; + do { + didChange = false; + simplify(packageLockDeps); + } while (didChange); + + // For each of the deps, move each dependency that has the same version into the current array + function simplify(dependencies: Record) { + for (const depPackage of Object.values(dependencies)) { + moveChildrenUp(depPackage, dependencies); + } + return dependencies; + } + + // Move the children of the parent onto the same level if there are no conflicts + function moveChildrenUp(parent: PackageLockPackage, parentContainer: Record) { + if (!parent.dependencies) { return; } + + // Then push packages from the mutable parent into ITS parent + for (const [depName, depPackage] of Object.entries(parent.dependencies)) { + if (!parentContainer[depName]) { + // It's new, we can move it up. + parentContainer[depName] = depPackage; + delete parent.dependencies[depName]; + didChange = true; + + // Recurse on the package we just moved + moveChildrenUp(depPackage, parentContainer); + } else if (parentContainer[depName].version === depPackage.version) { + // Already exists, no conflict, delete the child, no need to recurse + delete parent.dependencies[depName]; + didChange = true; + } else { + // There is a conflict, leave the second package where it is, but do recurse. + moveChildrenUp(depPackage, parent.dependencies); + } + } + + // Cleanup for nice printing + if (Object.keys(parent.dependencies).length === 0) { + delete parent.dependencies; + didChange = true; + } + } +} diff --git a/tools/yarn-cling/lib/index.ts b/tools/yarn-cling/lib/index.ts new file mode 100644 index 0000000000000..816f55e88e97d --- /dev/null +++ b/tools/yarn-cling/lib/index.ts @@ -0,0 +1,153 @@ +import * as lockfile from '@yarnpkg/lockfile'; +import { promises as fs } from 'fs'; +import * as path from 'path'; +import { hoistDependencies } from './hoisting'; +import { PackageJson, PackageLock, PackageLockEntry, PackageLockPackage, YarnLock } from './types'; + +export interface ShrinkwrapOptions { + /** + * The package.json file to start scanning for dependencies + */ + packageJsonFile: string; + + /** + * The output lockfile to generate + * + * @default - Don't generate the file, just return the calculated output + */ + outputFile?: string; + + /** + * Whether to hoist dependencies + * + * @default true + */ + hoist?: boolean; +} + +export async function generateShrinkwrap(options: ShrinkwrapOptions): Promise { + // No args (yet) + const packageJsonFile = options.packageJsonFile; + const packageJsonDir = path.dirname(packageJsonFile); + + const yarnLockLoc = await findYarnLock(packageJsonDir); + const yarnLock: YarnLock = lockfile.parse(await fs.readFile(yarnLockLoc, { encoding: 'utf-8' })); + const pkgJson = await loadPackageJson(packageJsonFile); + + const lock = await generateLockFile(pkgJson, yarnLock, packageJsonDir); + + if (options.hoist ?? true) { + hoistDependencies(lock.dependencies || {}); + } + + if (options.outputFile) { + // Write the shrinkwrap file + await fs.writeFile(options.outputFile, JSON.stringify(lock, undefined, 2), { encoding: 'utf-8'} ); + } + + return lock; +} + +async function generateLockFile(pkgJson: PackageJson, yarnLock: YarnLock, rootDir: string): Promise { + return { + name: pkgJson.name, + version: pkgJson.version, + lockfileVersion: 1, + requires: true, + dependencies: await dependenciesFor(pkgJson.dependencies || {}, yarnLock, rootDir), + }; +} + +// tslint:disable-next-line:max-line-length +async function dependenciesFor(deps: Record, yarnLock: YarnLock, rootDir: string): Promise> { + const ret: Record = {}; + + // Get rid of any monorepo symlinks + rootDir = await fs.realpath(rootDir); + + for (const [depName, versionRange] of Object.entries(deps)) { + const depPkgJsonFile = require.resolve(`${depName}/package.json`, { paths: [rootDir] }); + const depPkgJson = await loadPackageJson(depPkgJsonFile); + const depDir = path.dirname(depPkgJsonFile); + const yarnKey = `${depName}@${versionRange}`; + + // Sanity check + if (depPkgJson.name !== depName) { + throw new Error(`Looking for '${depName}' from ${rootDir}, but found '${depPkgJson.name}' in ${depDir}`); + } + + const yarnResolved = yarnLock.object[yarnKey]; + if (yarnResolved) { + // Resolved by Yarn + ret[depName] = { + version: yarnResolved.version, + integrity: yarnResolved.integrity, + resolved: yarnResolved.resolved, + requires: depPkgJson.dependencies, + dependencies: await dependenciesFor(depPkgJson.dependencies || {}, yarnLock, depDir), + }; + } else { + // Comes from monorepo, just use whatever's in package.json + ret[depName] = { + version: depPkgJson.version, + requires: depPkgJson.dependencies, + dependencies: await dependenciesFor(depPkgJson.dependencies || {}, yarnLock, depDir), + }; + } + + // Simplify by removing useless entries + if (Object.keys(ret[depName].requires ?? {}).length === 0) { delete ret[depName].requires; } + if (Object.keys(ret[depName].dependencies ?? {}).length === 0) { delete ret[depName].dependencies; } + } + + return ret; +} + +async function findYarnLock(start: string) { + return findUp('yarn.lock', start); +} + +async function findUp(fileName: string, start: string) { + start = path.resolve(start); + let dir = start; + const yarnLockHere = () => path.join(dir, fileName); + while (!await fileExists(yarnLockHere())) { + const parent = path.dirname(dir); + if (parent === dir) { + throw new Error(`No ${fileName} found upwards from ${start}`); + } + dir = parent; + } + + return yarnLockHere(); +} + +async function loadPackageJson(fileName: string): Promise { + return JSON.parse(await fs.readFile(fileName, { encoding: 'utf-8' })); +} + +async function fileExists(fullPath: string): Promise { + try { + await fs.stat(fullPath); + return true; + } catch (e) { + if (e.code === 'ENOENT' || e.code === 'ENOTDIR') { return false; } + throw e; + } +} + +export function formatPackageLock(entry: PackageLockEntry) { + const lines = new Array(); + recurse([], entry); + return lines.join('\n'); + + function recurse(names: string[], thisEntry: PackageLockEntry) { + if (names.length > 0) { + // tslint:disable-next-line:no-console + lines.push(`${names.join(' -> ')} @ ${thisEntry.version}`); + } + for (const [depName, depEntry] of Object.entries(thisEntry.dependencies || {})) { + recurse([...names, depName], depEntry); + } + } +} \ No newline at end of file diff --git a/tools/yarn-cling/lib/types.ts b/tools/yarn-cling/lib/types.ts new file mode 100644 index 0000000000000..0f800cc50de52 --- /dev/null +++ b/tools/yarn-cling/lib/types.ts @@ -0,0 +1,58 @@ +export interface PackageJson { + name: string; + version: string; + + /** + * Dependency name to version range + */ + dependencies?: Record; +} + +export interface YarnLock { + type: string; + /** + * Dependency range (pkg@^1.2.0) to resolved package + */ + object: Record; +} + +export interface ResolvedYarnPackage { + version: string; + resolved: string; + integrity: string; + + /** + * Dependency name to version range + */ + dependencies: Record; +} + +export interface PackageLock extends PackageLockEntry { + name: string; + lockfileVersion: 1; + requires: true; +} + +export interface PackageLockEntry { + version: string; + /** + * Package name to resolved package + */ + dependencies?: Record; +} + +export interface PackageLockPackage extends PackageLockEntry { + resolved?: string; + integrity?: string; + + /** + * Package name to version number + * + * Must be in 'dependencies' at this level or higher. + */ + requires?: Record; + + bundled?: boolean; + dev?: boolean; + optional?: boolean; +} \ No newline at end of file diff --git a/tools/yarn-cling/package.json b/tools/yarn-cling/package.json new file mode 100644 index 0000000000000..40334f414197e --- /dev/null +++ b/tools/yarn-cling/package.json @@ -0,0 +1,65 @@ +{ + "name": "yarn-cling", + "private": true, + "version": "0.0.0", + "description": "Tool for generating npm-shrinkwrap from yarn.lock", + "main": "lib/index.js", + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "tools/yarn-cling" + }, + "bin": { + "yarn-cling": "bin/yarn-cling" + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "pkglint": "pkglint -f", + "test": "ln -sf ../../package2 test/test-fixture/package1/node_modules/ && jest", + "build+test+package": "npm run build+test", + "build+test": "npm run build && npm test" + }, + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@types/yarnpkg__lockfile": "^1.1.3", + "@types/jest": "^25.1.4", + "jest": "^24.9.0", + "@types/node": "^13.9.1", + "typescript": "~3.8.3", + "pkglint": "0.0.0" + }, + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0" + }, + "jest": { + "moduleFileExtensions": [ + "js" + ], + "coverageThreshold": { + "global": { + "branches": 60, + "statements": 80 + } + }, + "collectCoverage": true, + "coverageReporters": [ + "lcov", + "html", + "text-summary" + ] + }, + "keywords": [ + "aws", + "cdk" + ], + "homepage": "https://github.com/aws/aws-cdk", + "engines": { + "node": ">= 10.3.0" + } +} diff --git a/tools/yarn-cling/test/cling.test.ts b/tools/yarn-cling/test/cling.test.ts new file mode 100644 index 0000000000000..6b5854db688ed --- /dev/null +++ b/tools/yarn-cling/test/cling.test.ts @@ -0,0 +1,68 @@ +import * as path from 'path'; +import { generateShrinkwrap } from "../lib"; + +test('generate lock for fixture directory', async () => { + const lockFile = await generateShrinkwrap({ + packageJsonFile: path.join(__dirname, 'test-fixture', 'package1', 'package.json'), + hoist: false, + }); + + expect(lockFile).toEqual({ + lockfileVersion: 1, + name: "package1", + requires: true, + version: "1.1.1", + dependencies: { + package2: { + version: "2.2.2", + }, + registrydependency1: { + dependencies: { + registrydependency2: { + integrity: "sha512-pineapple", + resolved: "https://registry.bla.com/stuff", + version: "2.3.999", + }, + }, + integrity: "sha512-banana", + requires: { + registrydependency2: "^2.3.4", + }, + resolved: "https://registry.bla.com/stuff", + version: "1.2.999", + }, + }, + }); +}); + +test('generate hoisted lock for fixture directory', async () => { + const lockFile = await generateShrinkwrap({ + packageJsonFile: path.join(__dirname, 'test-fixture', 'package1', 'package.json'), + hoist: true, + }); + + expect(lockFile).toEqual({ + lockfileVersion: 1, + name: "package1", + requires: true, + version: "1.1.1", + dependencies: { + package2: { + version: "2.2.2", + }, + registrydependency1: { + integrity: "sha512-banana", + requires: { + registrydependency2: "^2.3.4", + }, + resolved: "https://registry.bla.com/stuff", + version: "1.2.999", + }, + registrydependency2: { + integrity: "sha512-pineapple", + resolved: "https://registry.bla.com/stuff", + version: "2.3.999", + }, + }, + }); +}); \ No newline at end of file diff --git a/tools/yarn-cling/test/hoisting.test.ts b/tools/yarn-cling/test/hoisting.test.ts new file mode 100644 index 0000000000000..b48606f65e128 --- /dev/null +++ b/tools/yarn-cling/test/hoisting.test.ts @@ -0,0 +1,138 @@ +import { hoistDependencies } from "../lib/hoisting"; +import { PackageLockPackage } from "../lib/types"; + +type Tree = Record; + +test('nonconflicting tree gets flattened', () => { + // GIVEN + const tree: Tree = { + stringutil: { + version: '1.0.0', + dependencies: { + leftpad: { version: '2.0.0' } + }, + }, + numutil: { + version: '3.0.0', + dependencies: { + isodd: { version: '4.0.0' } + }, + }, + }; + + // WHEN + hoistDependencies(tree); + + // THEN + expect(tree).toEqual({ + stringutil: { version: '1.0.0' }, + leftpad: { version: '2.0.0' }, + numutil: { version: '3.0.0' }, + isodd: { version: '4.0.0' }, + }); +}); + +test('matching versions get deduped', () => { + // GIVEN + const tree: Tree = { + stringutil: { + version: '1.0.0', + dependencies: { + leftpad: { version: '2.0.0' } + }, + }, + numutil: { + version: '3.0.0', + dependencies: { + leftpad: { version: '2.0.0' }, + isodd: { version: '4.0.0' } + }, + }, + }; + + // WHEN + hoistDependencies(tree); + + // THEN + expect(tree).toEqual({ + stringutil: { version: '1.0.0' }, + leftpad: { version: '2.0.0' }, + numutil: { version: '3.0.0' }, + isodd: { version: '4.0.0' }, + }); +}); + +test('conflicting versions get left in place', () => { + // GIVEN + const tree: Tree = { + stringutil: { + version: '1.0.0', + dependencies: { + leftpad: { version: '2.0.0' } + }, + }, + numutil: { + version: '3.0.0', + dependencies: { + leftpad: { version: '5.0.0' }, + isodd: { version: '4.0.0' } + }, + }, + }; + + // WHEN + hoistDependencies(tree); + + // THEN + expect(tree).toEqual({ + stringutil: { version: '1.0.0' }, + leftpad: { version: '2.0.0' }, + numutil: { + version: '3.0.0', + dependencies: { + leftpad: { version: '5.0.0' }, + }, + }, + isodd: { version: '4.0.0' }, + }); +}); + +test('dependencies of deduped packages are not hoisted into useless positions', () => { + // GIVEN + + const tree: Tree = { + stringutil: { + version: '1.0.0', + dependencies: { + leftpad: { + version: '2.0.0', + dependencies: { + spacemaker: { version: '3.0.0' }, + } + } + }, + }, + leftpad: { + version: '2.0.0', + dependencies: { + spacemaker: { version: '3.0.0' }, + } + }, + spacemaker: { version: '4.0.0' } + }; + + // WHEN + hoistDependencies(tree); + + // THEN + expect(tree).toEqual({ + stringutil: { version: '1.0.0' }, + leftpad: { + version: '2.0.0', + dependencies: { + spacemaker: { version: '3.0.0' } + } + }, + spacemaker: { version: '4.0.0' }, + }); +}); \ No newline at end of file diff --git a/tools/yarn-cling/test/test-fixture/.gitignore b/tools/yarn-cling/test/test-fixture/.gitignore new file mode 100644 index 0000000000000..cf4bab9ddde9f --- /dev/null +++ b/tools/yarn-cling/test/test-fixture/.gitignore @@ -0,0 +1 @@ +!node_modules diff --git a/tools/yarn-cling/test/test-fixture/package1/node_modules/package2 b/tools/yarn-cling/test/test-fixture/package1/node_modules/package2 new file mode 120000 index 0000000000000..8db12e196dfbd --- /dev/null +++ b/tools/yarn-cling/test/test-fixture/package1/node_modules/package2 @@ -0,0 +1 @@ +../../package2 \ No newline at end of file diff --git a/tools/yarn-cling/test/test-fixture/package1/node_modules/registrydependency1/package.json b/tools/yarn-cling/test/test-fixture/package1/node_modules/registrydependency1/package.json new file mode 100644 index 0000000000000..8ecbc5b50e2e6 --- /dev/null +++ b/tools/yarn-cling/test/test-fixture/package1/node_modules/registrydependency1/package.json @@ -0,0 +1,7 @@ +{ + "name": "registrydependency1", + "version": "1.2.999", + "dependencies": { + "registrydependency2": "^2.3.4" + } +} diff --git a/tools/yarn-cling/test/test-fixture/package1/node_modules/registrydependency2/package.json b/tools/yarn-cling/test/test-fixture/package1/node_modules/registrydependency2/package.json new file mode 100644 index 0000000000000..8b9d7f39ababd --- /dev/null +++ b/tools/yarn-cling/test/test-fixture/package1/node_modules/registrydependency2/package.json @@ -0,0 +1,4 @@ +{ + "name": "registrydependency2", + "version": "2.3.999" +} diff --git a/tools/yarn-cling/test/test-fixture/package1/package.json b/tools/yarn-cling/test/test-fixture/package1/package.json new file mode 100644 index 0000000000000..8edf6d46e6537 --- /dev/null +++ b/tools/yarn-cling/test/test-fixture/package1/package.json @@ -0,0 +1,8 @@ +{ + "name": "package1", + "version": "1.1.1", + "dependencies": { + "registrydependency1": "^1.2.3", + "package2": "2.2.2" + } +} diff --git a/tools/yarn-cling/test/test-fixture/package2/package.json b/tools/yarn-cling/test/test-fixture/package2/package.json new file mode 100644 index 0000000000000..d10f139d13944 --- /dev/null +++ b/tools/yarn-cling/test/test-fixture/package2/package.json @@ -0,0 +1,4 @@ +{ + "name": "package2", + "version": "2.2.2" +} diff --git a/tools/yarn-cling/test/test-fixture/yarn.lock b/tools/yarn-cling/test/test-fixture/yarn.lock new file mode 100644 index 0000000000000..fda733502a052 --- /dev/null +++ b/tools/yarn-cling/test/test-fixture/yarn.lock @@ -0,0 +1,9 @@ +"registrydependency1@^1.2.3": + version "1.2.999" + resolved "https://registry.bla.com/stuff" + integrity sha512-banana + +"registrydependency2@^2.3.4": + version "2.3.999" + resolved "https://registry.bla.com/stuff" + integrity sha512-pineapple diff --git a/tools/yarn-cling/tsconfig.json b/tools/yarn-cling/tsconfig.json new file mode 100644 index 0000000000000..14499cd2abfaf --- /dev/null +++ b/tools/yarn-cling/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "commonjs", + "lib": ["es2018"], + "strict": true, + "alwaysStrict": true, + "declaration": true, + "inlineSourceMap": true, + "inlineSources": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "resolveJsonModule": true, + "composite": true, + "incremental": true + }, + "include": ["**/*.ts"] +} diff --git a/yarn.lock b/yarn.lock index 1777bed3a382d..0b6faad8efe86 100644 --- a/yarn.lock +++ b/yarn.lock @@ -406,7 +406,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -920,6 +920,15 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== +"@jest/console@^24.7.1", "@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== + dependencies: + "@jest/source-map" "^24.9.0" + chalk "^2.0.1" + slash "^2.0.0" + "@jest/console@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.4.0.tgz#e2760b532701137801ba824dcff6bc822c961bac" @@ -931,6 +940,40 @@ jest-util "^25.4.0" slash "^3.0.0" +"@jest/core@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" + integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== + dependencies: + "@jest/console" "^24.7.1" + "@jest/reporters" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-changed-files "^24.9.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-resolve-dependencies "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + jest-watcher "^24.9.0" + micromatch "^3.1.10" + p-each-series "^1.0.0" + realpath-native "^1.1.0" + rimraf "^2.5.4" + slash "^2.0.0" + strip-ansi "^5.0.0" + "@jest/core@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.4.0.tgz#cc1fe078df69b8f0fbb023bb0bcee23ef3b89411" @@ -965,6 +1008,16 @@ slash "^3.0.0" strip-ansi "^6.0.0" +"@jest/environment@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" + integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== + dependencies: + "@jest/fake-timers" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + "@jest/environment@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.4.0.tgz#45071f525f0d8c5a51ed2b04fd42b55a8f0c7cb3" @@ -974,6 +1027,15 @@ "@jest/types" "^25.4.0" jest-mock "^25.4.0" +"@jest/fake-timers@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" + integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== + dependencies: + "@jest/types" "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + "@jest/fake-timers@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.4.0.tgz#3a9a4289ba836abd084953dca406389a57e00fbd" @@ -985,6 +1047,33 @@ jest-util "^25.4.0" lolex "^5.0.0" +"@jest/reporters@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" + integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.1" + istanbul-reports "^2.2.6" + jest-haste-map "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + node-notifier "^5.4.2" + slash "^2.0.0" + source-map "^0.6.0" + string-length "^2.0.0" + "@jest/reporters@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.4.0.tgz#836093433b32ce4e866298af2d6fcf6ed351b0b0" @@ -1016,6 +1105,15 @@ optionalDependencies: node-notifier "^6.0.0" +"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + "@jest/source-map@^25.2.6": version "25.2.6" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.2.6.tgz#0ef2209514c6d445ebccea1438c55647f22abb4c" @@ -1025,6 +1123,15 @@ graceful-fs "^4.2.3" source-map "^0.6.0" +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== + dependencies: + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@jest/test-result@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.4.0.tgz#6f2ec2c8da9981ef013ad8651c1c6f0cb20c6324" @@ -1035,6 +1142,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-sequencer@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" + integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== + dependencies: + "@jest/test-result" "^24.9.0" + jest-haste-map "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + "@jest/test-sequencer@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.4.0.tgz#2b96f9d37f18dc3336b28e3c8070f97f9f55f43b" @@ -1045,6 +1162,28 @@ jest-runner "^25.4.0" jest-runtime "^25.4.0" +"@jest/transform@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" + integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^24.9.0" + babel-plugin-istanbul "^5.1.0" + chalk "^2.0.1" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.15" + jest-haste-map "^24.9.0" + jest-regex-util "^24.9.0" + jest-util "^24.9.0" + micromatch "^3.1.10" + pirates "^4.0.1" + realpath-native "^1.1.0" + slash "^2.0.0" + source-map "^0.6.1" + write-file-atomic "2.4.1" + "@jest/transform@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.4.0.tgz#eef36f0367d639e2fd93dccd758550377fbb9962" @@ -1067,6 +1206,15 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^13.0.0" + "@jest/types@^25.4.0": version "25.4.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.4.0.tgz#5afeb8f7e1cba153a28e5ac3c9fe3eede7206d59" @@ -1973,7 +2121,7 @@ resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.50.tgz#fecc12b91cf9c58e98b6cc201b5996a3bb1e7cee" integrity sha512-RDzmQ5mO1f0BViKiuOudENZmoCACEa461nTRVtxhsAiEqGCgwdhCYN0aFgk42X5+ELAiqJKbv2mK0LkopYRYQg== -"@types/babel__core@^7.1.7": +"@types/babel__core@^7.1.0", "@types/babel__core@^7.1.7": version "7.1.7" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.7.tgz#1dacad8840364a57c98d0dd4855c6dd3752c6b89" integrity sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw== @@ -2057,7 +2205,7 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/jest@^25.2.1": +"@types/jest@^25.1.4", "@types/jest@^25.2.1": version "25.2.1" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.2.1.tgz#9544cd438607955381c1bdbdb97767a249297db5" integrity sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA== @@ -2121,6 +2269,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.21.tgz#c00e9603399126925806bed2d9a1e37da506965e" integrity sha512-PQKsydPxYxF1DsAFWmunaxd3sOi3iMt6Zmx/tgaagHYmwJ/9cRH91hQkeJZaUGWbvn0K5HlSVEXkn5U/llWPpQ== +"@types/node@^13.9.1": + version "13.9.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.8.tgz#09976420fc80a7a00bf40680c63815ed8c7616f4" + integrity sha512-1WgO8hsyHynlx7nhP1kr0OFzsgKz5XDQL+Lfc3b1Q3qIln/n8cKD4m09NJ0+P1Rq7Zgnc7N0+SsMnoD1rEb0kA== + "@types/nodeunit@^0.0.30": version "0.0.30" resolved "https://registry.yarnpkg.com/@types/nodeunit/-/nodeunit-0.0.30.tgz#48d2c2719a118c7723b83306c3e800b11a2bf678" @@ -2204,6 +2357,13 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== +"@types/yargs@^13.0.0": + version "13.0.8" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.8.tgz#a38c22def2f1c2068f8971acb3ea734eb3c64a99" + integrity sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA== + dependencies: + "@types/yargs-parser" "*" + "@types/yargs@^15.0.0", "@types/yargs@^15.0.4": version "15.0.4" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299" @@ -2211,6 +2371,11 @@ dependencies: "@types/yargs-parser" "*" +"@types/yarnpkg__lockfile@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.3.tgz#38fb31d82ed07dea87df6bd565721d11979fd761" + integrity sha512-mhdQq10tYpiNncMkg1vovCud5jQm+rWeRVz6fxjCJlY6uhDlAn9GnMSmBa2DQwqPf/jS5YR0K/xChDEh1jdOQg== + "@typescript-eslint/eslint-plugin@^2.29.0": version "2.29.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.29.0.tgz#c9efab7624e3dd6d144a0e4577a541d1bd42c2ac" @@ -2277,6 +2442,11 @@ semver "^6.3.0" tsutils "^3.17.1" +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + "@zkochan/cmd-shim@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@zkochan/cmd-shim/-/cmd-shim-3.1.0.tgz#2ab8ed81f5bb5452a85f25758eb9b8681982fd2e" @@ -2304,7 +2474,7 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -acorn-globals@^4.3.0, acorn-globals@^4.3.2: +acorn-globals@^4.1.0, acorn-globals@^4.3.0, acorn-globals@^4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== @@ -2322,6 +2492,11 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== +acorn@^5.5.3: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + acorn@^6.0.1, acorn@^6.0.4: version "6.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" @@ -2381,7 +2556,7 @@ alphanum-sort@^1.0.0: resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= -ansi-escapes@^3.2.0: +ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== @@ -2403,7 +2578,7 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.1.0: +ansi-regex@^4.0.0, ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -2461,6 +2636,11 @@ anymatch@^3.0.3: normalize-path "^3.0.0" picomatch "^2.0.4" +app-root-path@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" + integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== + append-transform@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" @@ -2711,7 +2891,7 @@ available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: dependencies: array-filter "^1.0.0" -aws-sdk-mock@^5.1.0: +aws-sdk-mock@^5.0.0, aws-sdk-mock@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/aws-sdk-mock/-/aws-sdk-mock-5.1.0.tgz#6f2c0bd670d7f378c906a8dd806f812124db71aa" integrity sha512-Wa5eCSo8HX0Snqb7FdBylaXMmfrAWoWZ+d7MFhiYsgHPvNvMEGjV945FF2qqE1U0Tolr1ALzik1fcwgaOhqUWQ== @@ -2720,6 +2900,21 @@ aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" +aws-sdk@^2.596.0: + version "2.650.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.650.0.tgz#edf995cf2805c918d7470a652f1316ae902c5aa4" + integrity sha512-MlTKXeRSe4IXXqnulAiXZccpTgDafs3ofYIQv/7ApR+oQUFsq96RHwe8MdW9N1cXn7fz302jLXUAykj4boR3DA== + dependencies: + buffer "4.9.1" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.3.2" + xml2js "0.4.19" + aws-sdk@^2.637.0, aws-sdk@^2.660.0: version "2.660.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.660.0.tgz#1be2f814ffdb1aadf859b252601974073a39a4b2" @@ -2752,6 +2947,19 @@ axios@^0.19.0: dependencies: follow-redirects "1.5.10" +babel-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" + integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== + dependencies: + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/babel__core" "^7.1.0" + babel-plugin-istanbul "^5.1.0" + babel-preset-jest "^24.9.0" + chalk "^2.4.2" + slash "^2.0.0" + babel-jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.4.0.tgz#409eb3e2ddc2ad9a92afdbb00991f1633f8018d0" @@ -2772,6 +2980,16 @@ babel-plugin-dynamic-import-node@^2.3.0: dependencies: object.assign "^4.1.0" +babel-plugin-istanbul@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" + integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + find-up "^3.0.0" + istanbul-lib-instrument "^3.3.0" + test-exclude "^5.2.3" + babel-plugin-istanbul@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" @@ -2783,6 +3001,13 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^4.0.0" test-exclude "^6.0.0" +babel-plugin-jest-hoist@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" + integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== + dependencies: + "@types/babel__traverse" "^7.0.6" + babel-plugin-jest-hoist@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.4.0.tgz#0c122c1b93fb76f52d2465be2e8069e798e9d442" @@ -2806,6 +3031,14 @@ babel-preset-current-node-syntax@^0.1.2: "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" +babel-preset-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" + integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== + dependencies: + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^24.9.0" + babel-preset-jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.4.0.tgz#10037cc32b751b994b260964629e49dc479abf4c" @@ -4233,7 +4466,7 @@ csso@^4.0.2: dependencies: css-tree "1.0.0-alpha.39" -cssom@0.3.x, cssom@^0.3.4, cssom@~0.3.6: +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4, cssom@~0.3.6: version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== @@ -4243,7 +4476,7 @@ cssom@^0.4.1: resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== -cssstyle@^1.1.1: +cssstyle@^1.0.0, cssstyle@^1.1.1: version "1.4.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== @@ -4288,7 +4521,7 @@ data-uri-to-buffer@1: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" integrity sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ== -data-urls@^1.1.0: +data-urls@^1.0.0, data-urls@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== @@ -4530,6 +4763,11 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== + diff-sequences@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" @@ -4654,11 +4892,21 @@ dotenv-expand@^5.1.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== +dotenv-json@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dotenv-json/-/dotenv-json-1.0.0.tgz#fc7f672aafea04bed33818733b9f94662332815c" + integrity sha512-jAssr+6r4nKhKRudQ0HOzMskOFFi9+ubXWwmrSGJFgTvpjyPXCXsCsYbjif6mXp7uxA7xY3/LGaiTQukZzSbOQ== + dotenv@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== +dotenv@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + dotgitignore@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/dotgitignore/-/dotgitignore-2.1.0.tgz#a4b15a4e4ef3cf383598aaf1dfa4a04bcc089b7b" @@ -4869,7 +5117,7 @@ escape-string-regexp@^3.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-3.0.0.tgz#1dad9cc28aed682be0de197280f79911a5fccd61" integrity sha512-11dXIUC3umvzEViLP117d0KN6LJzZxh5+9F4E/7WLAAw7GrHk8NpUR+g9iJi/pe9C0py4F8rs0hreyRCwlAuZg== -escodegen@1.x.x, escodegen@^1.11.0, escodegen@^1.11.1: +escodegen@1.x.x, escodegen@^1.11.0, escodegen@^1.11.1, escodegen@^1.9.1: version "1.14.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== @@ -4893,6 +5141,11 @@ escodegen@~1.9.0: optionalDependencies: source-map "~0.6.1" +eslint-config-standard@^14.1.0: + version "14.1.1" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" + integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg== + eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" @@ -4920,7 +5173,15 @@ eslint-module-utils@^2.4.1: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-import@^2.20.2: +eslint-plugin-es@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz#0f5f5da5f18aa21989feebe8a73eadefb3432976" + integrity sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ== + dependencies: + eslint-utils "^1.4.2" + regexpp "^3.0.0" + +eslint-plugin-import@^2.19.1, eslint-plugin-import@^2.20.2: version "2.20.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d" integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg== @@ -4938,6 +5199,28 @@ eslint-plugin-import@^2.20.2: read-pkg-up "^2.0.0" resolve "^1.12.0" +eslint-plugin-node@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" + integrity sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ== + dependencies: + eslint-plugin-es "^2.0.0" + eslint-utils "^1.4.2" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-plugin-promise@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" + integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== + +eslint-plugin-standard@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" + integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== + eslint-scope@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" @@ -4946,7 +5229,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.4.3: +eslint-utils@^1.4.2, eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== @@ -5146,6 +5429,18 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expect@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== + dependencies: + "@jest/types" "^24.9.0" + ansi-styles "^3.2.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" + expect@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/expect/-/expect-25.4.0.tgz#0b16c17401906d1679d173e59f0d4580b22f8dc8" @@ -6148,6 +6443,11 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.1.1: + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -6724,7 +7024,7 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-lib-coverage@^2.0.5: +istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== @@ -6748,7 +7048,7 @@ istanbul-lib-hook@^3.0.0: dependencies: append-transform "^2.0.0" -istanbul-lib-instrument@^3.3.0: +istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== @@ -6787,7 +7087,7 @@ istanbul-lib-processinfo@^2.0.2: rimraf "^3.0.0" uuid "^3.3.3" -istanbul-lib-report@^2.0.8: +istanbul-lib-report@^2.0.4, istanbul-lib-report@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== @@ -6805,7 +7105,7 @@ istanbul-lib-report@^3.0.0: make-dir "^3.0.0" supports-color "^7.1.0" -istanbul-lib-source-maps@^3.0.6: +istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== @@ -6825,7 +7125,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^2.2.4: +istanbul-reports@^2.2.4, istanbul-reports@^2.2.6: version "2.2.7" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== @@ -6840,6 +7140,15 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jest-changed-files@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" + integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== + dependencies: + "@jest/types" "^24.9.0" + execa "^1.0.0" + throat "^4.0.0" + jest-changed-files@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.4.0.tgz#e573db32c2fd47d2b90357ea2eda0622c5c5cbd6" @@ -6849,6 +7158,25 @@ jest-changed-files@^25.4.0: execa "^3.2.0" throat "^5.0.0" +jest-cli@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" + integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== + dependencies: + "@jest/core" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + import-local "^2.0.0" + is-ci "^2.0.0" + jest-config "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + prompts "^2.0.1" + realpath-native "^1.1.0" + yargs "^13.3.0" + jest-cli@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.4.0.tgz#5dac8be0fece6ce39f0d671395a61d1357322bab" @@ -6868,6 +7196,29 @@ jest-cli@^25.4.0: realpath-native "^2.0.0" yargs "^15.3.1" +jest-config@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" + integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^24.9.0" + "@jest/types" "^24.9.0" + babel-jest "^24.9.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^24.9.0" + jest-environment-node "^24.9.0" + jest-get-type "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + micromatch "^3.1.10" + pretty-format "^24.9.0" + realpath-native "^1.1.0" + jest-config@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.4.0.tgz#56e5df3679a96ff132114b44fb147389c8c0a774" @@ -6892,6 +7243,16 @@ jest-config@^25.4.0: pretty-format "^25.4.0" realpath-native "^2.0.0" +jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== + dependencies: + chalk "^2.0.1" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + jest-diff@^25.2.1, jest-diff@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.4.0.tgz#260b70f19a46c283adcad7f081cae71eb784a634" @@ -6902,6 +7263,13 @@ jest-diff@^25.2.1, jest-diff@^25.4.0: jest-get-type "^25.2.6" pretty-format "^25.4.0" +jest-docblock@^24.3.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" + integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== + dependencies: + detect-newline "^2.1.0" + jest-docblock@^25.3.0: version "25.3.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.3.0.tgz#8b777a27e3477cd77a168c05290c471a575623ef" @@ -6909,6 +7277,17 @@ jest-docblock@^25.3.0: dependencies: detect-newline "^3.0.0" +jest-each@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" + integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== + dependencies: + "@jest/types" "^24.9.0" + chalk "^2.0.1" + jest-get-type "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + jest-each@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.4.0.tgz#ad4e46164764e8e77058f169a0076a7f86f6b7d4" @@ -6920,6 +7299,18 @@ jest-each@^25.4.0: jest-util "^25.4.0" pretty-format "^25.4.0" +jest-environment-jsdom@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" + integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + jsdom "^11.5.1" + jest-environment-jsdom@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.4.0.tgz#bbfc7f85bb6ade99089062a830c79cb454565cf0" @@ -6932,6 +7323,17 @@ jest-environment-jsdom@^25.4.0: jest-util "^25.4.0" jsdom "^15.2.1" +jest-environment-node@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" + integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + jest-environment-node@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.4.0.tgz#188aef01ae6418e001c03fdd1c299961e1439082" @@ -6944,11 +7346,35 @@ jest-environment-node@^25.4.0: jest-util "^25.4.0" semver "^6.3.0" +jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== + jest-get-type@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== +jest-haste-map@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" + integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== + dependencies: + "@jest/types" "^24.9.0" + anymatch "^2.0.0" + fb-watchman "^2.0.0" + graceful-fs "^4.1.15" + invariant "^2.2.4" + jest-serializer "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.9.0" + micromatch "^3.1.10" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^1.2.7" + jest-haste-map@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.4.0.tgz#da7c309dd7071e0a80c953ba10a0ec397efb1ae2" @@ -6968,6 +7394,28 @@ jest-haste-map@^25.4.0: optionalDependencies: fsevents "^2.1.2" +jest-jasmine2@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" + integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^24.9.0" + is-generator-fn "^2.0.0" + jest-each "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + throat "^4.0.0" + jest-jasmine2@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.4.0.tgz#3d3d19514022e2326e836c2b66d68b4cb63c5861" @@ -6991,6 +7439,14 @@ jest-jasmine2@^25.4.0: pretty-format "^25.4.0" throat "^5.0.0" +jest-leak-detector@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" + integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== + dependencies: + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + jest-leak-detector@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.4.0.tgz#cf94a160c78e53d810e7b2f40b5fd7ee263375b3" @@ -6999,6 +7455,16 @@ jest-leak-detector@^25.4.0: jest-get-type "^25.2.6" pretty-format "^25.4.0" +jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== + dependencies: + chalk "^2.0.1" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + jest-matcher-utils@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.4.0.tgz#dc3e7aec402a1e567ed80b572b9ad285878895e6" @@ -7009,6 +7475,20 @@ jest-matcher-utils@^25.4.0: jest-get-type "^25.2.6" pretty-format "^25.4.0" +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + jest-message-util@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.4.0.tgz#2899e8bc43f5317acf8dfdfe89ea237d354fcdab" @@ -7022,6 +7502,13 @@ jest-message-util@^25.4.0: slash "^3.0.0" stack-utils "^1.0.1" +jest-mock@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" + integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== + dependencies: + "@jest/types" "^24.9.0" + jest-mock@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.4.0.tgz#ded7d64b5328d81d78d2138c825d3a45e30ec8ca" @@ -7034,11 +7521,25 @@ jest-pnp-resolver@^1.2.1: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== +jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== + jest-regex-util@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== +jest-resolve-dependencies@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" + integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== + dependencies: + "@jest/types" "^24.9.0" + jest-regex-util "^24.3.0" + jest-snapshot "^24.9.0" + jest-resolve-dependencies@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.4.0.tgz#783937544cfc40afcc7c569aa54748c4b3f83f5a" @@ -7048,6 +7549,17 @@ jest-resolve-dependencies@^25.4.0: jest-regex-util "^25.2.6" jest-snapshot "^25.4.0" +jest-resolve@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" + integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== + dependencies: + "@jest/types" "^24.9.0" + browser-resolve "^1.11.3" + chalk "^2.0.1" + jest-pnp-resolver "^1.2.1" + realpath-native "^1.1.0" + jest-resolve@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.4.0.tgz#6f4540ce0d419c4c720e791e871da32ba4da7a60" @@ -7062,6 +7574,31 @@ jest-resolve@^25.4.0: resolve "^1.15.1" slash "^3.0.0" +jest-runner@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" + integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.4.2" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-docblock "^24.3.0" + jest-haste-map "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-leak-detector "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + source-map-support "^0.5.6" + throat "^4.0.0" + jest-runner@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.4.0.tgz#6ca4a3d52e692bbc081228fa68f750012f1f29e5" @@ -7087,6 +7624,35 @@ jest-runner@^25.4.0: source-map-support "^0.5.6" throat "^5.0.0" +jest-runtime@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" + integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/source-map" "^24.3.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + realpath-native "^1.1.0" + slash "^2.0.0" + strip-bom "^3.0.0" + yargs "^13.3.0" + jest-runtime@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.4.0.tgz#1e5227a9e2159d26ae27dcd426ca6bc041983439" @@ -7118,11 +7684,35 @@ jest-runtime@^25.4.0: strip-bom "^4.0.0" yargs "^15.3.1" +jest-serializer@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" + integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== + jest-serializer@^25.2.6: version "25.2.6" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.6.tgz#3bb4cc14fe0d8358489dbbefbb8a4e708ce039b7" integrity sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ== +jest-snapshot@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" + integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== + dependencies: + "@babel/types" "^7.0.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + expect "^24.9.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^24.9.0" + semver "^6.2.0" + jest-snapshot@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.4.0.tgz#e0b26375e2101413fd2ccb4278a5711b1922545c" @@ -7143,6 +7733,24 @@ jest-snapshot@^25.4.0: pretty-format "^25.4.0" semver "^6.3.0" +jest-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" + integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== + dependencies: + "@jest/console" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/source-map" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + callsites "^3.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + mkdirp "^0.5.1" + slash "^2.0.0" + source-map "^0.6.0" + jest-util@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.4.0.tgz#6a093d09d86d2b41ef583e5fe7dd3976346e1acd" @@ -7153,6 +7761,18 @@ jest-util@^25.4.0: is-ci "^2.0.0" make-dir "^3.0.0" +jest-validate@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" + integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== + dependencies: + "@jest/types" "^24.9.0" + camelcase "^5.3.1" + chalk "^2.0.1" + jest-get-type "^24.9.0" + leven "^3.1.0" + pretty-format "^24.9.0" + jest-validate@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.4.0.tgz#2e177a93b716a137110eaf2768f3d9095abd3f38" @@ -7165,6 +7785,19 @@ jest-validate@^25.4.0: leven "^3.1.0" pretty-format "^25.4.0" +jest-watcher@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" + integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== + dependencies: + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + jest-util "^24.9.0" + string-length "^2.0.0" + jest-watcher@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.4.0.tgz#63ec0cd5c83bb9c9d1ac95be7558dd61c995ff05" @@ -7177,6 +7810,14 @@ jest-watcher@^25.4.0: jest-util "^25.4.0" string-length "^3.1.0" +jest-worker@^24.6.0, jest-worker@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== + dependencies: + merge-stream "^2.0.0" + supports-color "^6.1.0" + jest-worker@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.4.0.tgz#ee0e2ceee5a36ecddf5172d6d7e0ab00df157384" @@ -7185,6 +7826,23 @@ jest-worker@^25.4.0: merge-stream "^2.0.0" supports-color "^7.0.0" +jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" + integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== + dependencies: + import-local "^2.0.0" + jest-cli "^24.9.0" + +jest@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.3.0.tgz#7a5e59741d94b8662664c77a9f346246d6bf228b" + integrity sha512-iKd5ShQSHzFT5IL/6h5RZJhApgqXSoPxhp5HEi94v6OAw9QkF8T7X+liEU2eEHJ1eMFYTHmeWLrpBWulsDpaUg== + dependencies: + "@jest/core" "^25.3.0" + import-local "^3.0.2" + jest-cli "^25.3.0" + jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest/-/jest-25.4.0.tgz#fb96892c5c4e4a6b9bcb12068849cddf4c5f8cc7" @@ -7222,6 +7880,38 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + jsdom@^14.1.0: version "14.1.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-14.1.0.tgz#916463b6094956b0a6c1782c94e380cd30e1981b" @@ -7507,6 +8197,24 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +lambda-leak@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lambda-leak/-/lambda-leak-2.0.0.tgz#771985d3628487f6e885afae2b54510dcfb2cd7e" + integrity sha1-dxmF02KEh/boha+uK1RRDc+yzX4= + +lambda-tester@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/lambda-tester/-/lambda-tester-3.6.0.tgz#ceb7d4f4f0da768487a05cff37dcd088508b5247" + integrity sha512-F2ZTGWCLyIR95o/jWK46V/WnOCFAEUG/m/V7/CLhPJ7PCM+pror1rZ6ujP3TkItSGxUfpJi0kqwidw+M/nEqWw== + dependencies: + app-root-path "^2.2.1" + dotenv "^8.0.0" + dotenv-json "^1.0.0" + lambda-leak "^2.0.0" + semver "^6.1.1" + uuid "^3.3.2" + vandium-utils "^1.1.1" + lazystream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" @@ -7526,6 +8234,11 @@ lcov-parse@^1.0.0: resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" integrity sha1-6w1GtUER68VhrLTECO+TY73I9+A= +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + lerna@^3.20.2: version "3.20.2" resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.20.2.tgz#abf84e73055fe84ee21b46e64baf37b496c24864" @@ -8292,6 +9005,17 @@ nise@^4.0.1: just-extend "^4.0.2" path-to-regexp "^1.7.0" +nock@^11.7.0: + version "11.9.1" + resolved "https://registry.yarnpkg.com/nock/-/nock-11.9.1.tgz#2b026c5beb6d0dbcb41e7e4cefa671bc36db9c61" + integrity sha512-U5wPctaY4/ar2JJ5Jg4wJxlbBfayxgKbiAeGh+a1kk6Pwnc2ZEuKviLyDSG6t0uXl56q7AALIxoM6FJrBSsVXA== + dependencies: + debug "^4.1.0" + json-stringify-safe "^5.0.1" + lodash "^4.17.13" + mkdirp "^0.5.0" + propagate "^2.0.0" + nock@^12.0.3: version "12.0.3" resolved "https://registry.yarnpkg.com/nock/-/nock-12.0.3.tgz#83f25076dbc4c9aa82b5cdf54c9604c7a778d1c9" @@ -8382,6 +9106,17 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= +node-notifier@^5.4.2: + version "5.4.3" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" + integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + node-notifier@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-6.0.0.tgz#cea319e06baa16deec8ce5cd7f133c4a46b68e12" @@ -8548,7 +9283,7 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -nwsapi@^2.1.3, nwsapi@^2.2.0: +nwsapi@^2.0.7, nwsapi@^2.1.3, nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== @@ -8824,6 +9559,13 @@ own-or@^1.0.0: resolved "https://registry.yarnpkg.com/own-or/-/own-or-1.0.0.tgz#4e877fbeda9a2ec8000fbc0bcae39645ee8bf8dc" integrity sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw= +p-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= + dependencies: + p-reduce "^1.0.0" + p-each-series@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" @@ -9123,6 +9865,11 @@ parse-url@^5.0.0: parse-path "^4.0.0" protocols "^1.4.0" +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + parse5@5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" @@ -9679,6 +10426,16 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== + dependencies: + "@jest/types" "^24.9.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + pretty-format@^25.2.1, pretty-format@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.4.0.tgz#c58801bb5c4926ff4a677fe43f9b8b99812c7830" @@ -9943,7 +10700,7 @@ raw-body@^2.2.0: iconv-lite "0.4.24" unpipe "1.0.0" -react-is@^16.12.0: +react-is@^16.12.0, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -10112,6 +10869,13 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" +realpath-native@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" + integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== + dependencies: + util.promisify "^1.0.0" + realpath-native@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" @@ -10258,7 +11022,7 @@ request-promise-native@^1.0.5, request-promise-native@^1.0.7: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.0: +request@^2.87.0, request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -10345,6 +11109,13 @@ resolve@1.x, resolve@^1.1.5, resolve@^1.10.0, resolve@^1.11.1, resolve@^1.12.0, dependencies: path-parse "^1.0.6" +resolve@^1.10.1: + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== + dependencies: + path-parse "^1.0.6" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -10483,7 +11254,7 @@ sax@1.2.1: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= -sax@>=0.6.0, sax@~1.2.4: +sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -10507,7 +11278,7 @@ semver-intersect@^1.4.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -11023,6 +11794,14 @@ streamroller@^2.2.4: debug "^4.1.1" fs-extra "^8.1.0" +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + string-length@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" @@ -11492,6 +12271,11 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" @@ -11616,7 +12400,7 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== -tough-cookie@^2.3.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -11665,7 +12449,7 @@ trivial-deferred@^1.0.1: resolved "https://registry.yarnpkg.com/trivial-deferred/-/trivial-deferred-1.0.1.tgz#376d4d29d951d6368a6f7a0ae85c2f4d5e0658f3" integrity sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM= -ts-jest@^25.4.0: +ts-jest@^25.3.1, ts-jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.4.0.tgz#5ad504299f8541d463a52e93e5e9d76876be0ba4" integrity sha512-+0ZrksdaquxGUBwSdTIcdX7VXdwLIlSRsyjivVA9gcO+Cvr6ByqDhu/mi5+HCcb6cMkiQp5xZ8qRO7/eCqLeyw== @@ -12030,7 +12814,7 @@ util-promisify@^2.1.0: dependencies: object.getownpropertydescriptors "^2.0.3" -util.promisify@~1.0.0: +util.promisify@^1.0.0, util.promisify@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== @@ -12098,6 +12882,11 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" +vandium-utils@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vandium-utils/-/vandium-utils-1.2.0.tgz#44735de4b7641a05de59ebe945f174e582db4f59" + integrity sha1-RHNd5LdkGgXeWevpRfF05YLbT1k= + vendors@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" @@ -12157,18 +12946,27 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" -whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" @@ -12295,6 +13093,15 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" + integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.2: version "2.4.3" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" @@ -12353,7 +13160,7 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -ws@^5.1.1: +ws@^5.1.1, ws@^5.2.0: version "5.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== @@ -12511,7 +13318,7 @@ yargs@15.0.2: y18n "^4.0.0" yargs-parser "^16.1.0" -yargs@^13.2.2: +yargs@^13.2.2, yargs@^13.3.0: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== From 6903869def944f8100c8eef51dd7145c181984e2 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Wed, 22 Apr 2020 17:17:25 +0200 Subject: [PATCH 11/28] feat(cfnspec): cloudformation spec v13.0.0 (#7504) see CHANGELOG --- .../@aws-cdk/aws-imagebuilder/.eslintrc.js | 2 - packages/@aws-cdk/aws-imagebuilder/.gitignore | 19 - packages/@aws-cdk/aws-imagebuilder/.npmignore | 22 - packages/@aws-cdk/aws-imagebuilder/LICENSE | 201 ------ packages/@aws-cdk/aws-imagebuilder/NOTICE | 2 - packages/@aws-cdk/aws-imagebuilder/README.md | 16 - .../@aws-cdk/aws-imagebuilder/lib/index.ts | 2 - .../@aws-cdk/aws-imagebuilder/package.json | 87 --- .../test/imagebuilder.test.ts | 6 - packages/@aws-cdk/cfnspec/CHANGELOG.md | 33 + packages/@aws-cdk/cfnspec/cfn.version | 2 +- ...0_CloudFormationResourceSpecification.json | 592 ++++-------------- 12 files changed, 145 insertions(+), 839 deletions(-) delete mode 100644 packages/@aws-cdk/aws-imagebuilder/.eslintrc.js delete mode 100644 packages/@aws-cdk/aws-imagebuilder/.gitignore delete mode 100644 packages/@aws-cdk/aws-imagebuilder/.npmignore delete mode 100644 packages/@aws-cdk/aws-imagebuilder/LICENSE delete mode 100644 packages/@aws-cdk/aws-imagebuilder/NOTICE delete mode 100644 packages/@aws-cdk/aws-imagebuilder/README.md delete mode 100644 packages/@aws-cdk/aws-imagebuilder/lib/index.ts delete mode 100644 packages/@aws-cdk/aws-imagebuilder/package.json delete mode 100644 packages/@aws-cdk/aws-imagebuilder/test/imagebuilder.test.ts diff --git a/packages/@aws-cdk/aws-imagebuilder/.eslintrc.js b/packages/@aws-cdk/aws-imagebuilder/.eslintrc.js deleted file mode 100644 index 1b28bad193ceb..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/.eslintrc.js +++ /dev/null @@ -1,2 +0,0 @@ -const baseConfig = require('../../../tools/cdk-build-tools/config/eslintrc'); -module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-imagebuilder/.gitignore b/packages/@aws-cdk/aws-imagebuilder/.gitignore deleted file mode 100644 index a2fc43792ccfe..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -*.js -*.js.map -*.d.ts -tsconfig.json -tslint.json -node_modules -*.generated.ts -dist -.jsii - -.LAST_BUILD -.nyc_output -coverage -.nycrc -.LAST_PACKAGE -*.snk -nyc.config.js - -!.eslintrc.js \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder/.npmignore b/packages/@aws-cdk/aws-imagebuilder/.npmignore deleted file mode 100644 index 36d0f522c8ab1..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/.npmignore +++ /dev/null @@ -1,22 +0,0 @@ -# Don't include original .ts files when doing `npm pack` -*.ts -!*.d.ts -coverage -.nyc_output -*.tgz - -dist -.LAST_PACKAGE -.LAST_BUILD -!*.js - -# Include .jsii -!.jsii - -*.snk - -*.tsbuildinfo - -tsconfig.json - -.eslintrc.js \ No newline at end of file diff --git a/packages/@aws-cdk/aws-imagebuilder/LICENSE b/packages/@aws-cdk/aws-imagebuilder/LICENSE deleted file mode 100644 index b71ec1688783a..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/packages/@aws-cdk/aws-imagebuilder/NOTICE b/packages/@aws-cdk/aws-imagebuilder/NOTICE deleted file mode 100644 index bfccac9a7f69c..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/NOTICE +++ /dev/null @@ -1,2 +0,0 @@ -AWS Cloud Development Kit (AWS CDK) -Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/aws-imagebuilder/README.md b/packages/@aws-cdk/aws-imagebuilder/README.md deleted file mode 100644 index ef5f4bc99f7fa..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/README.md +++ /dev/null @@ -1,16 +0,0 @@ -## AWS::ImageBuilder Construct Library - ---- - -![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge) - -> All classes with the `Cfn` prefix in this module ([CFN Resources](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) are always stable and safe to use. - ---- - - -This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. - -```ts -import imagebuilder = require('@aws-cdk/aws-imagebuilder'); -``` diff --git a/packages/@aws-cdk/aws-imagebuilder/lib/index.ts b/packages/@aws-cdk/aws-imagebuilder/lib/index.ts deleted file mode 100644 index 4f8727183ba0d..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/lib/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// AWS::ImageBuilder CloudFormation Resources: -export * from './imagebuilder.generated'; diff --git a/packages/@aws-cdk/aws-imagebuilder/package.json b/packages/@aws-cdk/aws-imagebuilder/package.json deleted file mode 100644 index 5cb313c61884f..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/package.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "name": "@aws-cdk/aws-imagebuilder", - "version": "0.0.0", - "description": "The CDK Construct Library for AWS::ImageBuilder", - "main": "lib/index.js", - "types": "lib/index.d.ts", - "jsii": { - "outdir": "dist", - "targets": { - "dotnet": { - "namespace": "Amazon.CDK.AWS.ImageBuilder", - "packageId": "Amazon.CDK.AWS.ImageBuilder", - "signAssembly": true, - "assemblyOriginatorKeyFile": "../../key.snk", - "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" - }, - "java": { - "package": "software.amazon.awscdk.services.imagebuilder", - "maven": { - "groupId": "software.amazon.awscdk", - "artifactId": "imagebuilder" - } - }, - "python": { - "distName": "aws-cdk.aws-imagebuilder", - "module": "aws_cdk.aws_imagebuilder" - } - } - }, - "repository": { - "type": "git", - "url": "https://github.com/aws/aws-cdk.git", - "directory": "packages/@aws-cdk/aws-imagebuilder" - }, - "homepage": "https://github.com/aws/aws-cdk", - "scripts": { - "build": "cdk-build", - "watch": "cdk-watch", - "lint": "cdk-lint", - "test": "cdk-test", - "integ": "cdk-integ", - "pkglint": "pkglint -f", - "package": "cdk-package", - "awslint": "cdk-awslint", - "cfn2ts": "cfn2ts", - "build+test+package": "npm run build+test && npm run package", - "build+test": "npm run build && npm test", - "compat": "cdk-compat" - }, - "cdk-build": { - "cloudformation": "AWS::ImageBuilder" - }, - "keywords": [ - "aws", - "cdk", - "constructs", - "AWS::ImageBuilder", - "aws-imagebuilder" - ], - "author": { - "name": "Amazon Web Services", - "url": "https://aws.amazon.com", - "organization": true - }, - "jest": {}, - "license": "Apache-2.0", - "devDependencies": { - "@aws-cdk/assert": "0.0.0", - "cdk-build-tools": "0.0.0", - "cfn2ts": "0.0.0", - "pkglint": "0.0.0" - }, - "dependencies": { - "@aws-cdk/core": "0.0.0" - }, - "peerDependencies": { - "@aws-cdk/core": "0.0.0" - }, - "engines": { - "node": ">= 10.12.0" - }, - "stability": "experimental", - "maturity": "cfn-only", - "awscdkio": { - "announce": false - } -} diff --git a/packages/@aws-cdk/aws-imagebuilder/test/imagebuilder.test.ts b/packages/@aws-cdk/aws-imagebuilder/test/imagebuilder.test.ts deleted file mode 100644 index e394ef336bfb4..0000000000000 --- a/packages/@aws-cdk/aws-imagebuilder/test/imagebuilder.test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import '@aws-cdk/assert/jest'; -import {} from '../lib'; - -test('No tests are specified for this package', () => { - expect(true).toBe(true); -}); diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md index 5a9c6834eb742..7bf88bc696d82 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,36 @@ +# CloudFormation Resource Specification v13.0.0 + +## New Resource Types + + +## Removed Resource Types + +* AWS::ImageBuilder::Component +* AWS::ImageBuilder::DistributionConfiguration +* AWS::ImageBuilder::ImagePipeline +* AWS::ImageBuilder::ImageRecipe +* AWS::ImageBuilder::InfrastructureConfiguration + +## Attribute Changes + + +## Property Changes + +* AWS::DocDB::DBCluster DeletionProtection (__added__) +* AWS::MediaConvert::JobTemplate HopDestinations (__added__) + +## Property Type Changes + +* AWS::LakeFormation::Permissions.ColumnWildcard (__added__) +* AWS::LakeFormation::Permissions.DataLocationResource (__added__) +* AWS::LakeFormation::Permissions.TableWithColumnsResource (__added__) +* AWS::MediaConvert::JobTemplate.HopDestination (__added__) +* AWS::SSM::PatchBaseline.PatchStringDate (__added__) +* AWS::LakeFormation::Permissions.Resource DataLocationResource (__added__) +* AWS::LakeFormation::Permissions.Resource TableWithColumnsResource (__added__) +* AWS::SSM::PatchBaseline.Rule ApproveUntilDate (__added__) + + # CloudFormation Resource Specification v12.3.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index 4d23cb8e0bd77..02161ca86e5e8 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -12.3.0 +13.0.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json index 690fd28e266da..b7d6cd40e03a5 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json @@ -18819,179 +18819,6 @@ } } }, - "AWS::ImageBuilder::DistributionConfiguration.Distribution": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-distributionconfiguration-distribution.html", - "Properties": { - "AmiDistributionConfiguration": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-distributionconfiguration-distribution.html#cfn-imagebuilder-distributionconfiguration-distribution-amidistributionconfiguration", - "PrimitiveType": "Json", - "Required": false, - "UpdateType": "Mutable" - }, - "LicenseConfigurationArns": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-distributionconfiguration-distribution.html#cfn-imagebuilder-distributionconfiguration-distribution-licenseconfigurationarns", - "PrimitiveItemType": "String", - "Required": false, - "Type": "List", - "UpdateType": "Mutable" - }, - "Region": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-distributionconfiguration-distribution.html#cfn-imagebuilder-distributionconfiguration-distribution-region", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - } - } - }, - "AWS::ImageBuilder::ImagePipeline.ImageTestsConfiguration": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagepipeline-imagetestsconfiguration.html", - "Properties": { - "ImageTestsEnabled": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagepipeline-imagetestsconfiguration.html#cfn-imagebuilder-imagepipeline-imagetestsconfiguration-imagetestsenabled", - "PrimitiveType": "Boolean", - "Required": false, - "UpdateType": "Mutable" - }, - "TimeoutMinutes": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagepipeline-imagetestsconfiguration.html#cfn-imagebuilder-imagepipeline-imagetestsconfiguration-timeoutminutes", - "PrimitiveType": "Integer", - "Required": false, - "UpdateType": "Mutable" - } - } - }, - "AWS::ImageBuilder::ImagePipeline.Schedule": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagepipeline-schedule.html", - "Properties": { - "PipelineExecutionStartCondition": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagepipeline-schedule.html#cfn-imagebuilder-imagepipeline-schedule-pipelineexecutionstartcondition", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "ScheduleExpression": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagepipeline-schedule.html#cfn-imagebuilder-imagepipeline-schedule-scheduleexpression", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - } - } - }, - "AWS::ImageBuilder::ImageRecipe.ComponentConfiguration": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-componentconfiguration.html", - "Properties": { - "ComponentArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-componentconfiguration.html#cfn-imagebuilder-imagerecipe-componentconfiguration-componentarn", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - } - } - }, - "AWS::ImageBuilder::ImageRecipe.EbsInstanceBlockDeviceSpecification": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html", - "Properties": { - "DeleteOnTermination": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-deleteontermination", - "PrimitiveType": "Boolean", - "Required": false, - "UpdateType": "Immutable" - }, - "Encrypted": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-encrypted", - "PrimitiveType": "Boolean", - "Required": false, - "UpdateType": "Immutable" - }, - "Iops": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-iops", - "PrimitiveType": "Integer", - "Required": false, - "UpdateType": "Immutable" - }, - "KmsKeyId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-kmskeyid", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "SnapshotId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-snapshotid", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "VolumeSize": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-volumesize", - "PrimitiveType": "Integer", - "Required": false, - "UpdateType": "Immutable" - }, - "VolumeType": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-volumetype", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - } - } - }, - "AWS::ImageBuilder::ImageRecipe.InstanceBlockDeviceMapping": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-instanceblockdevicemapping.html", - "Properties": { - "DeviceName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-instanceblockdevicemapping.html#cfn-imagebuilder-imagerecipe-instanceblockdevicemapping-devicename", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "Ebs": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-instanceblockdevicemapping.html#cfn-imagebuilder-imagerecipe-instanceblockdevicemapping-ebs", - "Required": false, - "Type": "EbsInstanceBlockDeviceSpecification", - "UpdateType": "Immutable" - }, - "NoDevice": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-instanceblockdevicemapping.html#cfn-imagebuilder-imagerecipe-instanceblockdevicemapping-nodevice", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "VirtualName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-instanceblockdevicemapping.html#cfn-imagebuilder-imagerecipe-instanceblockdevicemapping-virtualname", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - } - } - }, - "AWS::ImageBuilder::InfrastructureConfiguration.Logging": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-logging.html", - "Properties": { - "S3Logs": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-logging.html#cfn-imagebuilder-infrastructureconfiguration-logging-s3logs", - "Required": false, - "Type": "S3Logs", - "UpdateType": "Mutable" - } - } - }, - "AWS::ImageBuilder::InfrastructureConfiguration.S3Logs": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-s3logs.html", - "Properties": { - "S3BucketName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-s3logs.html#cfn-imagebuilder-infrastructureconfiguration-s3logs-s3bucketname", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "S3KeyPrefix": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-s3logs.html#cfn-imagebuilder-infrastructureconfiguration-s3logs-s3keyprefix", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - } - } - }, "AWS::IoT1Click::Project.DeviceTemplate": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot1click-project-devicetemplate.html", "Properties": { @@ -22976,6 +22803,18 @@ } } }, + "AWS::LakeFormation::Permissions.ColumnWildcard": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-columnwildcard.html", + "Properties": { + "ExcludedColumnNames": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-columnwildcard.html#cfn-lakeformation-permissions-columnwildcard-excludedcolumnnames", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::LakeFormation::Permissions.DataLakePrincipal": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-datalakeprincipal.html", "Properties": { @@ -22987,6 +22826,17 @@ } } }, + "AWS::LakeFormation::Permissions.DataLocationResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-datalocationresource.html", + "Properties": { + "S3Resource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-datalocationresource.html#cfn-lakeformation-permissions-datalocationresource-s3resource", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::LakeFormation::Permissions.DatabaseResource": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-databaseresource.html", "Properties": { @@ -23001,6 +22851,12 @@ "AWS::LakeFormation::Permissions.Resource": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-resource.html", "Properties": { + "DataLocationResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-resource.html#cfn-lakeformation-permissions-resource-datalocationresource", + "Required": false, + "Type": "DataLocationResource", + "UpdateType": "Mutable" + }, "DatabaseResource": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-resource.html#cfn-lakeformation-permissions-resource-databaseresource", "Required": false, @@ -23012,6 +22868,12 @@ "Required": false, "Type": "TableResource", "UpdateType": "Mutable" + }, + "TableWithColumnsResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-resource.html#cfn-lakeformation-permissions-resource-tablewithcolumnsresource", + "Required": false, + "Type": "TableWithColumnsResource", + "UpdateType": "Mutable" } } }, @@ -23032,6 +22894,36 @@ } } }, + "AWS::LakeFormation::Permissions.TableWithColumnsResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-tablewithcolumnsresource.html", + "Properties": { + "ColumnNames": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-tablewithcolumnsresource.html#cfn-lakeformation-permissions-tablewithcolumnsresource-columnnames", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "ColumnWildcard": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-tablewithcolumnsresource.html#cfn-lakeformation-permissions-tablewithcolumnsresource-columnwildcard", + "Required": false, + "Type": "ColumnWildcard", + "UpdateType": "Mutable" + }, + "DatabaseName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-tablewithcolumnsresource.html#cfn-lakeformation-permissions-tablewithcolumnsresource-databasename", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-permissions-tablewithcolumnsresource.html#cfn-lakeformation-permissions-tablewithcolumnsresource-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Lambda::Alias.AliasRoutingConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-alias-aliasroutingconfiguration.html", "Properties": { @@ -23743,6 +23635,29 @@ } } }, + "AWS::MediaConvert::JobTemplate.HopDestination": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediaconvert-jobtemplate-hopdestination.html", + "Properties": { + "Priority": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediaconvert-jobtemplate-hopdestination.html#cfn-mediaconvert-jobtemplate-hopdestination-priority", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Queue": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediaconvert-jobtemplate-hopdestination.html#cfn-mediaconvert-jobtemplate-hopdestination-queue", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "WaitMinutes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mediaconvert-jobtemplate-hopdestination.html#cfn-mediaconvert-jobtemplate-hopdestination-waitminutes", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::MediaLive::Channel.AribSourceSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-medialive-channel-aribsourcesettings.html", "Properties": {} @@ -28623,6 +28538,9 @@ } } }, + "AWS::SSM::PatchBaseline.PatchStringDate": { + "PrimitiveType": "String" + }, "AWS::SSM::PatchBaseline.Rule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ssm-patchbaseline-rule.html", "Properties": { @@ -28632,6 +28550,12 @@ "Required": false, "UpdateType": "Mutable" }, + "ApproveUntilDate": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ssm-patchbaseline-rule.html#cfn-ssm-patchbaseline-rule-approveuntildate", + "Required": false, + "Type": "PatchStringDate", + "UpdateType": "Mutable" + }, "ComplianceLevel": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ssm-patchbaseline-rule.html#cfn-ssm-patchbaseline-rule-compliancelevel", "PrimitiveType": "String", @@ -31306,7 +31230,7 @@ } } }, - "ResourceSpecificationVersion": "12.3.0", + "ResourceSpecificationVersion": "13.0.0", "ResourceTypes": { "AWS::ACMPCA::Certificate": { "Attributes": { @@ -38788,6 +38712,12 @@ "Required": false, "UpdateType": "Immutable" }, + "DeletionProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-docdb-dbcluster.html#cfn-docdb-dbcluster-deletionprotection", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "EnableCloudwatchLogsExports": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-docdb-dbcluster.html#cfn-docdb-dbcluster-enablecloudwatchlogsexports", "PrimitiveItemType": "String", @@ -46105,313 +46035,6 @@ } } }, - "AWS::ImageBuilder::Component": { - "Attributes": { - "Arn": { - "PrimitiveType": "String" - }, - "Encrypted": { - "PrimitiveType": "Boolean" - }, - "Type": { - "PrimitiveType": "String" - } - }, - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html", - "Properties": { - "ChangeDescription": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-changedescription", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "Data": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-data", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "Description": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-description", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "KmsKeyId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-kmskeyid", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "Name": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-name", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - }, - "Platform": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-platform", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - }, - "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-tags", - "PrimitiveItemType": "String", - "Required": false, - "Type": "Map", - "UpdateType": "Immutable" - }, - "Uri": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-uri", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "Version": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html#cfn-imagebuilder-component-version", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - } - } - }, - "AWS::ImageBuilder::DistributionConfiguration": { - "Attributes": { - "Arn": { - "PrimitiveType": "String" - } - }, - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-distributionconfiguration.html", - "Properties": { - "Description": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-distributionconfiguration.html#cfn-imagebuilder-distributionconfiguration-description", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "Distributions": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-distributionconfiguration.html#cfn-imagebuilder-distributionconfiguration-distributions", - "ItemType": "Distribution", - "Required": true, - "Type": "List", - "UpdateType": "Mutable" - }, - "Name": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-distributionconfiguration.html#cfn-imagebuilder-distributionconfiguration-name", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - }, - "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-distributionconfiguration.html#cfn-imagebuilder-distributionconfiguration-tags", - "PrimitiveItemType": "String", - "Required": false, - "Type": "Map", - "UpdateType": "Mutable" - } - } - }, - "AWS::ImageBuilder::ImagePipeline": { - "Attributes": { - "Arn": { - "PrimitiveType": "String" - } - }, - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html", - "Properties": { - "Description": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-description", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "DistributionConfigurationArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-distributionconfigurationarn", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "ImageRecipeArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-imagerecipearn", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Mutable" - }, - "ImageTestsConfiguration": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-imagetestsconfiguration", - "Required": false, - "Type": "ImageTestsConfiguration", - "UpdateType": "Mutable" - }, - "InfrastructureConfigurationArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-infrastructureconfigurationarn", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Mutable" - }, - "Name": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-name", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - }, - "Schedule": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-schedule", - "Required": false, - "Type": "Schedule", - "UpdateType": "Mutable" - }, - "Status": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-status", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html#cfn-imagebuilder-imagepipeline-tags", - "PrimitiveItemType": "String", - "Required": false, - "Type": "Map", - "UpdateType": "Mutable" - } - } - }, - "AWS::ImageBuilder::ImageRecipe": { - "Attributes": { - "Arn": { - "PrimitiveType": "String" - } - }, - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html", - "Properties": { - "BlockDeviceMappings": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html#cfn-imagebuilder-imagerecipe-blockdevicemappings", - "ItemType": "InstanceBlockDeviceMapping", - "Required": false, - "Type": "List", - "UpdateType": "Immutable" - }, - "Components": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html#cfn-imagebuilder-imagerecipe-components", - "ItemType": "ComponentConfiguration", - "Required": true, - "Type": "List", - "UpdateType": "Immutable" - }, - "Description": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html#cfn-imagebuilder-imagerecipe-description", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Immutable" - }, - "Name": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html#cfn-imagebuilder-imagerecipe-name", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - }, - "ParentImage": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html#cfn-imagebuilder-imagerecipe-parentimage", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - }, - "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html#cfn-imagebuilder-imagerecipe-tags", - "PrimitiveItemType": "String", - "Required": false, - "Type": "Map", - "UpdateType": "Immutable" - }, - "Version": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html#cfn-imagebuilder-imagerecipe-version", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - } - } - }, - "AWS::ImageBuilder::InfrastructureConfiguration": { - "Attributes": { - "Arn": { - "PrimitiveType": "String" - } - }, - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html", - "Properties": { - "Description": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-description", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "InstanceProfileName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-instanceprofilename", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Mutable" - }, - "InstanceTypes": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-instancetypes", - "PrimitiveItemType": "String", - "Required": false, - "Type": "List", - "UpdateType": "Mutable" - }, - "KeyPair": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-keypair", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "Logging": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-logging", - "PrimitiveType": "Json", - "Required": false, - "Type": "Logging", - "UpdateType": "Mutable" - }, - "Name": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-name", - "PrimitiveType": "String", - "Required": true, - "UpdateType": "Immutable" - }, - "SecurityGroupIds": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-securitygroupids", - "PrimitiveItemType": "String", - "Required": false, - "Type": "List", - "UpdateType": "Mutable" - }, - "SnsTopicArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-snstopicarn", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "SubnetId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-subnetid", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, - "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-tags", - "PrimitiveItemType": "String", - "Required": false, - "Type": "Map", - "UpdateType": "Mutable" - }, - "TerminateInstanceOnFailure": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-terminateinstanceonfailure", - "PrimitiveType": "Boolean", - "Required": false, - "UpdateType": "Mutable" - } - } - }, "AWS::Inspector::AssessmentTarget": { "Attributes": { "Arn": { @@ -48062,6 +47685,13 @@ "Required": false, "UpdateType": "Mutable" }, + "HopDestinations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mediaconvert-jobtemplate.html#cfn-mediaconvert-jobtemplate-hopdestinations", + "ItemType": "HopDestination", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mediaconvert-jobtemplate.html#cfn-mediaconvert-jobtemplate-name", "PrimitiveType": "String", From 857e78832fbfe0a540dddff440adfd5caeca0011 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2020 16:19:02 +0000 Subject: [PATCH 12/28] chore(deps): update @aws-cdk/aws-imagebuilder requirement (#7519) Updates the requirements on [@aws-cdk/aws-imagebuilder](https://github.com/aws/aws-cdk/tree/HEAD/packages/@aws-cdk/aws-imagebuilder) to permit the latest version. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/v1.34.1/CHANGELOG.md) - [Commits](https://github.com/aws/aws-cdk/commits/v1.34.1/packages/@aws-cdk/aws-imagebuilder) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/decdk/package.json | 2 +- packages/monocdk-experiment/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/decdk/package.json b/packages/decdk/package.json index dcb948b9236d6..fc4ac5fd87b1c 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -102,7 +102,7 @@ "@aws-cdk/aws-greengrass": "0.0.0", "@aws-cdk/aws-guardduty": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", - "@aws-cdk/aws-imagebuilder": "0.0.0", + "@aws-cdk/aws-imagebuilder": "1.34.1", "@aws-cdk/aws-inspector": "0.0.0", "@aws-cdk/aws-iot": "0.0.0", "@aws-cdk/aws-iot1click": "0.0.0", diff --git a/packages/monocdk-experiment/package.json b/packages/monocdk-experiment/package.json index 5d1ecec1e36d9..39cdffc7e9747 100644 --- a/packages/monocdk-experiment/package.json +++ b/packages/monocdk-experiment/package.json @@ -170,7 +170,7 @@ "@aws-cdk/aws-networkmanager": "0.0.0", "@aws-cdk/aws-resourcegroups": "0.0.0", "@aws-cdk/aws-detective": "0.0.0", - "@aws-cdk/aws-imagebuilder": "0.0.0" + "@aws-cdk/aws-imagebuilder": "1.34.1" }, "peerDependencies": { "constructs": "^3.0.2" From 1b3aeaf27b6491bc6d9c7c83dc7b03b8cd488534 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Wed, 22 Apr 2020 17:56:05 +0100 Subject: [PATCH 13/28] Currently deployment logical id salting are only part of Methods, Models and Resources. Properties of the `RestApi` such as policy, parameters, binaryMediaTypes, etc. are not currently added to this salting. As a consequence, any change to the RestApi property does not trigger a new deployment, as customers would expect it would. The solution adds the serialized CloudFormation JSON of `CfnRestApi` to the logical id salting, such that change to any of the properties here will trigger a new deployment. **Note:** With this change, any change to the properties of `RestApi` will trigger a new deployment. fixes #5354 --- .../@aws-cdk/aws-apigateway/lib/deployment.ts | 25 ++++++++++++++++--- .../integ.request-authorizer.expected.json | 4 +-- ...eg.token-authorizer-iam-role.expected.json | 4 +-- .../integ.token-authorizer.expected.json | 4 +-- .../test/integ.cors.expected.json | 4 +-- ...pi.latebound-deploymentstage.expected.json | 4 +-- .../test/integ.restapi.books.expected.json | 4 +-- .../test/integ.restapi.defaults.expected.json | 4 +-- .../test/integ.restapi.expected.json | 4 +-- .../integ.restapi.multistack.expected.json | 4 +-- .../test/integ.restapi.multiuse.expected.json | 8 +++--- .../integ.restapi.vpc-endpoint.expected.json | 4 +-- .../aws-apigateway/test/test.deployment.ts | 23 +++++++++-------- .../aws-apigateway/test/test.restapi.ts | 6 ++--- .../aws-apigateway/test/test.stage.ts | 4 +-- ...nteg.api-gateway-domain-name.expected.json | 4 +-- .../test/__snapshots__/synth.test.js.snap | 8 +++--- 17 files changed, 69 insertions(+), 49 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/lib/deployment.ts b/packages/@aws-cdk/aws-apigateway/lib/deployment.ts index 0d88a865b32ef..419078f88aebc 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/deployment.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/deployment.ts @@ -1,6 +1,6 @@ import { CfnResource, Construct, Lazy, RemovalPolicy, Resource, Stack } from '@aws-cdk/core'; import * as crypto from 'crypto'; -import { CfnDeployment, CfnDeploymentProps } from './apigateway.generated'; +import { CfnDeployment } from './apigateway.generated'; import { IRestApi, RestApi } from './restapi'; export interface DeploymentProps { @@ -68,7 +68,7 @@ export class Deployment extends Resource { this.resource = new LatestDeploymentResource(this, 'Resource', { description: props.description, - restApiId: props.api.restApiId, + restApi: props.api, }); if (props.retainDeployments) { @@ -116,13 +116,23 @@ export class Deployment extends Resource { } } +interface LatestDeploymentResourceProps { + readonly description?: string; + readonly restApi: IRestApi; +} + class LatestDeploymentResource extends CfnDeployment { private hashComponents = new Array(); private originalLogicalId: string; + private api: IRestApi; - constructor(scope: Construct, id: string, props: CfnDeploymentProps) { - super(scope, id, props); + constructor(scope: Construct, id: string, props: LatestDeploymentResourceProps) { + super(scope, id, { + description: props.description, + restApiId: props.restApi.restApiId, + }); + this.api = props.restApi; this.originalLogicalId = Stack.of(this).getLogicalId(this); } @@ -145,6 +155,13 @@ class LatestDeploymentResource extends CfnDeployment { * add via `addToLogicalId`. */ protected prepare() { + if (this.api instanceof RestApi) { // Ignore IRestApi that are imported + + // Add CfnRestApi to the logical id so a new deployment is triggered when any of its properties change. + const cfnRestApiCF = (this.api.node.defaultChild as any)._toCloudFormation(); + this.addToLogicalId(Stack.of(this).resolve(cfnRestApiCF)); + } + const stack = Stack.of(this); // if hash components were added to the deployment, we use them to calculate diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.expected.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.expected.json index 2e5680632a72d..25995111b8677 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.request-authorizer.expected.json @@ -131,7 +131,7 @@ "Name": "MyRestApi" } }, - "MyRestApiDeploymentB555B5828fad37a0e56bbac79ae37ae990881dca": { + "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -150,7 +150,7 @@ "Ref": "MyRestApi2D1F47A9" }, "DeploymentId": { - "Ref": "MyRestApiDeploymentB555B5828fad37a0e56bbac79ae37ae990881dca" + "Ref": "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json index 4337a4e96c8a0..97105a9490e83 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer-iam-role.expected.json @@ -170,7 +170,7 @@ "Name": "MyRestApi" } }, - "MyRestApiDeploymentB555B5828fad37a0e56bbac79ae37ae990881dca": { + "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -189,7 +189,7 @@ "Ref": "MyRestApi2D1F47A9" }, "DeploymentId": { - "Ref": "MyRestApiDeploymentB555B5828fad37a0e56bbac79ae37ae990881dca" + "Ref": "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.expected.json b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.expected.json index 9253b3bd5b070..79102afef29f4 100644 --- a/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/authorizers/integ.token-authorizer.expected.json @@ -131,7 +131,7 @@ "Name": "MyRestApi" } }, - "MyRestApiDeploymentB555B5828fad37a0e56bbac79ae37ae990881dca": { + "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -150,7 +150,7 @@ "Ref": "MyRestApi2D1F47A9" }, "DeploymentId": { - "Ref": "MyRestApiDeploymentB555B5828fad37a0e56bbac79ae37ae990881dca" + "Ref": "MyRestApiDeploymentB555B582dcff966d69deeda8d47e3bf409ce29cb" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json index 404586c92da79..043b4d20bea46 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.cors.expected.json @@ -6,7 +6,7 @@ "Name": "cors-api-test" } }, - "corsapitestDeployment2BF1633A197b7a426736ab40a59d8a41c2d3d50d": { + "corsapitestDeployment2BF1633A228079ea05e5799220dd4ca13512b92d": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -29,7 +29,7 @@ "Ref": "corsapitest8682546E" }, "DeploymentId": { - "Ref": "corsapitestDeployment2BF1633A197b7a426736ab40a59d8a41c2d3d50d" + "Ref": "corsapitestDeployment2BF1633A228079ea05e5799220dd4ca13512b92d" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.expected.json index 0a2572dd267bd..eda41e36751f6 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.lambda-api.latebound-deploymentstage.expected.json @@ -355,7 +355,7 @@ } } }, - "deployment33381975": { + "deployment3338197541aef5f15bf9a60b10e06fdbe72854f4": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -374,7 +374,7 @@ "Ref": "lambdarestapiF559E4F2" }, "DeploymentId": { - "Ref": "deployment33381975" + "Ref": "deployment3338197541aef5f15bf9a60b10e06fdbe72854f4" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json index 83d6ea6014ae5..0d471973c58ca 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.books.expected.json @@ -156,7 +156,7 @@ "Name": "books-api" } }, - "booksapiDeployment308B08F1c828b08824c062376eba921738884f85": { + "booksapiDeployment308B08F132cc25cf8168bd5e99b9e6d4915866b5": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -181,7 +181,7 @@ "Ref": "booksapiE1885304" }, "DeploymentId": { - "Ref": "booksapiDeployment308B08F1c828b08824c062376eba921738884f85" + "Ref": "booksapiDeployment308B08F132cc25cf8168bd5e99b9e6d4915866b5" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.expected.json index 7f54f90de14cb..bf73644303e7d 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.defaults.expected.json @@ -6,7 +6,7 @@ "Name": "my-api" } }, - "myapiDeployment92F2CB49916eaecf87f818f1e175215b8d086029": { + "myapiDeployment92F2CB4972a890db5063ec679071ba7eefc76f2a": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -25,7 +25,7 @@ "Ref": "myapi4C7BF186" }, "DeploymentId": { - "Ref": "myapiDeployment92F2CB49916eaecf87f818f1e175215b8d086029" + "Ref": "myapiDeployment92F2CB4972a890db5063ec679071ba7eefc76f2a" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json index a84aa3b973cf9..9758c8c2e1b00 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.expected.json @@ -6,7 +6,7 @@ "Name": "my-api" } }, - "myapiDeployment92F2CB4919460d935da8177bcfbc418506e514ff": { + "myapiDeployment92F2CB4963d40685c54c6f8da21d80a83f16d3d5": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -38,7 +38,7 @@ "CacheClusterEnabled": true, "CacheClusterSize": "0.5", "DeploymentId": { - "Ref": "myapiDeployment92F2CB4919460d935da8177bcfbc418506e514ff" + "Ref": "myapiDeployment92F2CB4963d40685c54c6f8da21d80a83f16d3d5" }, "Description": "beta stage", "MethodSettings": [ diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json index 89fc935988bf7..23a4100da8156 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multistack.expected.json @@ -75,7 +75,7 @@ "Name": "SecondRestAPI" } }, - "BooksApiDeployment86CA39AFc929a0f95f673e230c62e2c9754726f6": { + "BooksApiDeployment86CA39AF7e6c771d47a1a3777eba99bffc037822": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -96,7 +96,7 @@ "Ref": "BooksApi60AC975F" }, "DeploymentId": { - "Ref": "BooksApiDeployment86CA39AFc929a0f95f673e230c62e2c9754726f6" + "Ref": "BooksApiDeployment86CA39AF7e6c771d47a1a3777eba99bffc037822" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.expected.json index 4c37191b347c8..eb403f6d94d59 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.multiuse.expected.json @@ -56,7 +56,7 @@ "Name": "hello-api" } }, - "helloapiDeploymentFA89AEEC086c88c5044fbc117bd88fffcee53ab2": { + "helloapiDeploymentFA89AEEC3622d8c965f356a33fd95586d24bf138": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -76,7 +76,7 @@ "Ref": "helloapi4446A35B" }, "DeploymentId": { - "Ref": "helloapiDeploymentFA89AEEC086c88c5044fbc117bd88fffcee53ab2" + "Ref": "helloapiDeploymentFA89AEEC3622d8c965f356a33fd95586d24bf138" }, "StageName": "prod" } @@ -265,7 +265,7 @@ "Name": "second-api" } }, - "secondapiDeployment20F2C7001932445454ace403a6bfe89c1430ff70": { + "secondapiDeployment20F2C70088fa5a027620045bea3e5043c6d31f5a": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -285,7 +285,7 @@ "Ref": "secondapi730EF3C7" }, "DeploymentId": { - "Ref": "secondapiDeployment20F2C7001932445454ace403a6bfe89c1430ff70" + "Ref": "secondapiDeployment20F2C70088fa5a027620045bea3e5043c6d31f5a" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.vpc-endpoint.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.vpc-endpoint.expected.json index 0a2769170552e..29958c39c2759 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.restapi.vpc-endpoint.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.restapi.vpc-endpoint.expected.json @@ -631,7 +631,7 @@ } } }, - "MyApiDeploymentECB0D05E4316cb89aa1d468052daa78055609f5a": { + "MyApiDeploymentECB0D05E7a475a505b0c925e193030293593b6dc": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -650,7 +650,7 @@ "Ref": "MyApi49610EDF" }, "DeploymentId": { - "Ref": "MyApiDeploymentECB0D05E4316cb89aa1d468052daa78055609f5a" + "Ref": "MyApiDeploymentECB0D05E7a475a505b0c925e193030293593b6dc" }, "StageName": "prod" } diff --git a/packages/@aws-cdk/aws-apigateway/test/test.deployment.ts b/packages/@aws-cdk/aws-apigateway/test/test.deployment.ts index eb70ece0cce77..47118594132a5 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.deployment.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.deployment.ts @@ -43,7 +43,7 @@ export = { Name: 'api', }, }, - deployment33381975: { + deployment33381975bba46c5132329b81e7befcbbba5a0e75: { Type: 'AWS::ApiGateway::Deployment', Properties: { RestApiId: { @@ -97,7 +97,7 @@ export = { Name: 'api', }, }, - deployment33381975: { + deployment33381975bba46c5132329b81e7befcbbba5a0e75: { Type: 'AWS::ApiGateway::Deployment', Properties: { RestApiId: { @@ -133,30 +133,33 @@ export = { test.done(); }, - '"addToLogicalId" will "salt" the logical ID of the deployment resource'(test: Test) { + 'logical ID of the deployment resource is salted'(test: Test) { // GIVEN const stack = new Stack(); const api = new apigateway.RestApi(stack, 'api', { deploy: false, cloudWatchRole: false }); const deployment = new apigateway.Deployment(stack, 'deployment', { api }); api.root.addMethod('GET'); - // default logical ID (with no "salt") - test.ok(synthesize().Resources.deployment33381975); + const resources = synthesize().Resources; + test.ok(resources.deployment33381975bba46c5132329b81e7befcbbba5a0e75, + `resource deployment33381975bba46c5132329b81e7befcbbba5a0e75 not found, instead found ${Object.keys(resources)}`); // adding some salt deployment.addToLogicalId({ foo: 123 }); // add some data to the logical ID // the logical ID changed const template = synthesize(); - test.ok(!template.Resources.deployment33381975, 'old resource id deleted'); - test.ok(template.Resources.deployment33381975427670fa9e4148dc851927485bdf36a5, 'new resource is created'); + test.ok(!template.Resources.deployment33381975bba46c5132329b81e7befcbbba5a0e75, 'old resource id is not deleted'); + test.ok(template.Resources.deployment33381975075f46a4503208d69fcffed2f263c48c, + `new resource deployment33381975075f46a4503208d69fcffed2f263c48c is not created, instead found ${Object.keys(template.Resources)}`); // tokens supported, and are resolved upon synthesis const value = 'hello hello'; deployment.addToLogicalId({ foo: Lazy.stringValue({ produce: () => value }) }); const template2 = synthesize(); - test.ok(template2.Resources.deployment33381975a12dfe81474913364dc31c06e37f9449); + test.ok(template2.Resources.deployment33381975b6d7672e4c9afd0b741e41d07739786b, + `resource deployment33381975b6d7672e4c9afd0b741e41d07739786b not found, instead found ${Object.keys(template2.Resources)}`); test.done(); @@ -214,10 +217,10 @@ export = { // THEN expect(stack1).to(haveResource('AWS::ApiGateway::Stage', { - DeploymentId: { Ref: 'myapiDeploymentB7EF8EB7e0b8372768854261d2d1218739e0a307' }, + DeploymentId: { Ref: 'myapiDeploymentB7EF8EB74c5295c27fa87ff13f4d04e13f67662d' }, })); expect(stack2).to(haveResource('AWS::ApiGateway::Stage', { - DeploymentId: { Ref: 'myapiDeploymentB7EF8EB77c517352b0f7ab73c333e36585c8f1f3' }, + DeploymentId: { Ref: 'myapiDeploymentB7EF8EB7b50d305057ba109c118e4aafd4509355' }, })); test.done(); }, diff --git a/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts b/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts index 00e7d5858ebbd..97fac8ca999f4 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.restapi.ts @@ -36,7 +36,7 @@ export = { }, }, }, - myapiDeployment92F2CB49916eaecf87f818f1e175215b8d086029: { + myapiDeployment92F2CB4972a890db5063ec679071ba7eefc76f2a: { Type: 'AWS::ApiGateway::Deployment', Properties: { RestApiId: { Ref: 'myapi4C7BF186' }, @@ -48,7 +48,7 @@ export = { Type: 'AWS::ApiGateway::Stage', Properties: { RestApiId: { Ref: 'myapi4C7BF186' }, - DeploymentId: { Ref: 'myapiDeployment92F2CB49916eaecf87f818f1e175215b8d086029' }, + DeploymentId: { Ref: 'myapiDeployment92F2CB4972a890db5063ec679071ba7eefc76f2a' }, StageName: 'prod', }, }, @@ -590,7 +590,7 @@ export = { 'myapiAccountC3A4750C', 'myapiCloudWatchRoleEB425128', 'myapiGET9B7CD29E', - 'myapiDeploymentB7EF8EB75c091a668064a3f3a1f6d68a3fb22cf9', + 'myapiDeploymentB7EF8EB7b8edc043bcd33e0d85a3c85151f47e98', 'myapiDeploymentStageprod329F21FF', 'myapi162F20B8', ], diff --git a/packages/@aws-cdk/aws-apigateway/test/test.stage.ts b/packages/@aws-cdk/aws-apigateway/test/test.stage.ts index 725985a1ea276..bed2631ae1665 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.stage.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.stage.ts @@ -43,7 +43,7 @@ export = { }, }, }, - mydeployment71ED3B4B: { + mydeployment71ED3B4B5ce82e617e0729f75657ddcca51e3b91: { Type: 'AWS::ApiGateway::Deployment', Properties: { RestApiId: { @@ -61,7 +61,7 @@ export = { Ref: 'testapiD6451F70', }, DeploymentId: { - Ref: 'mydeployment71ED3B4B', + Ref: 'mydeployment71ED3B4B5ce82e617e0729f75657ddcca51e3b91', }, StageName: 'prod', }, diff --git a/packages/@aws-cdk/aws-route53-targets/test/integ.api-gateway-domain-name.expected.json b/packages/@aws-cdk/aws-route53-targets/test/integ.api-gateway-domain-name.expected.json index a09a3fada739d..d00377c922be9 100644 --- a/packages/@aws-cdk/aws-route53-targets/test/integ.api-gateway-domain-name.expected.json +++ b/packages/@aws-cdk/aws-route53-targets/test/integ.api-gateway-domain-name.expected.json @@ -212,7 +212,7 @@ "Name": "api" } }, - "apiDeployment149F12949ab8cbc5717926c7a1a01815778330c4": { + "apiDeployment149F1294891f10d69bae7c4d19bdee7af013a950": { "Type": "AWS::ApiGateway::Deployment", "Properties": { "RestApiId": { @@ -233,7 +233,7 @@ "Ref": "apiC8550315" }, "DeploymentId": { - "Ref": "apiDeployment149F12949ab8cbc5717926c7a1a01815778330c4" + "Ref": "apiDeployment149F1294891f10d69bae7c4d19bdee7af013a950" }, "StageName": "prod" } diff --git a/packages/decdk/test/__snapshots__/synth.test.js.snap b/packages/decdk/test/__snapshots__/synth.test.js.snap index 7a9d72ff1fc09..c181ff0751808 100644 --- a/packages/decdk/test/__snapshots__/synth.test.js.snap +++ b/packages/decdk/test/__snapshots__/synth.test.js.snap @@ -423,7 +423,7 @@ Object { }, "Type": "AWS::IAM::Role", }, - "MyApiDeploymentECB0D05Ed646248a19f9620d956e9fa33de3ed89": Object { + "MyApiDeploymentECB0D05E0597cc4592870e54c401cccc6090bd86": Object { "DependsOn": Array [ "GetRootA9424890", "MyApiproxyANYFCF46C66", @@ -441,7 +441,7 @@ Object { "MyApiDeploymentStageprodE1054AF0": Object { "Properties": Object { "DeploymentId": Object { - "Ref": "MyApiDeploymentECB0D05Ed646248a19f9620d956e9fa33de3ed89", + "Ref": "MyApiDeploymentECB0D05E0597cc4592870e54c401cccc6090bd86", }, "RestApiId": Object { "Ref": "MyApi49610EDF", @@ -1213,7 +1213,7 @@ Object { }, "Type": "AWS::IAM::Role", }, - "lambdaeventsHelloWorldFunctionAB27BB65ApiEventSourceA7A86A4FDeploymentFF3F4A1Aa119fa0e654d84489ef88606c21a73fb": Object { + "lambdaeventsHelloWorldFunctionAB27BB65ApiEventSourceA7A86A4FDeploymentFF3F4A1Ac00dde791d2719be3e8ea69f9a61a5cd": Object { "DependsOn": Array [ "lambdaeventsHelloWorldFunctionAB27BB65ApiEventSourceA7A86A4FhelloGET04FBC7F6", "lambdaeventsHelloWorldFunctionAB27BB65ApiEventSourceA7A86A4FhelloPOST53F177B1", @@ -1230,7 +1230,7 @@ Object { "lambdaeventsHelloWorldFunctionAB27BB65ApiEventSourceA7A86A4FDeploymentStageprod6A86C016": Object { "Properties": Object { "DeploymentId": Object { - "Ref": "lambdaeventsHelloWorldFunctionAB27BB65ApiEventSourceA7A86A4FDeploymentFF3F4A1Aa119fa0e654d84489ef88606c21a73fb", + "Ref": "lambdaeventsHelloWorldFunctionAB27BB65ApiEventSourceA7A86A4FDeploymentFF3F4A1Ac00dde791d2719be3e8ea69f9a61a5cd", }, "RestApiId": Object { "Ref": "lambdaeventsHelloWorldFunctionAB27BB65ApiEventSourceA7A86A4F12449C5F", From 61f310a63245ace5046de24eb80f79cc6540e264 Mon Sep 17 00:00:00 2001 From: Christoph Gysin Date: Wed, 22 Apr 2020 21:27:03 +0300 Subject: [PATCH 14/28] chore(aws-cdk): fix whitespace in tsconfig fixes #7511 --- .../aws-cdk/lib/init-templates/app/typescript/tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/lib/init-templates/app/typescript/tsconfig.json b/packages/aws-cdk/lib/init-templates/app/typescript/tsconfig.json index 03c16d26a637c..ec75123ce6554 100644 --- a/packages/aws-cdk/lib/init-templates/app/typescript/tsconfig.json +++ b/packages/aws-cdk/lib/init-templates/app/typescript/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target":"ES2018", + "target": "ES2018", "module": "commonjs", "lib": ["es2018"], "declaration": true, @@ -16,7 +16,7 @@ "inlineSourceMap": true, "inlineSources": true, "experimentalDecorators": true, - "strictPropertyInitialization":false, + "strictPropertyInitialization": false, "typeRoots": ["./node_modules/@types"] }, "exclude": ["cdk.out"] From 51ce855cd43f33cf3dea057ca84b6578e999c8cc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2020 19:11:30 +0000 Subject: [PATCH 15/28] chore(deps): bump aws-sdk from 2.660.0 to 2.661.0 (#7523) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.660.0 to 2.661.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.660.0...v2.661.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-cloudfront/package.json | 2 +- packages/@aws-cdk/aws-cloudtrail/package.json | 2 +- packages/@aws-cdk/aws-codebuild/package.json | 2 +- packages/@aws-cdk/aws-codecommit/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 2 +- .../@aws-cdk/aws-events-targets/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 2 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-sqs/package.json | 2 +- .../@aws-cdk/custom-resources/package.json | 2 +- packages/aws-cdk/package.json | 2 +- packages/cdk-assets/package.json | 2 +- yarn.lock | 170 +++++------------- 14 files changed, 54 insertions(+), 142 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index 547d045901823..336e2ec225cb3 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index 9630eac937be6..6940b61dbcdad 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index 3d20e12b9a500..2ef2da86c3b87 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -70,7 +70,7 @@ "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/aws-sqs": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index cb73512444adf..8cf5db589ce19 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -70,7 +70,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index 650f7a428fe9f..fb1549b720a0a 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/jest": "^25.2.1", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index 53e0c177e6c23..bda1512c0b441 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index 2f143e9564e5a..676a8cc6c378d 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -86,7 +86,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index 99f435418410c..4f5ed050a7e2d 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -71,7 +71,7 @@ "@types/lodash": "^4.14.150", "@types/nodeunit": "^0.0.30", "@types/sinon": "^9.0.0", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index bceb659370360..c1ef16decf786 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -64,7 +64,7 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-sqs/package.json b/packages/@aws-cdk/aws-sqs/package.json index 9fd3d3e07af99..b67ccc49ad438 100644 --- a/packages/@aws-cdk/aws-sqs/package.json +++ b/packages/@aws-cdk/aws-sqs/package.json @@ -65,7 +65,7 @@ "@aws-cdk/assert": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@types/nodeunit": "^0.0.30", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index a0ceafa94114c..76ad934b6062f 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -73,7 +73,7 @@ "@types/aws-lambda": "^8.10.39", "@types/fs-extra": "^8.1.0", "@types/sinon": "^9.0.0", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "aws-sdk-mock": "^5.1.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 017758e372b5e..2fb4a7ad5e583 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -68,7 +68,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/region-info": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "camelcase": "^6.0.0", "cdk-assets": "0.0.0", "colors": "^1.4.0", diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index 4f5df0ef088b1..d701abf862e6a 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -44,7 +44,7 @@ "dependencies": { "@aws-cdk/cdk-assets-schema": "0.0.0", "archiver": "^4.0.1", - "aws-sdk": "^2.660.0", + "aws-sdk": "^2.661.0", "glob": "^7.1.6", "yargs": "^15.3.1" }, diff --git a/yarn.lock b/yarn.lock index 0b6faad8efe86..35150ab4f8bab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,38 @@ # yarn lockfile v1 +"@aws-cdk/aws-imagebuilder@1.34.1": + version "1.34.1" + resolved "https://registry.yarnpkg.com/@aws-cdk/aws-imagebuilder/-/aws-imagebuilder-1.34.1.tgz#ae40cc78dfdfef421d7a3337cf909f112e43352b" + integrity sha512-WQjgZscfVPV5maatdFgvhPNp2Pdcs7KXat2uMfXF4LgaUmIa+BQ90LFShkfxDESvGZQTrMXgdOqPOwUuVmNR+Q== + dependencies: + "@aws-cdk/core" "1.34.1" + +"@aws-cdk/cloud-assembly-schema@1.34.1": + version "1.34.1" + resolved "https://registry.yarnpkg.com/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.34.1.tgz#c79eb4ccbe0301c2c0ad4d640d005b27de419a98" + integrity sha512-zBiP2ty4LgeFl0ulc8kDbAzI5MeKdkIwWd7ef1qz+pk4YfBtAjsHbJDzk/apkR7Yaf7Tum9UuPf7yCK4mB18IA== + dependencies: + jsonschema "^1.2.5" + semver "^7.2.2" + +"@aws-cdk/core@1.34.1": + version "1.34.1" + resolved "https://registry.yarnpkg.com/@aws-cdk/core/-/core-1.34.1.tgz#30ed9a457e2f5206180a61939d064cbbf24425b0" + integrity sha512-Lay8Wly6DBTTEJxeW/UNvC0MJbxZcbzSCwxcchHS4KzKaf40CnEIi9jEoSZ2VokjfJCI0KvlXaAB4z1Mt0kGOg== + dependencies: + "@aws-cdk/cloud-assembly-schema" "1.34.1" + "@aws-cdk/cx-api" "1.34.1" + constructs "^3.0.2" + +"@aws-cdk/cx-api@1.34.1": + version "1.34.1" + resolved "https://registry.yarnpkg.com/@aws-cdk/cx-api/-/cx-api-1.34.1.tgz#f1e5ca6f5c6315047e01f07aa8da34acad368a83" + integrity sha512-6eS08/6/iZPbsKeUlnmmflPYHirk3DSocSSRWCsmx9vcb2xQgHKJaWJWPcPXeaPyK3BuTe0Zw/XsC2SVD+u30Q== + dependencies: + "@aws-cdk/cloud-assembly-schema" "1.34.1" + semver "^7.2.2" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" @@ -2636,11 +2668,6 @@ anymatch@^3.0.3: normalize-path "^3.0.0" picomatch "^2.0.4" -app-root-path@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" - integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== - append-transform@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" @@ -2891,7 +2918,7 @@ available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: dependencies: array-filter "^1.0.0" -aws-sdk-mock@^5.0.0, aws-sdk-mock@^5.1.0: +aws-sdk-mock@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/aws-sdk-mock/-/aws-sdk-mock-5.1.0.tgz#6f2c0bd670d7f378c906a8dd806f812124db71aa" integrity sha512-Wa5eCSo8HX0Snqb7FdBylaXMmfrAWoWZ+d7MFhiYsgHPvNvMEGjV945FF2qqE1U0Tolr1ALzik1fcwgaOhqUWQ== @@ -2900,25 +2927,10 @@ aws-sdk-mock@^5.0.0, aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" -aws-sdk@^2.596.0: - version "2.650.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.650.0.tgz#edf995cf2805c918d7470a652f1316ae902c5aa4" - integrity sha512-MlTKXeRSe4IXXqnulAiXZccpTgDafs3ofYIQv/7ApR+oQUFsq96RHwe8MdW9N1cXn7fz302jLXUAykj4boR3DA== - dependencies: - buffer "4.9.1" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.15.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - uuid "3.3.2" - xml2js "0.4.19" - -aws-sdk@^2.637.0, aws-sdk@^2.660.0: - version "2.660.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.660.0.tgz#1be2f814ffdb1aadf859b252601974073a39a4b2" - integrity sha512-6FR91Jg1x9TuFglsdBHkRuE4X7sPRwqeTB2GwLk9XPX1giicdMvJrWbcw5rUnMKjXs9LVlkwaK5VI9AJ0d8dpw== +aws-sdk@^2.637.0, aws-sdk@^2.661.0: + version "2.661.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.661.0.tgz#e877dbc0d07b74e93e2383eb4cd0407592b1e46e" + integrity sha512-dfGtbRQQUmcpj6WGVhj7q2PADCvDhLf+/aRGPXcMrm0cnHavkmHPVaSvrw2lJJJ5N9MsBKoUyacrVcIQkfNsgw== dependencies: buffer "4.9.1" events "1.1.1" @@ -4892,21 +4904,11 @@ dotenv-expand@^5.1.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== -dotenv-json@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dotenv-json/-/dotenv-json-1.0.0.tgz#fc7f672aafea04bed33818733b9f94662332815c" - integrity sha512-jAssr+6r4nKhKRudQ0HOzMskOFFi9+ubXWwmrSGJFgTvpjyPXCXsCsYbjif6mXp7uxA7xY3/LGaiTQukZzSbOQ== - dotenv@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== -dotenv@^8.0.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - dotgitignore@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/dotgitignore/-/dotgitignore-2.1.0.tgz#a4b15a4e4ef3cf383598aaf1dfa4a04bcc089b7b" @@ -5141,11 +5143,6 @@ escodegen@~1.9.0: optionalDependencies: source-map "~0.6.1" -eslint-config-standard@^14.1.0: - version "14.1.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" - integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg== - eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" @@ -5173,15 +5170,7 @@ eslint-module-utils@^2.4.1: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-es@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz#0f5f5da5f18aa21989feebe8a73eadefb3432976" - integrity sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ== - dependencies: - eslint-utils "^1.4.2" - regexpp "^3.0.0" - -eslint-plugin-import@^2.19.1, eslint-plugin-import@^2.20.2: +eslint-plugin-import@^2.20.2: version "2.20.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d" integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg== @@ -5199,28 +5188,6 @@ eslint-plugin-import@^2.19.1, eslint-plugin-import@^2.20.2: read-pkg-up "^2.0.0" resolve "^1.12.0" -eslint-plugin-node@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" - integrity sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ== - dependencies: - eslint-plugin-es "^2.0.0" - eslint-utils "^1.4.2" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - -eslint-plugin-promise@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== - -eslint-plugin-standard@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" - integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== - eslint-scope@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" @@ -5229,7 +5196,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.4.2, eslint-utils@^1.4.3: +eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== @@ -6443,11 +6410,6 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1: - version "5.1.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" - integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== - immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -7834,15 +7796,6 @@ jest@^24.9.0: import-local "^2.0.0" jest-cli "^24.9.0" -jest@^25.3.0: - version "25.3.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.3.0.tgz#7a5e59741d94b8662664c77a9f346246d6bf228b" - integrity sha512-iKd5ShQSHzFT5IL/6h5RZJhApgqXSoPxhp5HEi94v6OAw9QkF8T7X+liEU2eEHJ1eMFYTHmeWLrpBWulsDpaUg== - dependencies: - "@jest/core" "^25.3.0" - import-local "^3.0.2" - jest-cli "^25.3.0" - jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest/-/jest-25.4.0.tgz#fb96892c5c4e4a6b9bcb12068849cddf4c5f8cc7" @@ -8197,24 +8150,6 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -lambda-leak@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lambda-leak/-/lambda-leak-2.0.0.tgz#771985d3628487f6e885afae2b54510dcfb2cd7e" - integrity sha1-dxmF02KEh/boha+uK1RRDc+yzX4= - -lambda-tester@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/lambda-tester/-/lambda-tester-3.6.0.tgz#ceb7d4f4f0da768487a05cff37dcd088508b5247" - integrity sha512-F2ZTGWCLyIR95o/jWK46V/WnOCFAEUG/m/V7/CLhPJ7PCM+pror1rZ6ujP3TkItSGxUfpJi0kqwidw+M/nEqWw== - dependencies: - app-root-path "^2.2.1" - dotenv "^8.0.0" - dotenv-json "^1.0.0" - lambda-leak "^2.0.0" - semver "^6.1.1" - uuid "^3.3.2" - vandium-utils "^1.1.1" - lazystream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" @@ -9005,17 +8940,6 @@ nise@^4.0.1: just-extend "^4.0.2" path-to-regexp "^1.7.0" -nock@^11.7.0: - version "11.9.1" - resolved "https://registry.yarnpkg.com/nock/-/nock-11.9.1.tgz#2b026c5beb6d0dbcb41e7e4cefa671bc36db9c61" - integrity sha512-U5wPctaY4/ar2JJ5Jg4wJxlbBfayxgKbiAeGh+a1kk6Pwnc2ZEuKviLyDSG6t0uXl56q7AALIxoM6FJrBSsVXA== - dependencies: - debug "^4.1.0" - json-stringify-safe "^5.0.1" - lodash "^4.17.13" - mkdirp "^0.5.0" - propagate "^2.0.0" - nock@^12.0.3: version "12.0.3" resolved "https://registry.yarnpkg.com/nock/-/nock-12.0.3.tgz#83f25076dbc4c9aa82b5cdf54c9604c7a778d1c9" @@ -11109,13 +11033,6 @@ resolve@1.x, resolve@^1.1.5, resolve@^1.10.0, resolve@^1.11.1, resolve@^1.12.0, dependencies: path-parse "^1.0.6" -resolve@^1.10.1: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== - dependencies: - path-parse "^1.0.6" - restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -11278,7 +11195,7 @@ semver-intersect@^1.4.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -12449,7 +12366,7 @@ trivial-deferred@^1.0.1: resolved "https://registry.yarnpkg.com/trivial-deferred/-/trivial-deferred-1.0.1.tgz#376d4d29d951d6368a6f7a0ae85c2f4d5e0658f3" integrity sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM= -ts-jest@^25.3.1, ts-jest@^25.4.0: +ts-jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.4.0.tgz#5ad504299f8541d463a52e93e5e9d76876be0ba4" integrity sha512-+0ZrksdaquxGUBwSdTIcdX7VXdwLIlSRsyjivVA9gcO+Cvr6ByqDhu/mi5+HCcb6cMkiQp5xZ8qRO7/eCqLeyw== @@ -12882,11 +12799,6 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -vandium-utils@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/vandium-utils/-/vandium-utils-1.2.0.tgz#44735de4b7641a05de59ebe945f174e582db4f59" - integrity sha1-RHNd5LdkGgXeWevpRfF05YLbT1k= - vendors@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" From cbe735e4c5a740c7e6f304bcd9aa867e4b44a9d8 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 22 Apr 2020 23:44:35 +0200 Subject: [PATCH 16/28] chore: make `run-against-dist` permanently install Verdaccio tool We can't combine `--daemon` with running ephemerally using `npx`, or the directory will be removed too quickly. Fixes the build. --- packages/aws-cdk/test/integ/run-against-dist.bash | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/aws-cdk/test/integ/run-against-dist.bash b/packages/aws-cdk/test/integ/run-against-dist.bash index d429bb3bee446..185365e13f53d 100644 --- a/packages/aws-cdk/test/integ/run-against-dist.bash +++ b/packages/aws-cdk/test/integ/run-against-dist.bash @@ -70,6 +70,10 @@ function serve_npm_packages() { # Start a mock npm repository from the given tarballs #------------------------------------------------------------------------------ header "Starting local NPM Repository" + + # When using '--daemon', 'npm install' first so the files are permanent, or + # 'npx' will remove them too soon. + npm install serve-npm-tarballs eval $(npx serve-npm-tarballs --glob "${tarballs_glob}" --daemon) trap "kill $SERVE_NPM_TARBALLS_PID" EXIT } From 272980492dc6b98d71ce9c3b23cab38f656dc632 Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Wed, 22 Apr 2020 22:54:13 -0700 Subject: [PATCH 17/28] fix(route53): cannot add tags to `HostedZone` (#7531) We don't classify `HostedZoneTags` as the tagging property since it follows a naming convention where it's not called `Tags`. `HostedZoneTags` are also an array of type `HostedZoneTag` objects that enforce the `{Key: "...", Value: "..."}` convention. This is similar to `FileSystemTags` property for `EFS` Closes #7445 --- .../aws-route53/test/test.hosted-zone.ts | 32 +++++++++++++++++++ .../@aws-cdk/cfnspec/lib/schema/property.ts | 6 ++-- .../cfnspec/lib/schema/resource-type.ts | 1 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts b/packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts index f9491ca00c30a..45eaed8e8cafb 100644 --- a/packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/test/test.hosted-zone.ts @@ -1,3 +1,4 @@ +import { expect } from '@aws-cdk/assert'; import * as cdk from '@aws-cdk/core'; import { Test } from 'nodeunit'; import { HostedZone } from '../lib'; @@ -29,4 +30,35 @@ export = { test.done(); }, }, + + 'Supports tags'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const hostedZone = new HostedZone(stack, 'HostedZone', { + zoneName: 'test.zone', + }); + cdk.Tag.add(hostedZone, 'zoneTag', 'inMyZone'); + + // THEN + expect(stack).toMatch({ + Resources: { + HostedZoneDB99F866: { + Type: 'AWS::Route53::HostedZone', + Properties: { + Name: 'test.zone.', + HostedZoneTags: [ + { + Key: 'zoneTag', + Value: 'inMyZone', + }, + ], + }, + }, + }, + }); + + test.done(); + }, }; diff --git a/packages/@aws-cdk/cfnspec/lib/schema/property.ts b/packages/@aws-cdk/cfnspec/lib/schema/property.ts index 21de42c059640..a5d8bc602347f 100644 --- a/packages/@aws-cdk/cfnspec/lib/schema/property.ts +++ b/packages/@aws-cdk/cfnspec/lib/schema/property.ts @@ -87,7 +87,7 @@ export interface ComplexMapProperty extends MapPropertyBase { } export interface TagPropertyStandard extends PropertyBase { - ItemType: 'Tag' | 'TagsEntry' | 'TagRef' | 'ElasticFileSystemTag'; + ItemType: 'Tag' | 'TagsEntry' | 'TagRef' | 'ElasticFileSystemTag' | 'HostedZoneTag'; Type: 'Tags'; } @@ -224,6 +224,7 @@ export function isPropertyScrutinyType(str: string): str is PropertyScrutinyType const tagPropertyNames = { FileSystemTags: '', + HostedZoneTags: '', Tags: '', UserPoolTags: '', }; @@ -257,7 +258,8 @@ export function isTagPropertyStandard(prop: Property): prop is TagPropertyStanda (prop as TagPropertyStandard).ItemType === 'TagsEntry' || (prop as TagPropertyStandard).Type === 'Tags' || (prop as TagPropertyStandard).ItemType === 'TagRef' || - (prop as TagPropertyStandard).ItemType === 'ElasticFileSystemTag' + (prop as TagPropertyStandard).ItemType === 'ElasticFileSystemTag' || + (prop as TagPropertyStandard).ItemType === 'HostedZoneTag' ); } diff --git a/packages/@aws-cdk/cfnspec/lib/schema/resource-type.ts b/packages/@aws-cdk/cfnspec/lib/schema/resource-type.ts index 6150c9bdd3dce..aeccfaa04d86f 100644 --- a/packages/@aws-cdk/cfnspec/lib/schema/resource-type.ts +++ b/packages/@aws-cdk/cfnspec/lib/schema/resource-type.ts @@ -31,6 +31,7 @@ export interface ResourceType extends Documented { export interface TaggableResource extends ResourceType { Properties: { FileSystemTags: TagProperty; + HostedZoneTags: TagProperty; Tags: TagProperty; UserPoolTags: TagProperty; [name: string]: Property; From 6f8ea78288c74ca083ffc453b8e1a492008067cd Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Wed, 22 Apr 2020 23:37:43 -0700 Subject: [PATCH 18/28] chore: remove imagebuilder dependency from decdk and monocdk-experiment This resource was removed in #7504 as it's no longer present in the CloudFormation spec. Dependabot went ahead and bumped up the dependency after it's removal in #7519 removing the dependency from decdk and monocdk-experiment so we don't pull it back in. --- packages/decdk/package.json | 1 - packages/monocdk-experiment/package.json | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/decdk/package.json b/packages/decdk/package.json index fc4ac5fd87b1c..4e049cdbd372c 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -102,7 +102,6 @@ "@aws-cdk/aws-greengrass": "0.0.0", "@aws-cdk/aws-guardduty": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", - "@aws-cdk/aws-imagebuilder": "1.34.1", "@aws-cdk/aws-inspector": "0.0.0", "@aws-cdk/aws-iot": "0.0.0", "@aws-cdk/aws-iot1click": "0.0.0", diff --git a/packages/monocdk-experiment/package.json b/packages/monocdk-experiment/package.json index 39cdffc7e9747..fc4058eedbbca 100644 --- a/packages/monocdk-experiment/package.json +++ b/packages/monocdk-experiment/package.json @@ -169,8 +169,7 @@ "@aws-cdk/aws-codeguruprofiler": "0.0.0", "@aws-cdk/aws-networkmanager": "0.0.0", "@aws-cdk/aws-resourcegroups": "0.0.0", - "@aws-cdk/aws-detective": "0.0.0", - "@aws-cdk/aws-imagebuilder": "1.34.1" + "@aws-cdk/aws-detective": "0.0.0" }, "peerDependencies": { "constructs": "^3.0.2" From 6e0feb0781603d87bcadcabb679f12778b1d44ea Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Thu, 23 Apr 2020 10:13:03 +0300 Subject: [PATCH 19/28] chore(eks): improve bottlerocket disclaimer Make the disclaimer about the beta availability more prominent to set expectations. --- packages/@aws-cdk/aws-eks/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index 84367ed81229f..dd41a74f879d3 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -501,7 +501,9 @@ which will be lower cassed and truncated to the last 63 characters. ### Bottlerocket -[Bottlerocket](https://aws.amazon.com/tw/bottlerocket/) is a Linux-based open-source operating system that is purpose-built by Amazon Web Services for running containers on virtual machines or bare metal hosts. At this moment the managed nodegroup only supports Amazon EKS-optimized AMI but it's possible to create a capacity of self-managed `AutoScalingGroup` running with bottlerocket Linux AMI. +[Bottlerocket](https://aws.amazon.com/bottlerocket/) is a Linux-based open-source operating system that is purpose-built by Amazon Web Services for running containers on virtual machines or bare metal hosts. At this moment the managed nodegroup only supports Amazon EKS-optimized AMI but it's possible to create a capacity of self-managed `AutoScalingGroup` running with bottlerocket Linux AMI. + +> **NOTICE**: Bottlerocket is in public preview and only available in [some supported AWS regions](https://github.com/bottlerocket-os/bottlerocket/blob/develop/QUICKSTART.md#finding-an-ami). The following example will create a capacity with self-managed Amazon EC2 capacity of 2 `t3.small` Linux instances running with `Bottlerocket` AMI. @@ -518,7 +520,6 @@ To define only Bottlerocket capacity in your cluster, set `defaultCapacity` to ` Please note Bottlerocket does not allow to customize bootstrap options and `bootstrapOptions` properties is not supported when you create the `Bottlerocket` capacity. -`Bottlerocket` is now available in public preview and only available in [some supported AWS regions](https://github.com/bottlerocket-os/bottlerocket/blob/develop/QUICKSTART.md#finding-an-ami). ### Roadmap From ddd47cd7e0735424d2e47891c32e4b7813035067 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Thu, 23 Apr 2020 09:55:10 +0100 Subject: [PATCH 20/28] chore(efs): drop Efs prefix from all exported types (#7481) - Drop the `Efs` prefix to the exported types. - Change the type of provisioned throughput property to use `Size`. BREAKING CHANGE: Exported types no longer have the `Efs` prefix. * **efs:** `provisionedThroughputInMibps` property is renamed to `provisionedThroughputPerSecond` and has the type `Size`. * **efs:** The property `fileSystemID` is now renamed to `fileSystemId` in the now named `FileSystemAttributes` (previously, `EfsFileSystemAttributes`). * **efs:** `LifecyclePolicyProperty` is now renamed to `LifecyclePolicy`. --- .../@aws-cdk/aws-efs/lib/efs-file-system.ts | 87 +++++++------------ packages/@aws-cdk/aws-efs/package.json | 8 -- .../aws-efs/test/efs-file-system.test.ts | 87 +++++++------------ 3 files changed, 65 insertions(+), 117 deletions(-) diff --git a/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts b/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts index 3b6337c838c79..e3212e6b1ec68 100644 --- a/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts +++ b/packages/@aws-cdk/aws-efs/lib/efs-file-system.ts @@ -1,15 +1,16 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; -import {Construct, Resource, Tag} from '@aws-cdk/core'; -import {CfnFileSystem, CfnMountTarget} from './efs.generated'; +import { Construct, IResource, Resource, Size, Tag } from '@aws-cdk/core'; +import { CfnFileSystem, CfnMountTarget } from './efs.generated'; -// tslint:disable: max-line-length +// tslint:disable:max-line-length /** * EFS Lifecycle Policy, if a file is not accessed for given days, it will move to EFS Infrequent Access. * * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html#cfn-elasticfilesystem-filesystem-lifecyclepolicies */ -export enum EfsLifecyclePolicyProperty { +// tslint:enable +export enum LifecyclePolicy { /** * After 7 days of not being accessed. */ @@ -41,7 +42,7 @@ export enum EfsLifecyclePolicyProperty { * * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html#cfn-efs-filesystem-performancemode */ -export enum EfsPerformanceMode { +export enum PerformanceMode { /** * This is the general purpose performance mode for most file systems. */ @@ -59,7 +60,7 @@ export enum EfsPerformanceMode { * * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html#cfn-elasticfilesystem-filesystem-throughputmode */ -export enum EfsThroughputMode { +export enum ThroughputMode { /** * This mode on Amazon EFS scales as the size of the file system in the standard storage class grows. */ @@ -74,7 +75,7 @@ export enum EfsThroughputMode { /** * Interface to implement AWS File Systems. */ -export interface IEfsFileSystem extends ec2.IConnectable { +export interface IFileSystem extends ec2.IConnectable, IResource { /** * The ID of the file system, assigned by Amazon EFS. * @@ -86,7 +87,7 @@ export interface IEfsFileSystem extends ec2.IConnectable { /** * Properties of EFS FileSystem. */ -export interface EfsFileSystemProps { +export interface FileSystemProps { /** * VPC to launch the file system in. @@ -133,51 +134,36 @@ export interface EfsFileSystemProps { * * @default - none */ - readonly lifecyclePolicy?: EfsLifecyclePolicyProperty; + readonly lifecyclePolicy?: LifecyclePolicy; /** * Enum to mention the performance mode of the file system. * * @default - GENERAL_PURPOSE */ - readonly performanceMode?: EfsPerformanceMode; + readonly performanceMode?: PerformanceMode; /** * Enum to mention the throughput mode of the file system. * * @default - BURSTING */ - readonly throughputMode?: EfsThroughputMode; + readonly throughputMode?: ThroughputMode; /** - * Provisioned throughput for the file system. This is a required property if the throughput mode is set to PROVISIONED. - * Valid values are 1-1024. + * Provisioned throughput for the file system. + * This is a required property if the throughput mode is set to PROVISIONED. + * Must be at least 1MiB/s. * - * @default - None, errors out + * @default - none, errors out */ - readonly provisionedThroughputInMibps?: number; -} - -/** - * A new or imported EFS File System. - */ -abstract class EfsFileSystemBase extends Resource implements IEfsFileSystem { - - /** - * The security groups/rules used to allow network connections to the file system. - */ - public abstract readonly connections: ec2.Connections; - - /** - * @attribute - */ - public abstract readonly fileSystemId: string; + readonly provisionedThroughputPerSecond?: Size; } /** * Properties that describe an existing EFS file system. */ -export interface EfsFileSystemAttributes { +export interface FileSystemAttributes { /** * The security group of the file system */ @@ -186,7 +172,7 @@ export interface EfsFileSystemAttributes { /** * The File System's ID. */ - readonly fileSystemID: string; + readonly fileSystemId: string; } /** @@ -199,17 +185,17 @@ export interface EfsFileSystemAttributes { * * @resource AWS::EFS::FileSystem */ -export class EfsFileSystem extends EfsFileSystemBase { +export class FileSystem extends Resource implements IFileSystem { /** * Import an existing File System from the given properties. */ - public static fromEfsFileSystemAttributes(scope: Construct, id: string, attrs: EfsFileSystemAttributes): IEfsFileSystem { - class Import extends EfsFileSystemBase implements IEfsFileSystem { - public readonly fileSystemId = attrs.fileSystemID; + public static fromFileSystemAttributes(scope: Construct, id: string, attrs: FileSystemAttributes): IFileSystem { + class Import extends Resource implements IFileSystem { + public readonly fileSystemId = attrs.fileSystemId; public readonly connections = new ec2.Connections({ securityGroups: [attrs.securityGroup], - defaultPort: ec2.Port.tcp(EfsFileSystem.DEFAULT_PORT), + defaultPort: ec2.Port.tcp(FileSystem.DEFAULT_PORT), }); } @@ -231,37 +217,28 @@ export class EfsFileSystem extends EfsFileSystemBase { */ public readonly fileSystemId: string; - private readonly efsFileSystem: CfnFileSystem; - /** * Constructor for creating a new EFS FileSystem. */ - constructor(scope: Construct, id: string, props: EfsFileSystemProps) { + constructor(scope: Construct, id: string, props: FileSystemProps) { super(scope, id); - if (props.throughputMode === EfsThroughputMode.PROVISIONED) { - if (props.provisionedThroughputInMibps === undefined) { - throw new Error('Property provisionedThroughputInMibps is required when throughputMode is PROVISIONED'); - } else if (!Number.isInteger(props.provisionedThroughputInMibps)) { - throw new Error('Invalid input for provisionedThroughputInMibps'); - } else if (props.provisionedThroughputInMibps < 1 || props.provisionedThroughputInMibps > 1024) { - this.node.addWarning('Valid values for throughput are 1-1024 MiB/s. You can get this limit increased by contacting AWS Support.'); - } + if (props.throughputMode === ThroughputMode.PROVISIONED && props.provisionedThroughputPerSecond === undefined) { + throw new Error('Property provisionedThroughputPerSecond is required when throughputMode is PROVISIONED'); } - this.efsFileSystem = new CfnFileSystem(this, 'Resource', { + const filesystem = new CfnFileSystem(this, 'Resource', { encrypted: props.encrypted, kmsKeyId: (props.kmsKey ? props.kmsKey.keyId : undefined), lifecyclePolicies: (props.lifecyclePolicy ? Array.of({ - transitionToIa: EfsLifecyclePolicyProperty[props.lifecyclePolicy], + transitionToIa: LifecyclePolicy[props.lifecyclePolicy], } as CfnFileSystem.LifecyclePolicyProperty) : undefined), performanceMode: props.performanceMode, throughputMode: props.throughputMode, - provisionedThroughputInMibps: props.provisionedThroughputInMibps, + provisionedThroughputInMibps: props.provisionedThroughputPerSecond?.toMebibytes(), }); - this.fileSystemId = this.efsFileSystem.ref; - this.node.defaultChild = this.efsFileSystem; + this.fileSystemId = filesystem.ref; Tag.add(this, 'Name', props.fileSystemName || this.node.path); const securityGroup = (props.securityGroup || new ec2.SecurityGroup(this, 'EfsSecurityGroup', { @@ -270,7 +247,7 @@ export class EfsFileSystem extends EfsFileSystemBase { this.connections = new ec2.Connections({ securityGroups: [securityGroup], - defaultPort: ec2.Port.tcp(EfsFileSystem.DEFAULT_PORT), + defaultPort: ec2.Port.tcp(FileSystem.DEFAULT_PORT), }); const subnets = props.vpc.selectSubnets(props.vpcSubnets); diff --git a/packages/@aws-cdk/aws-efs/package.json b/packages/@aws-cdk/aws-efs/package.json index ba875fb4bfa7b..5e3fd641cddca 100644 --- a/packages/@aws-cdk/aws-efs/package.json +++ b/packages/@aws-cdk/aws-efs/package.json @@ -104,14 +104,6 @@ "engines": { "node": ">= 10.12.0" }, - "awslint": { - "exclude": [ - "props-physical-name:@aws-cdk/aws-efs.EfsFileSystemProps", - "resource-interface:@aws-cdk/aws-efs.EfsFileSystem", - "construct-interface-extends-iconstruct:@aws-cdk/aws-efs.IEfsFileSystem", - "resource-interface-extends-resource:@aws-cdk/aws-efs.IEfsFileSystem" - ] - }, "stability": "experimental", "maturity": "experimental", "awscdkio": { diff --git a/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts b/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts index 2aef981984a5b..d9c2cf12f0dac 100644 --- a/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts +++ b/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts @@ -1,9 +1,8 @@ import {expect as expectCDK, haveResource} from '@aws-cdk/assert'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; -import * as cxschema from '@aws-cdk/cloud-assembly-schema'; -import {Stack, Tag} from '@aws-cdk/core'; -import {EfsFileSystem, EfsLifecyclePolicyProperty, EfsPerformanceMode, EfsThroughputMode} from '../lib/efs-file-system'; +import { Size, Stack, Tag } from '@aws-cdk/core'; +import { FileSystem, LifecyclePolicy, PerformanceMode, ThroughputMode} from '../lib'; let stack = new Stack(); let vpc = new ec2.Vpc(stack, 'VPC'); @@ -15,7 +14,7 @@ beforeEach( () => { test('default file system is created correctly', () => { // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, }); // THEN @@ -26,7 +25,7 @@ test('default file system is created correctly', () => { test('unencrypted file system is created correctly with default KMS', () => { // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, encrypted: false, }); @@ -38,7 +37,7 @@ test('unencrypted file system is created correctly with default KMS', () => { test('encrypted file system is created correctly with default KMS', () => { // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, encrypted: true, }); @@ -52,7 +51,7 @@ test('encrypted file system is created correctly with custom KMS', () => { const key = new kms.Key(stack, 'customKeyFS'); // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, encrypted: true, kmsKey: key, @@ -75,9 +74,9 @@ test('encrypted file system is created correctly with custom KMS', () => { test('file system is created correctly with life cycle property', () => { // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, - lifecyclePolicy: EfsLifecyclePolicyProperty.AFTER_14_DAYS, + lifecyclePolicy: LifecyclePolicy.AFTER_14_DAYS, }); // THEN expectCDK(stack).to(haveResource('AWS::EFS::FileSystem', { @@ -89,9 +88,9 @@ test('file system is created correctly with life cycle property', () => { test('file system is created correctly with performance mode', () => { // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, - performanceMode: EfsPerformanceMode.MAX_IO, + performanceMode: PerformanceMode.MAX_IO, }); // THEN expectCDK(stack).to(haveResource('AWS::EFS::FileSystem', { @@ -101,9 +100,9 @@ test('file system is created correctly with performance mode', () => { test('file system is created correctly with bursting throughput mode', () => { // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, - throughputMode: EfsThroughputMode.BURSTING, + throughputMode: ThroughputMode.BURSTING, }); // THEN expectCDK(stack).to(haveResource('AWS::EFS::FileSystem', { @@ -113,57 +112,37 @@ test('file system is created correctly with bursting throughput mode', () => { test('Exception when throughput mode is set to PROVISIONED, but provisioned throughput is not set', () => { expect(() => { - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, - throughputMode: EfsThroughputMode.PROVISIONED, + throughputMode: ThroughputMode.PROVISIONED, }); - }).toThrowError(/Property provisionedThroughputInMibps is required when throughputMode is PROVISIONED/); + }).toThrowError(/Property provisionedThroughputPerSecond is required when throughputMode is PROVISIONED/); }); -test('Warning when provisioned throughput is less than the valid range', () => { - const fileSystem = new EfsFileSystem(stack, 'EfsFileSystem', { +test('fails when provisioned throughput is less than the valid range', () => { + expect(() => new FileSystem(stack, 'EfsFileSystem', { vpc, - throughputMode: EfsThroughputMode.PROVISIONED, - provisionedThroughputInMibps: 0, - }); - - expect(fileSystem.node.metadata[0].type).toMatch(cxschema.ArtifactMetadataEntryType.WARN); - expect(fileSystem.node.metadata[0].data).toContain('Valid values for throughput are 1-1024 MiB/s'); - expect(fileSystem.node.metadata[0].data).toContain('You can get this limit increased by contacting AWS Support'); - - expectCDK(stack).to(haveResource('AWS::EFS::FileSystem')); -}); - -test('Warning when provisioned throughput is above than the valid range', () => { - const fileSystem = new EfsFileSystem(stack, 'EfsFileSystem1', { - vpc, - throughputMode: EfsThroughputMode.PROVISIONED, - provisionedThroughputInMibps: 1025, - }); - - expect(fileSystem.node.metadata[0].type).toMatch(cxschema.ArtifactMetadataEntryType.WARN); - expect(fileSystem.node.metadata[0].data).toContain('Valid values for throughput are 1-1024 MiB/s'); - expect(fileSystem.node.metadata[0].data).toContain('You can get this limit increased by contacting AWS Support'); - - expectCDK(stack).to(haveResource('AWS::EFS::FileSystem')); + throughputMode: ThroughputMode.PROVISIONED, + provisionedThroughputPerSecond: Size.kibibytes(10), + })).toThrow(/cannot be converted into a whole number/); }); -test('Error when provisioned throughput is invalid number', () => { +test('fails when provisioned throughput is not a whole number of mebibytes', () => { expect(() => { - new EfsFileSystem(stack, 'EfsFileSystem2', { + new FileSystem(stack, 'EfsFileSystem2', { vpc, - throughputMode: EfsThroughputMode.PROVISIONED, - provisionedThroughputInMibps: 1.5, + throughputMode: ThroughputMode.PROVISIONED, + provisionedThroughputPerSecond: Size.kibibytes(2050), }); - }).toThrowError(/Invalid input for provisionedThroughputInMibps/); + }).toThrowError(/cannot be converted into a whole number/); }); test('file system is created correctly with provisioned throughput mode', () => { // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { vpc, - throughputMode: EfsThroughputMode.PROVISIONED, - provisionedThroughputInMibps: 5, + throughputMode: ThroughputMode.PROVISIONED, + provisionedThroughputPerSecond: Size.mebibytes(5), }); // THEN expectCDK(stack).to(haveResource('AWS::EFS::FileSystem', { @@ -174,8 +153,8 @@ test('file system is created correctly with provisioned throughput mode', () => test('existing file system is imported correctly', () => { // WHEN - const fs = EfsFileSystem.fromEfsFileSystemAttributes(stack, 'existingFS', { - fileSystemID: 'fs123', + const fs = FileSystem.fromFileSystemAttributes(stack, 'existingFS', { + fileSystemId: 'fs123', securityGroup: ec2.SecurityGroup.fromSecurityGroupId(stack, 'SG', 'sg-123456789', { allowAllOutbound: false, }), @@ -191,7 +170,7 @@ test('existing file system is imported correctly', () => { test('support tags', () => { // WHEN - const fileSystem = new EfsFileSystem(stack, 'EfsFileSystem', { + const fileSystem = new FileSystem(stack, 'EfsFileSystem', { vpc, }); Tag.add(fileSystem, 'Name', 'LookAtMeAndMyFancyTags'); @@ -206,7 +185,7 @@ test('support tags', () => { test('file system is created correctly when given a name', () => { // WHEN - new EfsFileSystem(stack, 'EfsFileSystem', { + new FileSystem(stack, 'EfsFileSystem', { fileSystemName: 'MyNameableFileSystem', vpc, }); @@ -221,7 +200,7 @@ test('file system is created correctly when given a name', () => { test('auto-named if none provided', () => { // WHEN - const fileSystem = new EfsFileSystem(stack, 'EfsFileSystem', { + const fileSystem = new FileSystem(stack, 'EfsFileSystem', { vpc, }); From 4a70138faf2e863be37a66bec23ed29a784b486a Mon Sep 17 00:00:00 2001 From: Ryan Bright Date: Thu, 23 Apr 2020 05:30:55 -0400 Subject: [PATCH 21/28] feat(cloudtrail): Lambda Function data events This adds support for the `AWS::Lambda::Function` [data event resource type](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudtrail-trail-dataresource.html). I wasn't able to find any GitHub issues that will be resolved with this, but it's possible that I overlooked one. --- packages/@aws-cdk/aws-cloudtrail/README.md | 21 ++++++ .../@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts | 69 ++++++++++++++++--- packages/@aws-cdk/aws-cloudtrail/package.json | 2 + ...oudtrail-supplied-bucket.lit.expected.json | 65 +++++++++++++++++ .../integ.cloudtrail-supplied-bucket.lit.ts | 7 ++ .../test/integ.cloudtrail.lit.expected.json | 65 +++++++++++++++++ .../test/integ.cloudtrail.lit.ts | 7 ++ .../aws-cloudtrail/test/test.cloudtrail.ts | 54 +++++++++++++++ 8 files changed, 280 insertions(+), 10 deletions(-) diff --git a/packages/@aws-cdk/aws-cloudtrail/README.md b/packages/@aws-cdk/aws-cloudtrail/README.md index e96ebebc78451..41aaa675aa6c2 100644 --- a/packages/@aws-cdk/aws-cloudtrail/README.md +++ b/packages/@aws-cdk/aws-cloudtrail/README.md @@ -72,3 +72,24 @@ trail.addS3EventSelector(["arn:aws:s3:::foo/"], { readWriteType: ReadWriteType.ALL, }); ``` + +For using CloudTrail event selector to log events about Lambda +functions, you can use `addLambdaEventSelector`. + +```ts +import cloudtrail = require('@aws-cdk/aws-cloudtrail'); +import lambda = require('@aws-cdk/aws-lambda'); + +const trail = new cloudtrail.Trail(this, 'MyAmazingCloudTrail'); +const lambdaFunction = new lambda.Function(stack, 'AnAmazingFunction', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: "hello.handler", + code: lambda.Code.fromAsset("lambda"), +}); + +// Add an event selector to log data events for all functions in the account. +trail.addLambdaEventSelector(["arn:aws:lambda"]); + +// Add an event selector to log data events for the provided Lambda functions. +trail.addLambdaEventSelector([lambdaFunction.functionArn]); +``` \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts b/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts index f9a55fa864add..d5ada2f9e1662 100644 --- a/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts +++ b/packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts @@ -222,31 +222,65 @@ export class Trail extends Resource { * When an event occurs in your account, CloudTrail evaluates whether the event matches the settings for your trails. * Only events that match your trail settings are delivered to your Amazon S3 bucket and Amazon CloudWatch Logs log group. * - * This method adds an S3 Data Event Selector for filtering events that match S3 operations. + * This method adds an Event Selector for filtering events that match either S3 or Lambda function operations. * * Data events: These events provide insight into the resource operations performed on or within a resource. * These are also known as data plane operations. * - * @param prefixes the list of object ARN prefixes to include in logging (maximum 250 entries). + * @param dataResourceValues the list of data resource ARNs to include in logging (maximum 250 entries). * @param options the options to configure logging of management and data events. */ - public addS3EventSelector(prefixes: string[], options: AddS3EventSelectorOptions = {}) { - if (prefixes.length > 250) { + public addEventSelector(dataResourceType: DataResourceType, dataResourceValues: string[], options: AddEventSelectorOptions = {}) { + if (dataResourceValues.length > 250) { throw new Error('A maximum of 250 data elements can be in one event selector'); } + if (this.eventSelectors.length > 5) { throw new Error('A maximum of 5 event selectors are supported per trail.'); } + this.eventSelectors.push({ - includeManagementEvents: options.includeManagementEvents, - readWriteType: options.readWriteType, dataResources: [{ - type: 'AWS::S3::Object', - values: prefixes, + type: dataResourceType, + values: dataResourceValues, }], + includeManagementEvents: options.includeManagementEvents, + readWriteType: options.readWriteType, }); } + /** + * When an event occurs in your account, CloudTrail evaluates whether the event matches the settings for your trails. + * Only events that match your trail settings are delivered to your Amazon S3 bucket and Amazon CloudWatch Logs log group. + * + * This method adds a Lambda Data Event Selector for filtering events that match Lambda function operations. + * + * Data events: These events provide insight into the resource operations performed on or within a resource. + * These are also known as data plane operations. + * + * @param dataResourceValues the list of data resource ARNs to include in logging (maximum 250 entries). + * @param options the options to configure logging of management and data events. + */ + public addLambdaEventSelector(dataResourceValues: string[], options: AddEventSelectorOptions = {}) { + return this.addEventSelector(DataResourceType.LAMBDA_FUNCTION, dataResourceValues, options); + } + + /** + * When an event occurs in your account, CloudTrail evaluates whether the event matches the settings for your trails. + * Only events that match your trail settings are delivered to your Amazon S3 bucket and Amazon CloudWatch Logs log group. + * + * This method adds an S3 Data Event Selector for filtering events that match S3 operations. + * + * Data events: These events provide insight into the resource operations performed on or within a resource. + * These are also known as data plane operations. + * + * @param dataResourceValues the list of data resource ARNs to include in logging (maximum 250 entries). + * @param options the options to configure logging of management and data events. + */ + public addS3EventSelector(dataResourceValues: string[], options: AddEventSelectorOptions = {}) { + return this.addEventSelector(DataResourceType.S3_OBJECT, dataResourceValues, options); + } + /** * Create an event rule for when an event is recorded by any Trail in the account. * @@ -266,9 +300,9 @@ export class Trail extends Resource { } /** - * Options for adding an S3 event selector. + * Options for adding an event selector. */ -export interface AddS3EventSelectorOptions { +export interface AddEventSelectorOptions { /** * Specifies whether to log read-only events, write-only events, or all events. * @@ -284,6 +318,21 @@ export interface AddS3EventSelectorOptions { readonly includeManagementEvents?: boolean; } +/** + * Resource type for a data event + */ +export enum DataResourceType { + /** + * Data resource type for Lambda function + */ + LAMBDA_FUNCTION = 'AWS::Lambda::Function', + + /** + * Data resource type for S3 objects + */ + S3_OBJECT = 'AWS::S3::Object', +} + interface EventSelector { readonly includeManagementEvents?: boolean; readonly readWriteType?: ReadWriteType; diff --git a/packages/@aws-cdk/aws-cloudtrail/package.json b/packages/@aws-cdk/aws-cloudtrail/package.json index 6940b61dbcdad..e345112c26b74 100644 --- a/packages/@aws-cdk/aws-cloudtrail/package.json +++ b/packages/@aws-cdk/aws-cloudtrail/package.json @@ -76,6 +76,7 @@ "@aws-cdk/aws-events": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", + "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/core": "0.0.0", @@ -86,6 +87,7 @@ "@aws-cdk/aws-events": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", + "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-supplied-bucket.lit.expected.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-supplied-bucket.lit.expected.json index 2a4bed6ae5e55..86773e090a9fe 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-supplied-bucket.lit.expected.json +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-supplied-bucket.lit.expected.json @@ -5,6 +5,56 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "LambdaFunctionServiceRoleC555A460": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaFunctionBF21E41F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = {}" + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRoleC555A460", + "Arn" + ] + }, + "Runtime": "nodejs10.x" + }, + "DependsOn": [ + "LambdaFunctionServiceRoleC555A460" + ] + }, "S3486F821D": { "Type": "AWS::S3::Bucket", "UpdateReplacePolicy": "Retain", @@ -75,6 +125,21 @@ }, "EnableLogFileValidation": true, "EventSelectors": [ + { + "DataResources": [ + { + "Type": "AWS::Lambda::Function", + "Values": [ + { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + } + ] + } + ] + }, { "DataResources": [ { diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-supplied-bucket.lit.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-supplied-bucket.lit.ts index f596934f2e336..fa57b1f2caf05 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-supplied-bucket.lit.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail-supplied-bucket.lit.ts @@ -1,4 +1,5 @@ import * as iam from '@aws-cdk/aws-iam'; +import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; @@ -8,6 +9,11 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'integ-cloudtrail'); const bucket = new s3.Bucket(stack, 'Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY }); +const lambdaFunction = new lambda.Function(stack, 'LambdaFunction', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'hello.handler', + code: lambda.Code.fromInline('exports.handler = {}'), +}); // using exctecy the same code as inside the cloudtrail class to produce the supplied bucket and policy const cloudTrailPrincipal = new iam.ServicePrincipal('cloudtrail.amazonaws.com'); @@ -31,6 +37,7 @@ Trailbucket.addToResourcePolicy(new iam.PolicyStatement({ const trail = new cloudtrail.Trail(stack, 'Trail', {bucket: Trailbucket}); +trail.addLambdaEventSelector([lambdaFunction.functionArn]); trail.addS3EventSelector([bucket.arnForObjects('')]); app.synth(); diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.expected.json b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.expected.json index 8cb7e7df565dc..06cf3a82e0331 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.expected.json +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.expected.json @@ -5,6 +5,56 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "LambdaFunctionServiceRoleC555A460": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaFunctionBF21E41F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = {}" + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "LambdaFunctionServiceRoleC555A460", + "Arn" + ] + }, + "Runtime": "nodejs10.x" + }, + "DependsOn": [ + "LambdaFunctionServiceRoleC555A460" + ] + }, "TrailS30071F172": { "Type": "AWS::S3::Bucket", "UpdateReplacePolicy": "Retain", @@ -75,6 +125,21 @@ }, "EnableLogFileValidation": true, "EventSelectors": [ + { + "DataResources": [ + { + "Type": "AWS::Lambda::Function", + "Values": [ + { + "Fn::GetAtt": [ + "LambdaFunctionBF21E41F", + "Arn" + ] + } + ] + } + ] + }, { "DataResources": [ { diff --git a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts index e707ce811f09a..bee7fc432d6ed 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/integ.cloudtrail.lit.ts @@ -1,3 +1,4 @@ +import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; import * as cloudtrail from '../lib'; @@ -6,8 +7,14 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'integ-cloudtrail'); const bucket = new s3.Bucket(stack, 'Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY }); +const lambdaFunction = new lambda.Function(stack, 'LambdaFunction', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'hello.handler', + code: lambda.Code.fromInline('exports.handler = {}'), +}); const trail = new cloudtrail.Trail(stack, 'Trail'); +trail.addLambdaEventSelector([lambdaFunction.functionArn]); trail.addS3EventSelector([bucket.arnForObjects('')]); app.synth(); diff --git a/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts b/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts index a257ca05db361..5138395d43be4 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/test.cloudtrail.ts @@ -1,5 +1,6 @@ import { expect, haveResource, not, SynthUtils } from '@aws-cdk/assert'; import * as iam from '@aws-cdk/aws-iam'; +import * as lambda from '@aws-cdk/aws-lambda'; import { RetentionDays } from '@aws-cdk/aws-logs'; import * as s3 from '@aws-cdk/aws-s3'; import { Stack } from '@aws-cdk/core'; @@ -273,6 +274,59 @@ export = { test.equals(selector.DataResources, undefined, 'Expected there to be no data resources'); test.done(); }, + + 'for Lambda function data event'(test: Test) { + const stack = getTestStack(); + const lambdaFunction = new lambda.Function(stack, 'LambdaFunction', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'hello.handler', + code: lambda.Code.fromInline('exports.handler = {}'), + }); + + const cloudTrail = new Trail(stack, 'MyAmazingCloudTrail'); + cloudTrail.addLambdaEventSelector([lambdaFunction.functionArn]); + + expect(stack).to(haveResource('AWS::CloudTrail::Trail')); + expect(stack).to(haveResource('AWS::Lambda::Function')); + expect(stack).to(not(haveResource('AWS::Logs::LogGroup'))); + + const trail: any = SynthUtils.synthesize(stack).template.Resources.MyAmazingCloudTrail54516E8D; + test.equals(trail.Properties.EventSelectors.length, 1); + const selector = trail.Properties.EventSelectors[0]; + test.equals(selector.ReadWriteType, null, 'Expected selector read write type to be undefined'); + test.equals(selector.IncludeManagementEvents, null, 'Expected management events to be undefined'); + test.equals(selector.DataResources.length, 1, 'Expected there to be one data resource'); + const dataResource = selector.DataResources[0]; + test.equals(dataResource.Type, 'AWS::Lambda::Function', 'Expected the data resrouce type to be AWS::Lambda::Function'); + test.equals(dataResource.Values.length, 1, 'Expected there to be one value'); + test.deepEqual(dataResource.Values[0], { 'Fn::GetAtt': [ 'LambdaFunctionBF21E41F', 'Arn' ] }, 'Expected the first type value to be the Lambda type'); + test.deepEqual(trail.DependsOn, ['MyAmazingCloudTrailS3Policy39C120B0']); + test.done(); + }, + + 'for all Lambda function data events'(test: Test) { + const stack = getTestStack(); + + const cloudTrail = new Trail(stack, 'MyAmazingCloudTrail'); + cloudTrail.addLambdaEventSelector(['arn:aws:lambda']); + + expect(stack).to(haveResource('AWS::CloudTrail::Trail')); + expect(stack).to(not(haveResource('AWS::Logs::LogGroup'))); + expect(stack).to(not(haveResource('AWS::IAM::Role'))); + + const trail: any = SynthUtils.synthesize(stack).template.Resources.MyAmazingCloudTrail54516E8D; + test.equals(trail.Properties.EventSelectors.length, 1); + const selector = trail.Properties.EventSelectors[0]; + test.equals(selector.ReadWriteType, null, 'Expected selector read write type to be undefined'); + test.equals(selector.IncludeManagementEvents, null, 'Expected management events to be undefined'); + test.equals(selector.DataResources.length, 1, 'Expected there to be one data resource'); + const dataResource = selector.DataResources[0]; + test.equals(dataResource.Type, 'AWS::Lambda::Function', 'Expected the data resource type to be AWS::Lambda::Function'); + test.equals(dataResource.Values.length, 1, 'Expected there to be one value'); + test.equals(dataResource.Values[0], 'arn:aws:lambda', 'Expected the first type value to be the Lambda type'); + test.deepEqual(trail.DependsOn, ['MyAmazingCloudTrailS3Policy39C120B0']); + test.done(); + }, }, }, From 00c9deb975fe794eef9003cd26a6453abc514928 Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Thu, 23 Apr 2020 12:06:03 +0200 Subject: [PATCH 22/28] fix(assets): infrequent "ValidationError: S3 error: Access Denied" (#7556) We're checking if an asset exists in S3 before uploading (to avoid re-uploading possibly large assets). This causes HEAD/GET-after-PUT to become eventually consistent because it creates a negative cache entry! This switches to using a LIST-based check, which will not create a negative cache entry, and preserve the immediate consistency of GET-after-PUT in this workflow. BREAKING CHANGE: `cdk deploy` now needs `s3:ListBucket` instead of `s3:HeadObject`. Fixes #6430 Fixes #7553 --- .../cdk-assets/lib/private/handlers/files.ts | 25 +++++++------- packages/cdk-assets/test/files.test.ts | 33 ++++++++++++++----- packages/cdk-assets/test/placeholders.test.ts | 7 ++-- packages/cdk-assets/test/progress.test.ts | 4 +-- packages/cdk-assets/test/zipping.test.ts | 4 +-- packages/cdk-assets/tsconfig.json | 3 ++ 6 files changed, 50 insertions(+), 26 deletions(-) diff --git a/packages/cdk-assets/lib/private/handlers/files.ts b/packages/cdk-assets/lib/private/handlers/files.ts index 0baf42185da63..bedf2e5a02aa8 100644 --- a/packages/cdk-assets/lib/private/handlers/files.ts +++ b/packages/cdk-assets/lib/private/handlers/files.ts @@ -95,14 +95,17 @@ async function bucketOwnership(s3: AWS.S3, bucket: string): Promise object.Key === key); +} diff --git a/packages/cdk-assets/test/files.test.ts b/packages/cdk-assets/test/files.test.ts index 5b8efe537648f..cbd7b08ba32a1 100644 --- a/packages/cdk-assets/test/files.test.ts +++ b/packages/cdk-assets/test/files.test.ts @@ -1,7 +1,7 @@ import { AssetManifestSchema } from '@aws-cdk/cdk-assets-schema'; import * as mockfs from 'mock-fs'; import { AssetManifest, AssetPublishing } from '../lib'; -import { mockAws, mockedApiFailure, mockedApiResult, mockUpload } from './mock-aws'; +import { mockAws, mockedApiResult, mockUpload } from './mock-aws'; let aws: ReturnType; beforeEach(() => { @@ -66,20 +66,37 @@ test('pass destination properties to AWS client', async () => { test('Do nothing if file already exists', async () => { const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out') , { aws }); - aws.mockS3.headObject = mockedApiResult({ /* No error == file exists */ }); + aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: [{ Key: 'some_key' }] }); await pub.publish(); - expect(aws.mockS3.headObject).toHaveBeenCalledWith(expect.objectContaining({ + expect(aws.mockS3.listObjectsV2).toHaveBeenCalledWith(expect.objectContaining({ + Bucket: 'some_bucket', + Prefix: 'some_key', + MaxKeys: 1, + })); +}); + +test('upload file if new (list returns other key)', async () => { + const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); + + aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: [{ Key: 'some_key.but_not_the_one' }] }); + aws.mockS3.upload = mockUpload('FILE_CONTENTS'); + + await pub.publish(); + + expect(aws.mockS3.upload).toHaveBeenCalledWith(expect.objectContaining({ Bucket: 'some_bucket', Key: 'some_key', })); + + // We'll just have to assume the contents are correct }); -test('upload file if new', async () => { +test('upload file if new (list returns no key)', async () => { const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - aws.mockS3.headObject = mockedApiFailure('NotFound', 'File does not exist'); + aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); aws.mockS3.upload = mockUpload('FILE_CONTENTS'); await pub.publish(); @@ -95,7 +112,7 @@ test('upload file if new', async () => { test('successful run does not need to query account ID', async () => { const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - aws.mockS3.headObject = mockedApiFailure('NotFound', 'File does not exist'); + aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); aws.mockS3.upload = mockUpload('FILE_CONTENTS'); await pub.publish(); @@ -106,8 +123,8 @@ test('successful run does not need to query account ID', async () => { test('correctly identify asset path if path is absolute', async () => { const pub = new AssetPublishing(AssetManifest.fromPath('/abs/cdk.out'), { aws }); - aws.mockS3.headObject = mockedApiFailure('NotFound', 'File does not exist'); + aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); aws.mockS3.upload = mockUpload('FILE_CONTENTS'); await pub.publish(); -}); \ No newline at end of file +}); diff --git a/packages/cdk-assets/test/placeholders.test.ts b/packages/cdk-assets/test/placeholders.test.ts index f280cb9a479c1..76d82fa76e497 100644 --- a/packages/cdk-assets/test/placeholders.test.ts +++ b/packages/cdk-assets/test/placeholders.test.ts @@ -55,7 +55,7 @@ afterEach(() => { test('check that placeholders are replaced', async () => { const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); aws.mockS3.getBucketLocation = mockedApiResult({}); - aws.mockS3.headObject = mockedApiResult({ /* No error == file exists */ }); + aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: [{ Key: 'some_key-current_account-current_region' }] }); aws.mockEcr.describeImages = mockedApiResult({ /* No error == image exists */ }); await pub.publish(); @@ -69,9 +69,10 @@ test('check that placeholders are replaced', async () => { assumeRoleArn: 'arn:aws:role-current_account', })); - expect(aws.mockS3.headObject).toHaveBeenCalledWith(expect.objectContaining({ + expect(aws.mockS3.listObjectsV2).toHaveBeenCalledWith(expect.objectContaining({ Bucket: 'some_bucket-current_account-current_region', - Key: 'some_key-current_account-current_region', + Prefix: 'some_key-current_account-current_region', + MaxKeys: 1, })); expect(aws.mockEcr.describeImages).toHaveBeenCalledWith(expect.objectContaining({ diff --git a/packages/cdk-assets/test/progress.test.ts b/packages/cdk-assets/test/progress.test.ts index 1752db95def51..b082e4529c69a 100644 --- a/packages/cdk-assets/test/progress.test.ts +++ b/packages/cdk-assets/test/progress.test.ts @@ -1,7 +1,7 @@ import { AssetManifestSchema } from '@aws-cdk/cdk-assets-schema'; import * as mockfs from 'mock-fs'; import { AssetManifest, AssetPublishing, EventType, IPublishProgress, IPublishProgressListener } from '../lib'; -import { mockAws, mockedApiFailure, mockedApiResult, mockUpload } from './mock-aws'; +import { mockAws, mockedApiResult, mockUpload } from './mock-aws'; let aws: ReturnType; beforeEach(() => { @@ -37,7 +37,7 @@ beforeEach(() => { // Accept all S3 uploads as new aws.mockS3.getBucketLocation = mockedApiResult({}); - aws.mockS3.headObject = mockedApiFailure('NotFound', 'File does not exist'); + aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); aws.mockS3.upload = mockUpload(); }); diff --git a/packages/cdk-assets/test/zipping.test.ts b/packages/cdk-assets/test/zipping.test.ts index ee0e7f3cf066b..fa568f3829f18 100644 --- a/packages/cdk-assets/test/zipping.test.ts +++ b/packages/cdk-assets/test/zipping.test.ts @@ -2,7 +2,7 @@ import { AssetManifestSchema } from '@aws-cdk/cdk-assets-schema'; import { AssetManifest, AssetPublishing } from '../lib'; import * as bockfs from './bockfs'; -import { mockAws, mockedApiFailure, mockUpload } from './mock-aws'; +import { mockAws, mockedApiResult, mockUpload } from './mock-aws'; let aws: ReturnType; beforeEach(() => { @@ -32,7 +32,7 @@ beforeEach(() => { aws = mockAws(); // Accept all S3 uploads as new - aws.mockS3.headObject = mockedApiFailure('NotFound', 'File does not exist'); + aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); aws.mockS3.upload = mockUpload(); }); diff --git a/packages/cdk-assets/tsconfig.json b/packages/cdk-assets/tsconfig.json index 04e0404f04442..21692ad1da733 100644 --- a/packages/cdk-assets/tsconfig.json +++ b/packages/cdk-assets/tsconfig.json @@ -23,6 +23,9 @@ ], "exclude": [ "lib/init-templates/*/typescript/**/*.ts" + ], + "references": [ + { "path": "../@aws-cdk/cdk-assets-schema" } ] } From 3eeb21ed2f74ea8c2de3bf8f6245eab67595ee40 Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Thu, 23 Apr 2020 12:12:30 +0100 Subject: [PATCH 23/28] chore(cognito): fix erroneous code snippet & improve README on domain (#7557) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- packages/@aws-cdk/aws-cognito/README.md | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/@aws-cdk/aws-cognito/README.md b/packages/@aws-cdk/aws-cognito/README.md index e16a1ccaef3e6..4c9a5c60ea77f 100644 --- a/packages/@aws-cdk/aws-cognito/README.md +++ b/packages/@aws-cdk/aws-cognito/README.md @@ -407,26 +407,26 @@ configured using domains. There are two ways to set up a domain - either the Ama with an available domain prefix, or a custom domain name can be chosen. The custom domain must be one that is already owned, and whose certificate is registered in AWS Certificate Manager. -The following code sets up a user pool domain in Amazon Cognito hosted domain with the prefix 'my-awesome-app' - +The following code sets up a user pool domain in Amazon Cognito hosted domain with the prefix 'my-awesome-app', and another domain with the custom domain 'user.myapp.com' - ```ts const pool = new UserPool(this, 'Pool'); -pool.addDomain('domain', { - domain: UserPoolDomainType.cognitoDomain({ + +pool.addDomain('CognitoDomain', { + cognitoDomain: { domainPrefix: 'my-awesome-app', - }), + }, }); -``` -On the other hand, the following code sets up a user pool domain and use your own custom domain - - -```ts const domainCert = new acm.Certificate.fromCertificateArn(this, 'domainCert', certificateArn); -const pool = new UserPool(this, 'Pool'); -pool.addDomain('domain', { - domain: UserPoolDomainType.customDomain({ - domainPrefix: 'my-awesome-app', +pool.addDomain('CustomDomain', { + customDomain: { + domainName: 'user.myapp.com', certificate: domainCert, - }), + }, }); -``` \ No newline at end of file +``` + +Read more about [Using the Amazon Cognito +Domain](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-assign-domain-prefix.html) and [Using Your Own +Domain](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-add-custom-domain.html). \ No newline at end of file From 607b84b1acd53b5fbc1557a814eb5d10bad5114a Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Thu, 23 Apr 2020 14:20:07 +0200 Subject: [PATCH 24/28] chore(monocdk): upgrade jsii and generate bindings for monocdk (#7520) Those bindings are experimental in that the name of types within those is subject to change in the future as jsii adds features to enable name customization. The names are eventually expected to converge to those in the individual modules --- package.json | 6 +- packages/cdk-dasm/package.json | 2 +- packages/decdk/package.json | 4 +- packages/monocdk-experiment/.gitignore | 1 + packages/monocdk-experiment/.npmignore | 1 + packages/monocdk-experiment/build.sh | 18 +- packages/monocdk-experiment/gen.js | 36 ++-- packages/monocdk-experiment/package.json | 25 ++- packages/monocdk-experiment/tsconfig.json | 18 -- scripts/check-api-compatibility.sh | 1 + tools/awslint/package.json | 4 +- tools/cdk-build-tools/package.json | 4 +- tools/cfn2ts/package.json | 2 +- yarn.lock | 234 ++++++++++++++-------- 14 files changed, 219 insertions(+), 137 deletions(-) delete mode 100644 packages/monocdk-experiment/tsconfig.json diff --git a/package.json b/package.json index dbee4f54492ad..3a486f40e72f4 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,9 @@ "devDependencies": { "conventional-changelog-cli": "^2.0.31", "fs-extra": "^8.1.0", - "jsii-diff": "^1.3.2", - "jsii-pacmak": "^1.3.2", - "jsii-rosetta": "^1.3.2", + "jsii-diff": "^1.4.1", + "jsii-pacmak": "^1.4.1", + "jsii-rosetta": "^1.4.1", "lerna": "^3.20.2", "standard-version": "^7.1.0", "typescript": "~3.8.3" diff --git a/packages/cdk-dasm/package.json b/packages/cdk-dasm/package.json index e3b6fc3069b8c..aa6edd21d75bf 100644 --- a/packages/cdk-dasm/package.json +++ b/packages/cdk-dasm/package.json @@ -26,7 +26,7 @@ }, "license": "Apache-2.0", "dependencies": { - "codemaker": "^1.3.2", + "codemaker": "^1.4.1", "yaml": "1.9.2" }, "devDependencies": { diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 4e049cdbd372c..a4c7de508fdfe 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -173,7 +173,7 @@ "@aws-cdk/region-info": "0.0.0", "constructs": "^3.0.2", "fs-extra": "^8.1.0", - "jsii-reflect": "^1.3.2", + "jsii-reflect": "^1.4.1", "jsonschema": "^1.2.6", "yaml": "1.9.2", "yargs": "^15.3.1" @@ -184,7 +184,7 @@ "@types/yaml": "1.2.0", "@types/yargs": "^15.0.4", "jest": "^25.4.0", - "jsii": "^1.3.2" + "jsii": "^1.4.1" }, "keywords": [ "aws", diff --git a/packages/monocdk-experiment/.gitignore b/packages/monocdk-experiment/.gitignore index 4a03ddbdf2f9f..a25055f733262 100644 --- a/packages/monocdk-experiment/.gitignore +++ b/packages/monocdk-experiment/.gitignore @@ -3,3 +3,4 @@ !deps.js !gen.js staging/ +tsconfig.json diff --git a/packages/monocdk-experiment/.npmignore b/packages/monocdk-experiment/.npmignore index 40bc5fe6ba3f5..0b96cfab1fbc5 100644 --- a/packages/monocdk-experiment/.npmignore +++ b/packages/monocdk-experiment/.npmignore @@ -16,4 +16,5 @@ dist .LAST_PACKAGE .jsii +tsconfig.json *.tsbuildinfo diff --git a/packages/monocdk-experiment/build.sh b/packages/monocdk-experiment/build.sh index 0d1742e577ff8..eeb21879b484d 100755 --- a/packages/monocdk-experiment/build.sh +++ b/packages/monocdk-experiment/build.sh @@ -15,11 +15,11 @@ echo "installing dependencies for bundling..." npm install echo "compiling..." -tsc +${CDK_BUILD_JSII:-jsii} echo "packaging..." -npm pack -tarball=$PWD/monocdk-experiment-*.tgz +${CDK_PACKAGE_JSII_PACMAK:-jsii-pacmak} +tarball=$PWD/dist/js/monocdk-experiment@*.tgz echo "verifying package..." cd $(mktemp -d) @@ -28,11 +28,11 @@ npm install ${tarball} constructs@${constructs_version} node -e "require('monocdk-experiment')" unpacked=$(node -p 'path.dirname(require.resolve("monocdk-experiment/package.json"))') -# saving tarball -cd ${scriptdir} -mkdir -p dist/js -cp ${tarball} dist/js +# saving publishable artifact +rm -fr ${scriptdir}/dist +mv ${outdir}/dist ${scriptdir}/dist # so this module will also work as a local dependency (e.g. for modules under @monocdk-experiment/*). -rm -fr staging -mv ${unpacked} staging +rm -fr ${scriptdir}/staging +mv ${unpacked} ${scriptdir}/staging +mv ${scriptdir}/staging/.jsii ${scriptdir} diff --git a/packages/monocdk-experiment/gen.js b/packages/monocdk-experiment/gen.js index 4a68e0fc81a0e..ff187cf84241d 100644 --- a/packages/monocdk-experiment/gen.js +++ b/packages/monocdk-experiment/gen.js @@ -5,11 +5,11 @@ const path = require('path'); const glob = require('glob'); const os = require('os'); -const exclude_modules = [ +const exclude_modules = [ // 'aws-lambda-nodejs' // bundles "parcel" which is unacceptable for now ]; -const include_non_jsii = [ +const include_non_jsii = [ // 'assert', // 'cloudformation-diff', ]; @@ -22,14 +22,14 @@ const include_dev_deps = [ const exclude_files = [ 'test', 'scripts', - 'node_modules', - 'package.json', - 'tsconfig.json', - 'tsconfig.tsbuildinfo', - '.gitignore', - '.jsii', - 'LICENSE', - 'NOTICE' + 'node_modules', + 'package.json', + 'tsconfig.json', + 'tsconfig.tsbuildinfo', + '.gitignore', + '.jsii', + 'LICENSE', + 'NOTICE' ]; async function main() { @@ -46,6 +46,10 @@ async function main() { const modules = await fs.readdir(root); const manifest = await fs.readJson(path.join(monocdkroot, 'package.json')); + // Adjust index location for initial compilation + manifest.main = manifest.main.replace(/^staging\//, ''); + manifest.types = manifest.types.replace(/^staging\//, ''); + const nodeTypes = manifest.devDependencies['@types/node']; if (!nodeTypes) { throw new Error(`@types/node must be defined in devDependencies`); @@ -134,12 +138,12 @@ async function main() { const bundled = [ ...meta.bundleDependencies || [], ...meta.bundledDependencies || [] ]; for (const d of bundled) { const ver = meta.dependencies[d]; - + console.error(`adding bundled dep ${d} with version ${ver}`); if (!pkgBundled.includes(d)) { pkgBundled.push(d); } - + if (!ver) { throw new Error(`cannot determine version for bundled dep ${d} of module ${meta.name}`); } @@ -151,7 +155,7 @@ async function main() { throw new Error(`version mismatch for bundled dep ${d}: ${meta.name} requires version ${ver} but we already have version ${existingVer}`); } } - } + } } await fs.writeFile(path.join(outdir, 'index.ts'), reexports.join('\n')); @@ -162,12 +166,12 @@ async function main() { await rewriteImports(outdir, source); } - // copy tsconfig.json and .npmignore - const files = [ 'tsconfig.json', '.npmignore', 'README.md', 'LICENSE', 'NOTICE' ]; + // copy .npmignore, license stuff, readme, ... + const files = [ '.npmignore', 'README.md', 'LICENSE', 'NOTICE' ]; for (const file of files) { await fs.copy(path.join(monocdkroot, file), path.join(outdir, file)); } - + console.error('writing package.json'); await fs.writeJson(path.join(outdir, 'package.json'), manifest, { spaces: 2 }); diff --git a/packages/monocdk-experiment/package.json b/packages/monocdk-experiment/package.json index fc4058eedbbca..17bd0a871959a 100644 --- a/packages/monocdk-experiment/package.json +++ b/packages/monocdk-experiment/package.json @@ -2,8 +2,8 @@ "name": "monocdk-experiment", "version": "0.0.0", "description": "An experiment to bundle the entire CDK into a single module", - "main": "index.js", - "types": "index.d.ts", + "main": "staging/index.js", + "types": "staging/index.d.ts", "repository": { "type": "git", "url": "https://github.com/aws/aws-cdk.git" @@ -17,6 +17,27 @@ "build+test": "npm run build && npm test", "build+test+package": "npm run build+test && npm run package" }, + "jsii": { + "outdir": "dist", + "targets": { + "java": { + "package": "software.amazon.awscdk.monocdkexperiment", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "monocdk-experiment", + "versionSuffix": ".DEVPREVIEW" + } + }, + "dotnet": { + "namespace": "Amazon.CDK.MonoCDK.Experiment", + "packageId": "Amazon.CDK.MonoCDK.Experiment", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png", + "versionSuffix": "-devpreview", + "signAssembly": true, + "assemblyOriginatorKeyFile": "../../key.snk" + } + } + }, "author": { "name": "Amazon Web Services", "url": "https://aws.amazon.com", diff --git a/packages/monocdk-experiment/tsconfig.json b/packages/monocdk-experiment/tsconfig.json deleted file mode 100644 index 8039efc7a72bd..0000000000000 --- a/packages/monocdk-experiment/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2018", - "module": "commonjs", - "lib": ["es2018"], - "strict": true, - "alwaysStrict": true, - "declaration": true, - "inlineSourceMap": true, - "inlineSources": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "resolveJsonModule": true, - "incremental": true - }, -} diff --git a/scripts/check-api-compatibility.sh b/scripts/check-api-compatibility.sh index f73702b61c639..a2fdb1ac57c27 100755 --- a/scripts/check-api-compatibility.sh +++ b/scripts/check-api-compatibility.sh @@ -71,6 +71,7 @@ success=true for dir in $jsii_package_dirs; do name=$(package_name "$dir") if [[ ! -d $tmpdir/node_modules/$name ]]; then continue; fi + if [[ ! -f $tmpdir/node_modules/$name/.jsii ]]; then continue; fi echo -n "$name... " if npx jsii-diff \ --keys \ diff --git a/tools/awslint/package.json b/tools/awslint/package.json index 83c675d8f596f..5a7d9cbcf2f4f 100644 --- a/tools/awslint/package.json +++ b/tools/awslint/package.json @@ -16,11 +16,11 @@ "awslint": "bin/awslint" }, "dependencies": { - "@jsii/spec": "^1.3.2", + "@jsii/spec": "^1.4.1", "camelcase": "^6.0.0", "colors": "^1.4.0", "fs-extra": "^8.1.0", - "jsii-reflect": "^1.3.2", + "jsii-reflect": "^1.4.1", "yargs": "^15.3.1" }, "devDependencies": { diff --git a/tools/cdk-build-tools/package.json b/tools/cdk-build-tools/package.json index 2f54ebf8482d3..34b706b00b327 100644 --- a/tools/cdk-build-tools/package.json +++ b/tools/cdk-build-tools/package.json @@ -49,8 +49,8 @@ "eslint-plugin-import": "^2.20.2", "fs-extra": "^8.1.0", "jest": "^25.4.0", - "jsii": "^1.3.2", - "jsii-pacmak": "^1.3.2", + "jsii": "^1.4.1", + "jsii-pacmak": "^1.4.1", "nodeunit": "^0.11.3", "nyc": "^15.0.1", "ts-jest": "^25.4.0", diff --git a/tools/cfn2ts/package.json b/tools/cfn2ts/package.json index 4be86cf87b570..f435be1374daa 100644 --- a/tools/cfn2ts/package.json +++ b/tools/cfn2ts/package.json @@ -30,7 +30,7 @@ "license": "Apache-2.0", "dependencies": { "@aws-cdk/cfnspec": "0.0.0", - "codemaker": "^1.3.2", + "codemaker": "^1.4.1", "fast-json-patch": "^3.0.0-1", "fs-extra": "^8.1.0", "yargs": "^15.3.1" diff --git a/yarn.lock b/yarn.lock index 35150ab4f8bab..d636c4b8052a9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,38 +2,6 @@ # yarn lockfile v1 -"@aws-cdk/aws-imagebuilder@1.34.1": - version "1.34.1" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-imagebuilder/-/aws-imagebuilder-1.34.1.tgz#ae40cc78dfdfef421d7a3337cf909f112e43352b" - integrity sha512-WQjgZscfVPV5maatdFgvhPNp2Pdcs7KXat2uMfXF4LgaUmIa+BQ90LFShkfxDESvGZQTrMXgdOqPOwUuVmNR+Q== - dependencies: - "@aws-cdk/core" "1.34.1" - -"@aws-cdk/cloud-assembly-schema@1.34.1": - version "1.34.1" - resolved "https://registry.yarnpkg.com/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.34.1.tgz#c79eb4ccbe0301c2c0ad4d640d005b27de419a98" - integrity sha512-zBiP2ty4LgeFl0ulc8kDbAzI5MeKdkIwWd7ef1qz+pk4YfBtAjsHbJDzk/apkR7Yaf7Tum9UuPf7yCK4mB18IA== - dependencies: - jsonschema "^1.2.5" - semver "^7.2.2" - -"@aws-cdk/core@1.34.1": - version "1.34.1" - resolved "https://registry.yarnpkg.com/@aws-cdk/core/-/core-1.34.1.tgz#30ed9a457e2f5206180a61939d064cbbf24425b0" - integrity sha512-Lay8Wly6DBTTEJxeW/UNvC0MJbxZcbzSCwxcchHS4KzKaf40CnEIi9jEoSZ2VokjfJCI0KvlXaAB4z1Mt0kGOg== - dependencies: - "@aws-cdk/cloud-assembly-schema" "1.34.1" - "@aws-cdk/cx-api" "1.34.1" - constructs "^3.0.2" - -"@aws-cdk/cx-api@1.34.1": - version "1.34.1" - resolved "https://registry.yarnpkg.com/@aws-cdk/cx-api/-/cx-api-1.34.1.tgz#f1e5ca6f5c6315047e01f07aa8da34acad368a83" - integrity sha512-6eS08/6/iZPbsKeUlnmmflPYHirk3DSocSSRWCsmx9vcb2xQgHKJaWJWPcPXeaPyK3BuTe0Zw/XsC2SVD+u30Q== - dependencies: - "@aws-cdk/cloud-assembly-schema" "1.34.1" - semver "^7.2.2" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" @@ -1257,10 +1225,10 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" -"@jsii/spec@^1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@jsii/spec/-/spec-1.3.2.tgz#e669d63e08864b3df5fcd8083dc6a9088c96008d" - integrity sha512-iQjb8FnOgw/Pfjq5cKXnIHfTZDv1hDbgPMsymv58KfRgyq+NZOHr7AHNNn1oha0VStCJVinA3gVsNVnK8suxZQ== +"@jsii/spec@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@jsii/spec/-/spec-1.4.1.tgz#35893433c7144bc56efcf3528bc9e21c638ea405" + integrity sha512-iARdSgmuq2+9BCS9fd2RD+KN7FCPwXCW8pIJkAaTWDJolS9cmVaNp7WWZKLhdo7UkPDUpYzLUW3nCc5dimo3iw== dependencies: jsonschema "^1.2.6" @@ -2668,6 +2636,11 @@ anymatch@^3.0.3: normalize-path "^3.0.0" picomatch "^2.0.4" +app-root-path@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" + integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== + append-transform@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" @@ -2918,7 +2891,7 @@ available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: dependencies: array-filter "^1.0.0" -aws-sdk-mock@^5.1.0: +aws-sdk-mock@^5.0.0, aws-sdk-mock@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/aws-sdk-mock/-/aws-sdk-mock-5.1.0.tgz#6f2c0bd670d7f378c906a8dd806f812124db71aa" integrity sha512-Wa5eCSo8HX0Snqb7FdBylaXMmfrAWoWZ+d7MFhiYsgHPvNvMEGjV945FF2qqE1U0Tolr1ALzik1fcwgaOhqUWQ== @@ -2927,6 +2900,21 @@ aws-sdk-mock@^5.1.0: sinon "^9.0.1" traverse "^0.6.6" +aws-sdk@^2.596.0: + version "2.660.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.660.0.tgz#1be2f814ffdb1aadf859b252601974073a39a4b2" + integrity sha512-6FR91Jg1x9TuFglsdBHkRuE4X7sPRwqeTB2GwLk9XPX1giicdMvJrWbcw5rUnMKjXs9LVlkwaK5VI9AJ0d8dpw== + dependencies: + buffer "4.9.1" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.3.2" + xml2js "0.4.19" + aws-sdk@^2.637.0, aws-sdk@^2.661.0: version "2.661.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.661.0.tgz#e877dbc0d07b74e93e2383eb4cd0407592b1e46e" @@ -3739,10 +3727,10 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -codemaker@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/codemaker/-/codemaker-1.3.2.tgz#e9f41e6d78329e927bb5def77b3d26caa57bc15e" - integrity sha512-KVMT/b65M8+WeWrhIxoGbpREtavrZBT3Zc4/MXO6vl2H2RXn0HWGuzYNXCmi+QkDGutUYsXQfHqH2H3hrw4FKQ== +codemaker@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/codemaker/-/codemaker-1.4.1.tgz#fc87559a99fa751add5ea53380c41cf12afad128" + integrity sha512-UCyJxq94GNli8wxPQc4lItDOdoK6XCjevgcS7GKix8lTLgR4IFhbd9Y/ZcV6n04r2PEKT44yErSLvCsJ31nQ3g== dependencies: camelcase "^6.0.0" decamelize "^1.2.0" @@ -4904,11 +4892,21 @@ dotenv-expand@^5.1.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== +dotenv-json@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dotenv-json/-/dotenv-json-1.0.0.tgz#fc7f672aafea04bed33818733b9f94662332815c" + integrity sha512-jAssr+6r4nKhKRudQ0HOzMskOFFi9+ubXWwmrSGJFgTvpjyPXCXsCsYbjif6mXp7uxA7xY3/LGaiTQukZzSbOQ== + dotenv@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== +dotenv@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + dotgitignore@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/dotgitignore/-/dotgitignore-2.1.0.tgz#a4b15a4e4ef3cf383598aaf1dfa4a04bcc089b7b" @@ -5143,6 +5141,11 @@ escodegen@~1.9.0: optionalDependencies: source-map "~0.6.1" +eslint-config-standard@^14.1.0: + version "14.1.1" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea" + integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg== + eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" @@ -5170,7 +5173,15 @@ eslint-module-utils@^2.4.1: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-import@^2.20.2: +eslint-plugin-es@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz#0f5f5da5f18aa21989feebe8a73eadefb3432976" + integrity sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ== + dependencies: + eslint-utils "^1.4.2" + regexpp "^3.0.0" + +eslint-plugin-import@^2.19.1, eslint-plugin-import@^2.20.2: version "2.20.2" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d" integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg== @@ -5188,6 +5199,28 @@ eslint-plugin-import@^2.20.2: read-pkg-up "^2.0.0" resolve "^1.12.0" +eslint-plugin-node@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" + integrity sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ== + dependencies: + eslint-plugin-es "^2.0.0" + eslint-utils "^1.4.2" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-plugin-promise@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" + integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== + +eslint-plugin-standard@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" + integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== + eslint-scope@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" @@ -5196,7 +5229,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.4.3: +eslint-utils@^1.4.2, eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== @@ -6410,6 +6443,11 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.1.1: + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -7796,7 +7834,7 @@ jest@^24.9.0: import-local "^2.0.0" jest-cli "^24.9.0" -jest@^25.4.0: +jest@^25.3.0, jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/jest/-/jest-25.4.0.tgz#fb96892c5c4e4a6b9bcb12068849cddf4c5f8cc7" integrity sha512-XWipOheGB4wai5JfCYXd6vwsWNwM/dirjRoZgAa7H2wd8ODWbli2AiKjqG8AYhyx+8+5FBEdpO92VhGlBydzbw== @@ -7939,65 +7977,65 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -jsii-diff@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/jsii-diff/-/jsii-diff-1.3.2.tgz#1106f2e3374f339e283b9db7e4d83c96eb30be21" - integrity sha512-Wn93JYupqB/XtmLdkO9mj6eViz1zJm48x228cs3KBVxgzatnHfWE0SzNaZ0BZkl1uQrGPM8tHEGaI4HsHrGHNw== +jsii-diff@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsii-diff/-/jsii-diff-1.4.1.tgz#a4111869323940a693ce7a9a7c6559ade51dc6ee" + integrity sha512-7dtYd24w1UNDki0Uc7CJiv7oKoYAnKem1fSRDiEUVcAL1/9iNvYVGPMjUMMNx8RoRYln/oK3988AYB/h6VDxYw== dependencies: - "@jsii/spec" "^1.3.2" + "@jsii/spec" "^1.4.1" fs-extra "^9.0.0" - jsii-reflect "^1.3.2" + jsii-reflect "^1.4.1" log4js "^6.2.1" typescript "~3.8.3" yargs "^15.3.1" -jsii-pacmak@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/jsii-pacmak/-/jsii-pacmak-1.3.2.tgz#d3ec235cdcb32e6559cd9b4020165948cf74d001" - integrity sha512-WAhv7c11PmNWYfDK4GooBEfC6EcOQsqrR7ONbTftS0udJ6TCDNcJZHZ7ApiYvxSrGfNm42syD1g5Yo9dFktiew== +jsii-pacmak@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsii-pacmak/-/jsii-pacmak-1.4.1.tgz#ff119b51989b8b89edf2de983779727a43586f9e" + integrity sha512-2RSlhMDsXOoyJI9dCAXAZ29oHQhtJFfcmtfBP4CIz90HFk/UYQlEHz6Mj6E398XwEnSSRaDzu3DA2WEJPb4cNw== dependencies: - "@jsii/spec" "^1.3.2" + "@jsii/spec" "^1.4.1" clone "^2.1.2" - codemaker "^1.3.2" + codemaker "^1.4.1" commonmark "^0.29.1" escape-string-regexp "^3.0.0" fs-extra "^9.0.0" - jsii-reflect "^1.3.2" - jsii-rosetta "^1.3.2" + jsii-reflect "^1.4.1" + jsii-rosetta "^1.4.1" semver "^7.3.2" spdx-license-list "^6.2.0" xmlbuilder "^15.1.1" yargs "^15.3.1" -jsii-reflect@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/jsii-reflect/-/jsii-reflect-1.3.2.tgz#1b9b83ec16cb9e5dcfb94ad6e1d7d9fafb7cc883" - integrity sha512-iwAoLJNZL6Sl8HqWm9Y2AfT0y2JHfhhPZFAFdjWR7f5MO3esn3hU1BJntxfwmRuat7z1kqFUx5p1QnoQ11oK7g== +jsii-reflect@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsii-reflect/-/jsii-reflect-1.4.1.tgz#c4f5ef4878ead129740e412e66411a2b74f2c5c8" + integrity sha512-Z4KK6ThkxwstPTaDLaWWn2y3YTCxOY1zOz3WJ2aQnrVNeEVs3Se084fEa44uXiidfq8e9kJ7npUeSMIgQuRDMQ== dependencies: - "@jsii/spec" "^1.3.2" + "@jsii/spec" "^1.4.1" colors "^1.4.0" fs-extra "^9.0.0" - oo-ascii-tree "^1.3.2" + oo-ascii-tree "^1.4.1" yargs "^15.3.1" -jsii-rosetta@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/jsii-rosetta/-/jsii-rosetta-1.3.2.tgz#d500ba5a137656e3aaf9ec87d7eb848af423eb03" - integrity sha512-V50M+/tEr6N1YLeGq5JHI2p/db0HqvzkFaL8MumpCbz5tCdhM1fmxp/8aJ8Dy4sCERkO/EA/rpbNbx08yNB/jw== +jsii-rosetta@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsii-rosetta/-/jsii-rosetta-1.4.1.tgz#50f41aff8066bdeecb6a85141a0bbed6fdf86517" + integrity sha512-6zDlsasizUOr4zLmRYPupL53ZAsk6Tcre/23hhrrMNcAazoe1wZtEa6UtpOm+qbwD67z2VgqcMTXcfFQvPEUAA== dependencies: - "@jsii/spec" "^1.3.2" + "@jsii/spec" "^1.4.1" commonmark "^0.29.1" fs-extra "^9.0.0" typescript "~3.8.3" xmldom "^0.3.0" yargs "^15.3.1" -jsii@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/jsii/-/jsii-1.3.2.tgz#82b049aec062c69f8c25b1fe469ddb8d2a5fee7a" - integrity sha512-71TX96GJPiXL3KI+h0MPdSwXirP09Zop71IAkxMsTJf091QdTP6dsjruqwYUosOAoiTuSbpz+6DXztvqKACkTg== +jsii@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsii/-/jsii-1.4.1.tgz#eaa166829fc90dfe6f207139170e6608a63221be" + integrity sha512-EMBPeLs52JgCujAuPuZb0MQX5Wa3h/XskyzJNKgP5NqSLrntKtXb9379g4W0RBF2+df4lJyXDfa6dr59jefi2g== dependencies: - "@jsii/spec" "^1.3.2" + "@jsii/spec" "^1.4.1" case "^1.6.3" colors "^1.4.0" deep-equal "^2.0.2" @@ -8150,6 +8188,24 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +lambda-leak@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lambda-leak/-/lambda-leak-2.0.0.tgz#771985d3628487f6e885afae2b54510dcfb2cd7e" + integrity sha1-dxmF02KEh/boha+uK1RRDc+yzX4= + +lambda-tester@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/lambda-tester/-/lambda-tester-3.6.0.tgz#ceb7d4f4f0da768487a05cff37dcd088508b5247" + integrity sha512-F2ZTGWCLyIR95o/jWK46V/WnOCFAEUG/m/V7/CLhPJ7PCM+pror1rZ6ujP3TkItSGxUfpJi0kqwidw+M/nEqWw== + dependencies: + app-root-path "^2.2.1" + dotenv "^8.0.0" + dotenv-json "^1.0.0" + lambda-leak "^2.0.0" + semver "^6.1.1" + uuid "^3.3.2" + vandium-utils "^1.1.1" + lazystream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" @@ -8940,6 +8996,17 @@ nise@^4.0.1: just-extend "^4.0.2" path-to-regexp "^1.7.0" +nock@^11.7.0: + version "11.9.1" + resolved "https://registry.yarnpkg.com/nock/-/nock-11.9.1.tgz#2b026c5beb6d0dbcb41e7e4cefa671bc36db9c61" + integrity sha512-U5wPctaY4/ar2JJ5Jg4wJxlbBfayxgKbiAeGh+a1kk6Pwnc2ZEuKviLyDSG6t0uXl56q7AALIxoM6FJrBSsVXA== + dependencies: + debug "^4.1.0" + json-stringify-safe "^5.0.1" + lodash "^4.17.13" + mkdirp "^0.5.0" + propagate "^2.0.0" + nock@^12.0.3: version "12.0.3" resolved "https://registry.yarnpkg.com/nock/-/nock-12.0.3.tgz#83f25076dbc4c9aa82b5cdf54c9604c7a778d1c9" @@ -9392,10 +9459,10 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -oo-ascii-tree@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/oo-ascii-tree/-/oo-ascii-tree-1.3.2.tgz#eac9b058c83f0efd5566fa71ccf67bac40294b8f" - integrity sha512-nRkex03NnQ9f6cCWeW2Ar6qHRcVc3v4gN6ZRTU3UdlizagmL4CLgHzpdwcty+zpGT6VO6H0orE7SzX0rWFEjYw== +oo-ascii-tree@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/oo-ascii-tree/-/oo-ascii-tree-1.4.1.tgz#c48aa8afcb90863e9efcae9dbfa07d897c98e964" + integrity sha512-8bCnzfbDQvJCOirc77ISBjR0X8ziploaydwJyQD5ZgF6W6Nh3Ds3C8Q/95Lc095TBfDU+m+VZLxk3z3DgW/t+w== opener@^1.5.1: version "1.5.1" @@ -11026,7 +11093,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.x, resolve@^1.1.5, resolve@^1.10.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.4.0: +resolve@1.x, resolve@^1.1.5, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.4.0: version "1.16.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.16.1.tgz#49fac5d8bacf1fd53f200fa51247ae736175832c" integrity sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig== @@ -11195,7 +11262,7 @@ semver-intersect@^1.4.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@6.3.0, semver@6.x, semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -12366,7 +12433,7 @@ trivial-deferred@^1.0.1: resolved "https://registry.yarnpkg.com/trivial-deferred/-/trivial-deferred-1.0.1.tgz#376d4d29d951d6368a6f7a0ae85c2f4d5e0658f3" integrity sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM= -ts-jest@^25.4.0: +ts-jest@^25.3.1, ts-jest@^25.4.0: version "25.4.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.4.0.tgz#5ad504299f8541d463a52e93e5e9d76876be0ba4" integrity sha512-+0ZrksdaquxGUBwSdTIcdX7VXdwLIlSRsyjivVA9gcO+Cvr6ByqDhu/mi5+HCcb6cMkiQp5xZ8qRO7/eCqLeyw== @@ -12799,6 +12866,11 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" +vandium-utils@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vandium-utils/-/vandium-utils-1.2.0.tgz#44735de4b7641a05de59ebe945f174e582db4f59" + integrity sha1-RHNd5LdkGgXeWevpRfF05YLbT1k= + vendors@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" From d1b3b750cec3c514df6690e8baeffa7e9b260500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=91=A8=F0=9F=8F=BC=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier-Muller?= Date: Thu, 23 Apr 2020 13:37:29 +0200 Subject: [PATCH 25/28] chore: add missing comment in monocdk build.sh --- packages/monocdk-experiment/build.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/monocdk-experiment/build.sh b/packages/monocdk-experiment/build.sh index eeb21879b484d..eea6710a3cc93 100755 --- a/packages/monocdk-experiment/build.sh +++ b/packages/monocdk-experiment/build.sh @@ -35,4 +35,8 @@ mv ${outdir}/dist ${scriptdir}/dist # so this module will also work as a local dependency (e.g. for modules under @monocdk-experiment/*). rm -fr ${scriptdir}/staging mv ${unpacked} ${scriptdir}/staging + +# move .jsii to package root, where our build tools, etc... will look for it. +# this is needed because the generated code is hosted under staging/, but during +# it's creation, it was directly in the package root. mv ${scriptdir}/staging/.jsii ${scriptdir} From c8aa92d1a0b87afc380fecaf91fc1048a74f670f Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Thu, 23 Apr 2020 17:59:37 +0200 Subject: [PATCH 26/28] feat(backup): Vault, Plan and Selection Add L2 constructs for AWS Backup: BackupVault, BackupPlan and BackupSelection. Ready-made plans and rules are provided. All backupable resources inside a Construct can be easily added to a selection. Credits to @arnulfojr for starting the work on this in #4954. --- packages/@aws-cdk/aws-backup/README.md | 72 ++++- .../lib/backupable-resources-collector.ts | 52 ++++ packages/@aws-cdk/aws-backup/lib/index.ts | 6 + packages/@aws-cdk/aws-backup/lib/plan.ts | 201 ++++++++++++ packages/@aws-cdk/aws-backup/lib/resource.ts | 139 +++++++++ packages/@aws-cdk/aws-backup/lib/rule.ts | 160 ++++++++++ packages/@aws-cdk/aws-backup/lib/selection.ts | 136 ++++++++ packages/@aws-cdk/aws-backup/lib/vault.ts | 164 ++++++++++ packages/@aws-cdk/aws-backup/package.json | 17 + .../@aws-cdk/aws-backup/test/backup.test.ts | 6 - .../test/integ.backup.expected.json | 204 ++++++++++++ .../@aws-cdk/aws-backup/test/integ.backup.ts | 36 +++ .../@aws-cdk/aws-backup/test/plan.test.ts | 206 ++++++++++++ .../aws-backup/test/selection.test.ts | 292 ++++++++++++++++++ .../@aws-cdk/aws-backup/test/vault.test.ts | 152 +++++++++ 15 files changed, 1835 insertions(+), 8 deletions(-) create mode 100644 packages/@aws-cdk/aws-backup/lib/backupable-resources-collector.ts create mode 100644 packages/@aws-cdk/aws-backup/lib/plan.ts create mode 100644 packages/@aws-cdk/aws-backup/lib/resource.ts create mode 100644 packages/@aws-cdk/aws-backup/lib/rule.ts create mode 100644 packages/@aws-cdk/aws-backup/lib/selection.ts create mode 100644 packages/@aws-cdk/aws-backup/lib/vault.ts delete mode 100644 packages/@aws-cdk/aws-backup/test/backup.test.ts create mode 100644 packages/@aws-cdk/aws-backup/test/integ.backup.expected.json create mode 100644 packages/@aws-cdk/aws-backup/test/integ.backup.ts create mode 100644 packages/@aws-cdk/aws-backup/test/plan.test.ts create mode 100644 packages/@aws-cdk/aws-backup/test/selection.test.ts create mode 100644 packages/@aws-cdk/aws-backup/test/vault.test.ts diff --git a/packages/@aws-cdk/aws-backup/README.md b/packages/@aws-cdk/aws-backup/README.md index 23e6d35b92f84..531a324855f26 100644 --- a/packages/@aws-cdk/aws-backup/README.md +++ b/packages/@aws-cdk/aws-backup/README.md @@ -9,8 +9,76 @@ --- -This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. +AWS Backup is a fully managed backup service that makes it easy to centralize and automate the backup of data across AWS services in the cloud and on premises. Using AWS Backup, you can configure backup policies and monitor backup activity for your AWS resources in one place. + +### Backup plan and selection + +In AWS Backup, a *backup plan* is a policy expression that defines when and how you want to back up your AWS resources, such as Amazon DynamoDB tables or Amazon Elastic File System (Amazon EFS) file systems. You can assign resources to backup plans, and AWS Backup automatically backs up and retains backups for those resources according to the backup plan. You can create multiple backup plans if you have workloads with different backup requirements. + +This module provides ready-made backup plans (similar to the console experience): + +```ts +import * as backup from '@aws-cdk/aws-backup'; + +// Daily, weekly and monthly with 5 year retention +const plan = backup.BackupPlan.dailyWeeklyMonthly5YearRetention(this, 'Plan'); +``` + +Assigning resources to a plan can be done with `addSelection()`: + +```ts +plan.addSelection('Selection', { + resources: [ + backup.BackupResource.fromDynamoDbTable(myTable), // A DynamoDB table + backup.BackupResource.fromTag('stage', 'prod'), // All resources that are tagged stage=prod in the region/account + backup.BackupResource.fromConstruct(myCoolConstruct), // All backupable resources in `myCoolConstruct` + ] +}) +``` + +If not specified, a new IAM role with a managed policy for backup will be +created for the selection. The `BackupSelection` implements `IGrantable`. + +To add rules to a plan, use `addRule()`: ```ts -import backup = require('@aws-cdk/aws-backup'); +plan.addRule(new BackupPlanRule({ + completionWindow: Duration.hours(2), + startWindow: Duration.hours(1), + scheduleExpression: events.Schedule.cron({ // Only cron expressions are supported + day: '15', + hour: '3', + minute: '30' + }), + moveToColdStorageAfter: Duration.days(30) +})); ``` + +Ready-made rules are also available: + +```ts +plan.addRule(BackupPlanRule.daily()); +plan.addRule(BackupPlanRule.weekly()); +``` + +By default a new [vault](#Backup-vault) is created when creating a plan. +It is also possible to specify a vault either at the plan level or at the +rule level. + +```ts +const plan = backup.BackupPlan.daily35DayRetention(this, 'Plan', myVault); // Use `myVault` for all plan rules +plan.addRule(BackupPlanRule.monthly1Year(otherVault)); // Use `otherVault` for this specific rule +``` + +### Backup vault +In AWS Backup, a *backup vault* is a container that you organize your backups in. You can use backup vaults to set the AWS Key Management Service (AWS KMS) encryption key that is used to encrypt backups in the backup vault and to control access to the backups in the backup vault. If you require different encryption keys or access policies for different groups of backups, you can optionally create multiple backup vaults. + +```ts +const vault = new BackupVault(stack, 'Vault', { + encryptionKey: myKey, // Custom encryption key + notificationTopic: myTopic, // Send all vault events to this SNS topic +}); +``` + +A vault has a default `RemovalPolicy` set to `RETAIN`. Note that removing a vault +that contains recovery points will fail. diff --git a/packages/@aws-cdk/aws-backup/lib/backupable-resources-collector.ts b/packages/@aws-cdk/aws-backup/lib/backupable-resources-collector.ts new file mode 100644 index 0000000000000..c363ab6424812 --- /dev/null +++ b/packages/@aws-cdk/aws-backup/lib/backupable-resources-collector.ts @@ -0,0 +1,52 @@ +import * as dynamodb from '@aws-cdk/aws-dynamodb'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as efs from '@aws-cdk/aws-efs'; +import * as rds from '@aws-cdk/aws-rds'; +import { IAspect, IConstruct, Stack } from '@aws-cdk/core'; + +export class BackupableResourcesCollector implements IAspect { + public readonly resources: string[] = []; + + public visit(node: IConstruct) { + if (node instanceof efs.CfnFileSystem) { + this.resources.push(Stack.of(node).formatArn({ + service: 'elasticfilesystem', + resource: 'file-system', + resourceName: node.ref, + })); + } + + if (node instanceof dynamodb.CfnTable) { + this.resources.push(Stack.of(node).formatArn({ + service: 'dynamodb', + resource: 'table', + resourceName: node.ref, + })); + } + + if (node instanceof ec2.CfnInstance) { + this.resources.push(Stack.of(node).formatArn({ + service: 'ec2', + resource: 'instance', + resourceName: node.ref, + })); + } + + if (node instanceof ec2.CfnVolume) { + this.resources.push(Stack.of(node).formatArn({ + service: 'ec2', + resource: 'volume', + resourceName: node.ref, + })); + } + + if (node instanceof rds.CfnDBInstance) { + this.resources.push(Stack.of(node).formatArn({ + service: 'rds', + resource: 'db', + sep: ':', + resourceName: node.ref, + })); + } + } +} diff --git a/packages/@aws-cdk/aws-backup/lib/index.ts b/packages/@aws-cdk/aws-backup/lib/index.ts index adc11b8e473b7..7b34df14d75df 100644 --- a/packages/@aws-cdk/aws-backup/lib/index.ts +++ b/packages/@aws-cdk/aws-backup/lib/index.ts @@ -1,2 +1,8 @@ +export * from './vault'; +export * from './plan'; +export * from './rule'; +export * from './selection'; +export * from './resource'; + // AWS::Backup CloudFormation Resources: export * from './backup.generated'; diff --git a/packages/@aws-cdk/aws-backup/lib/plan.ts b/packages/@aws-cdk/aws-backup/lib/plan.ts new file mode 100644 index 0000000000000..99301fde7bde9 --- /dev/null +++ b/packages/@aws-cdk/aws-backup/lib/plan.ts @@ -0,0 +1,201 @@ +import { Construct, IResource, Lazy, Resource } from '@aws-cdk/core'; +import { CfnBackupPlan } from './backup.generated'; +import { BackupPlanRule } from './rule'; +import { BackupSelection, BackupSelectionOptions } from './selection'; +import { BackupVault, IBackupVault } from './vault'; + +/** + * A backup plan + */ +export interface IBackupPlan extends IResource { + /** + * The identifier of the backup plan. + * + * @attribute + */ + readonly backupPlanId: string; +} + +/** + * Properties for a BackupPlan + */ +export interface BackupPlanProps { + /** + * The display name of the backup plan. + * + * @default - A CDK generated name + */ + readonly backupPlanName?: string; + + /** + * The backup vault where backups are stored + * + * @default - use the vault defined at the rule level. If not defined a new + * common vault for the plan will be created + */ + readonly backupVault?: IBackupVault; + + /** + * Rules for the backup plan. Use `addRule()` to add rules after + * instantiation. + * + * @default - use `addRule()` to add rules + */ + readonly backupPlanRules?: BackupPlanRule[]; +} + +/** + * A backup plan + */ +export class BackupPlan extends Resource implements IBackupPlan { + /** + * Import an existing backup plan + */ + public static fromBackupPlanId(scope: Construct, id: string, backupPlanId: string): IBackupPlan { + class Import extends Resource implements IBackupPlan { + public readonly backupPlanId = backupPlanId; + } + return new Import(scope, id); + } + + /** + * Daily with 35 day retention + */ + public static daily35DayRetention(scope: Construct, id: string, backupVault?: IBackupVault) { + const plan = new BackupPlan(scope, id, { backupVault }); + plan.addRule(BackupPlanRule.daily()); + return plan; + } + + /** + * Daily and monthly with 1 year retention + */ + public static dailyMonthly1YearRetention(scope: Construct, id: string, backupVault?: IBackupVault) { + const plan = new BackupPlan(scope, id, { backupVault }); + plan.addRule(BackupPlanRule.daily()); + plan.addRule(BackupPlanRule.monthly1Year()); + return plan; + } + + /** + * Daily, weekly and monthly with 5 year retention + */ + public static dailyWeeklyMonthly5YearRetention(scope: Construct, id: string, backupVault?: IBackupVault) { + const plan = new BackupPlan(scope, id, { backupVault }); + plan.addRule(BackupPlanRule.daily()); + plan.addRule(BackupPlanRule.weekly()); + plan.addRule(BackupPlanRule.monthly5Year()); + return plan; + } + + /** + * Daily, weekly and monthly with 7 year retention + */ + public static dailyWeeklyMonthly7YearRetention(scope: Construct, id: string, backupVault?: IBackupVault) { + const plan = new BackupPlan(scope, id, { backupVault }); + plan.addRule(BackupPlanRule.daily()); + plan.addRule(BackupPlanRule.weekly()); + plan.addRule(BackupPlanRule.monthly7Year()); + return plan; + } + + public readonly backupPlanId: string; + + /** + * The ARN of the backup plan + * + * @attribute + */ + public readonly backupPlanArn: string; + + /** + * Version Id + * + * @attribute + */ + public readonly versionId: string; + + private readonly rules: CfnBackupPlan.BackupRuleResourceTypeProperty[] = []; + private _backupVault?: IBackupVault; + + constructor(scope: Construct, id: string, props: BackupPlanProps = {}) { + super(scope, id); + + const plan = new CfnBackupPlan(this, 'Resource', { + backupPlan: { + backupPlanName: props.backupPlanName || id, + backupPlanRule: Lazy.anyValue({ produce: () => this.rules }, { omitEmptyArray: true }), + }, + }); + + this.backupPlanId = plan.attrBackupPlanId; + this.backupPlanArn = plan.attrBackupPlanArn; + this.versionId = plan.attrVersionId; + + this._backupVault = props.backupVault; + + for (const rule of props.backupPlanRules || []) { + this.addRule(rule); + } + } + + /** + * Adds a rule to a plan + * + * @param rule the rule to add + */ + public addRule(rule: BackupPlanRule) { + let vault: IBackupVault; + if (rule.props.backupVault) { + vault = rule.props.backupVault; + } else if (this._backupVault) { + vault = this._backupVault; + } else { + this._backupVault = new BackupVault(this, 'Vault'); + vault = this._backupVault; + } + + this.rules.push({ + completionWindowMinutes: rule.props.completionWindow?.toMinutes(), + lifecycle: (rule.props.deleteAfter || rule.props.moveToColdStorageAfter) && { + deleteAfterDays: rule.props.deleteAfter?.toDays(), + moveToColdStorageAfterDays: rule.props.moveToColdStorageAfter?.toDays(), + }, + ruleName: rule.props.ruleName ?? `${this.node.id}Rule${this.rules.length}`, + scheduleExpression: rule.props.scheduleExpression?.expressionString, + startWindowMinutes: rule.props.startWindow?.toMinutes(), + targetBackupVault: vault.backupVaultName, + }); + } + + /** + * The backup vault where backups are stored if not defined at + * the rule level + */ + public get backupVault(): IBackupVault { + if (!this._backupVault) { + // This cannot happen but is here to make TypeScript happy + throw new Error('No backup vault!'); + } + + return this._backupVault; + } + + /** + * Adds a selection to this plan + */ + public addSelection(id: string, options: BackupSelectionOptions): BackupSelection { + return new BackupSelection(this, id, { + backupPlan: this, + ...options, + }); + } + + protected validate() { + if (this.rules.length === 0) { + return ['A backup plan must have at least 1 rule.']; + } + + return []; + } +} diff --git a/packages/@aws-cdk/aws-backup/lib/resource.ts b/packages/@aws-cdk/aws-backup/lib/resource.ts new file mode 100644 index 0000000000000..5f3073642c05b --- /dev/null +++ b/packages/@aws-cdk/aws-backup/lib/resource.ts @@ -0,0 +1,139 @@ +import * as dynamodb from '@aws-cdk/aws-dynamodb'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as efs from '@aws-cdk/aws-efs'; +import * as rds from '@aws-cdk/aws-rds'; +import { Construct, Stack } from '@aws-cdk/core'; + +/** + * An operation that is applied to a key-value pair + */ +export enum TagOperation { + /** + * StringEquals + */ + STRING_EQUALS = 'STRINGEQUALS', + + /** + * Dummy member + */ + DUMMY = 'dummy' +} + +/** + * A tag condition + */ +export interface TagCondition { + /** + * The key in a key-value pair. + * + * For example, in `"ec2:ResourceTag/Department": "accounting"`, + * `ec2:ResourceTag/Department` is the key. + */ + readonly key: string; + + /** + * An operation that is applied to a key-value pair used to filter + * resources in a selection. + * + * @default STRING_EQUALS + */ + readonly operation?: TagOperation; + + /** + * The value in a key-value pair. + * + * For example, in `"ec2:ResourceTag/Department": "accounting"`, + * `accounting` is the value. + */ + readonly value: string; +} + +/** + * A resource to backup + */ +export class BackupResource { + /** + * Adds all supported resources in a construct + * + * @param construct The construct containing resources to backup + */ + public static fromConstruct(construct: Construct) { + return new BackupResource(undefined, undefined, construct); + } + + /** + * A DynamoDB table + */ + public static fromDynamoDbTable(table: dynamodb.Table) { + return BackupResource.fromArn(table.tableArn); + } + + /** + * An EC2 instance + */ + public static fromEc2Instance(instance: ec2.Instance) { + return BackupResource.fromArn(Stack.of(instance).formatArn({ + service: 'ec2', + resource: 'instance', + resourceName: instance.instanceId, + })); + } + + /** + * An EFS file system + */ + public static fromEfsFileSystem(fileSystem: efs.FileSystem) { + return BackupResource.fromArn(Stack.of(fileSystem).formatArn({ + service: 'elasticfilesystem', + resource: 'file-system', + resourceName: fileSystem.fileSystemId, + })); + } + + /** + * A RDS database instance + */ + public static fromRdsDatabaseInstance(instance: rds.DatabaseInstance) { + return BackupResource.fromArn(instance.instanceArn); + } + + /** + * A list of ARNs or match patterns such as + * `arn:aws:ec2:us-east-1:123456789012:volume/*` + */ + public static fromArn(arn: string) { + return new BackupResource(arn); + } + + /** + * A tag condition + */ + public static fromTag(key: string, value: string, operation?: TagOperation) { + return new BackupResource(undefined, { + key, + value, + operation, + }); + } + + /** + * A resource + */ + public readonly resource?: string; + + /** + * A condition on a tag + */ + public readonly tagCondition?: TagCondition; + + /** + * A construct + */ + public readonly construct?: Construct; + + constructor(resource?: string, tagCondition?: TagCondition, construct?: Construct) { + this.resource = resource; + this.tagCondition = tagCondition; + this.construct = construct; + } +} diff --git a/packages/@aws-cdk/aws-backup/lib/rule.ts b/packages/@aws-cdk/aws-backup/lib/rule.ts new file mode 100644 index 0000000000000..3c4a730d90a50 --- /dev/null +++ b/packages/@aws-cdk/aws-backup/lib/rule.ts @@ -0,0 +1,160 @@ +import * as events from '@aws-cdk/aws-events'; +import { Duration } from '@aws-cdk/core'; +import { IBackupVault } from './vault'; + +/** + * Properties for a BackupPlanRule + */ +export interface BackupPlanRuleProps { + /** + * The duration after a backup job is successfully started before it must be + * completed or it is canceled by AWS Backup. + * + * @default - 8 hours + */ + readonly completionWindow?: Duration; + + /** + * Specifies the duration after creation that a recovery point is deleted. + * Must be greater than `moveToColdStorageAfter`. + * + * @default - recovery point is never deleted + */ + readonly deleteAfter?: Duration; + + /** + * Specifies the duration after creation that a recovery point is moved to cold + * storage. + * + * @default - recovery point is never moved to cold storage + */ + readonly moveToColdStorageAfter?: Duration; + + /** + * A display name for the backup rule. + * + * @default - a CDK generated name + */ + readonly ruleName?: string; + + /** + * A CRON expression specifying when AWS Backup initiates a backup job. + * + * @default - no schedule + */ + readonly scheduleExpression?: events.Schedule; + + /** + * The duration after a backup is scheduled before a job is canceled if it doesn't start successfully. + * + * @default - 8 hours + */ + readonly startWindow?: Duration; + + /** + * The backup vault where backups are + * + * @default - use the vault defined at the plan level. If not defined a new + * common vault for the plan will be created + */ + readonly backupVault?: IBackupVault; +} + +/** + * A backup plan rule + */ +export class BackupPlanRule { + /** + * Daily with 35 days retention + */ + public static daily(backupVault?: IBackupVault) { + return new BackupPlanRule({ + backupVault, + ruleName: 'Daily', + scheduleExpression: events.Schedule.cron({ + hour: '5', + minute: '0', + }), + deleteAfter: Duration.days(35), + }); + } + + /** + * Weekly with 3 months retention + */ + public static weekly(backupVault?: IBackupVault) { + return new BackupPlanRule({ + backupVault, + ruleName: 'Weekly', + scheduleExpression: events.Schedule.cron({ + hour: '5', + minute: '0', + weekDay: 'SAT', + }), + deleteAfter: Duration.days(30 * 3), + }); + } + + /** + * Monthly 1 year retention, move to cold storage after 1 month + */ + public static monthly1Year(backupVault?: IBackupVault) { + return new BackupPlanRule({ + backupVault, + ruleName: 'Monthly1Year', + scheduleExpression: events.Schedule.cron({ + day: '1', + hour: '5', + minute: '0', + }), + moveToColdStorageAfter: Duration.days(30), + deleteAfter: Duration.days(365), + }); + } + + /** + * Monthly 5 year retention, move to cold storage after 3 months + */ + public static monthly5Year(backupVault?: IBackupVault) { + return new BackupPlanRule({ + backupVault, + ruleName: 'Monthly5Year', + scheduleExpression: events.Schedule.cron({ + day: '1', + hour: '5', + minute: '0', + }), + moveToColdStorageAfter: Duration.days(30 * 3), + deleteAfter: Duration.days(365 * 5), + }); + } + + /** + * Monthly 7 year retention, move to cold storage after 3 months + */ + public static monthly7Year(backupVault?: IBackupVault) { + return new BackupPlanRule({ + backupVault, + ruleName: 'Monthly7Year', + scheduleExpression: events.Schedule.cron({ + day: '1', + hour: '5', + minute: '0', + }), + moveToColdStorageAfter: Duration.days(30 * 3), + deleteAfter: Duration.days(365 * 7), + }); + } + + /** @param props Rule properties */ + constructor(public readonly props: BackupPlanRuleProps) { + if (props.deleteAfter && props.moveToColdStorageAfter && + props.deleteAfter.toSeconds() < props.moveToColdStorageAfter.toSeconds()) { + throw new Error('`deleteAfter` must be greater than `moveToColdStorageAfter`'); + } + + if (props.scheduleExpression && !/^cron/.test(props.scheduleExpression.expressionString)) { + throw new Error('`scheduleExpression` must be of type `cron`'); + } + } +} diff --git a/packages/@aws-cdk/aws-backup/lib/selection.ts b/packages/@aws-cdk/aws-backup/lib/selection.ts new file mode 100644 index 0000000000000..4e1ba54b472cb --- /dev/null +++ b/packages/@aws-cdk/aws-backup/lib/selection.ts @@ -0,0 +1,136 @@ +import * as iam from '@aws-cdk/aws-iam'; +import { Construct, Lazy, Resource } from '@aws-cdk/core'; +import { CfnBackupSelection } from './backup.generated'; +import { BackupableResourcesCollector } from './backupable-resources-collector'; +import { IBackupPlan } from './plan'; +import { BackupResource, TagOperation } from './resource'; + +/** + * Options for a BackupSelection + */ +export interface BackupSelectionOptions { + /** + * The resources to backup. + * Use the helper static methods defined on `BackupResource`. + */ + readonly resources: BackupResource[]; + + /** + * The name for this selection + * + * @default - a CDK generated name + */ + readonly backupSelectionName?: string; + + /** + * The role that AWS Backup uses to authenticate when backuping or restoring + * the resources. The `AWSBackupServiceRolePolicyForBackup` managed policy + * will be attached to this role. + * + * @default - a new role will be created + */ + readonly role?: iam.IRole; + + /** + * Whether to automatically give restores permissions to the role that AWS + * Backup uses. If `true`, the `AWSBackupServiceRolePolicyForRestores` managed + * policy will be attached to the role. + * + * @default false + */ + readonly allowRestores?: boolean; +} + +/** + * Properties for a BackupSelection + */ +export interface BackupSelectionProps extends BackupSelectionOptions { + /** + * The backup plan for this selection + */ + readonly backupPlan: IBackupPlan; +} + +/** + * A backup selection + */ +export class BackupSelection extends Resource implements iam.IGrantable { + /** + * The identifier of the backup plan. + * + * @attribute + */ + public readonly backupPlanId: string; + + /** + * The identifier of the backup selection. + * + * @attribute + */ + public readonly selectionId: string; + + /** + * The principal to grant permissions to + */ + public readonly grantPrincipal: iam.IPrincipal; + + private listOfTags: CfnBackupSelection.ConditionResourceTypeProperty[] = []; + private resources: string[] = []; + private readonly backupableResourcesCollector = new BackupableResourcesCollector(); + + constructor(scope: Construct, id: string, props: BackupSelectionProps) { + super(scope, id); + + const role = props.role || new iam.Role(this, 'Role', { + assumedBy: new iam.ServicePrincipal('backup.amazonaws.com'), + }); + role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSBackupServiceRolePolicyForBackup')); + if (props.allowRestores) { + role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSBackupServiceRolePolicyForRestores')); + } + this.grantPrincipal = role; + + const selection = new CfnBackupSelection(this, 'Resource', { + backupPlanId: props.backupPlan.backupPlanId, + backupSelection: { + iamRoleArn: role.roleArn, + selectionName: props.backupSelectionName || this.node.id, + listOfTags: Lazy.anyValue({ + produce: () => this.listOfTags, + }, { omitEmptyArray: true }), + resources: Lazy.listValue({ + produce: () => [...this.resources, ...this.backupableResourcesCollector.resources ], + }, { omitEmpty: true }), + }, + }); + + this.backupPlanId = selection.attrBackupPlanId; + this.selectionId = selection.attrSelectionId; + + for (const resource of props.resources) { + this.addResource(resource); + } + } + + private addResource(resource: BackupResource) { + if (resource.tagCondition) { + this.listOfTags.push({ + conditionKey: resource.tagCondition.key, + conditionType: resource.tagCondition.operation || TagOperation.STRING_EQUALS, + conditionValue: resource.tagCondition.value, + }); + } + + if (resource.resource) { + this.resources.push(resource.resource); + } + + if (resource.construct) { + resource.construct.node.applyAspect(this.backupableResourcesCollector); + // Cannot push `this.backupableResourcesCollector.resources` to + // `this.resources` here because it has not been evaluated yet. + // Will be concatenated to `this.resources` in a `Lazy.listValue` + // in the constructor instead. + } + } +} diff --git a/packages/@aws-cdk/aws-backup/lib/vault.ts b/packages/@aws-cdk/aws-backup/lib/vault.ts new file mode 100644 index 0000000000000..849f7dfa5cfa5 --- /dev/null +++ b/packages/@aws-cdk/aws-backup/lib/vault.ts @@ -0,0 +1,164 @@ +import * as iam from '@aws-cdk/aws-iam'; +import * as kms from '@aws-cdk/aws-kms'; +import * as sns from '@aws-cdk/aws-sns'; +import { Aws, Construct, IResource, RemovalPolicy, Resource } from '@aws-cdk/core'; +import { CfnBackupVault } from './backup.generated'; + +/** + * A backup vault + */ +export interface IBackupVault extends IResource { + /** + * The name of a logical container where backups are stored. + * + * @attribute + */ + readonly backupVaultName: string; +} + +/** + * Properties for a BackupVault + */ +export interface BackupVaultProps { + /** + * The name of a logical container where backups are stored. + * + * @default - A CDK generated name + */ + readonly backupVaultName?: string; + + /** + * A resource-based policy that is used to manage access permissions on the + * backup vault. + * + * @default - access is not restricted + */ + readonly accessPolicy?: iam.PolicyDocument; + + /** + * The server-side encryption key to use to protect your backups. + * + * @default - an Amazon managed KMS key + */ + readonly encryptionKey?: kms.IKey; + + /** + * A SNS topic to send vault events to. + * + * @see https://docs.aws.amazon.com/aws-backup/latest/devguide/sns-notifications.html + * + * @default - no notifications + */ + readonly notificationTopic?: sns.ITopic + + /** + * The vault events to send. + * + * @see https://docs.aws.amazon.com/aws-backup/latest/devguide/sns-notifications.html + * + * @default - all vault events if `notificationTopic` is defined + */ + readonly notificationEvents?: BackupVaultEvents[]; + + /** + * The removal policy to apply to the vault. Note that removing a vault + * that contains recovery points will fail. + * + * @default RemovalPolicy.RETAIN + */ + readonly removalPolicy?: RemovalPolicy; +} + +/** + * Backup vault events + */ +export enum BackupVaultEvents { + /** BACKUP_JOB_STARTED */ + BACKUP_JOB_STARTED = 'BACKUP_JOB_STARTED', + /** BACKUP_JOB_COMPLETED */ + BACKUP_JOB_COMPLETED = 'BACKUP_JOB_COMPLETED', + /** BACKUP_JOB_SUCCESSFUL */ + BACKUP_JOB_SUCCESSFUL = 'BACKUP_JOB_SUCCESSFUL', + /** BACKUP_JOB_FAILED */ + BACKUP_JOB_FAILED = 'BACKUP_JOB_FAILED', + /** BACKUP_JOB_EXPIRED */ + BACKUP_JOB_EXPIRED = 'BACKUP_JOB_EXPIRED', + /** RESTORE_JOB_STARTED */ + RESTORE_JOB_STARTED = 'RESTORE_JOB_STARTED', + /** RESTORE_JOB_COMPLETED */ + RESTORE_JOB_COMPLETED = 'RESTORE_JOB_COMPLETED', + /** RESTORE_JOB_SUCCESSFUL */ + RESTORE_JOB_SUCCESSFUL = 'RESTORE_JOB_SUCCESSFUL', + /** RESTORE_JOB_FAILED */ + RESTORE_JOB_FAILED = 'RESTORE_JOB_FAILED', + /** COPY_JOB_STARTED */ + COPY_JOB_STARTED = 'COPY_JOB_STARTED', + /** COPY_JOB_SUCCESSFUL */ + COPY_JOB_SUCCESSFUL = 'COPY_JOB_SUCCESSFUL', + /** COPY_JOB_FAILED */ + COPY_JOB_FAILED = 'COPY_JOB_FAILED', + /** RECOVERY_POINT_MODIFIED */ + RECOVERY_POINT_MODIFIED = 'RECOVERY_POINT_MODIFIED', + /** BACKUP_PLAN_CREATED */ + BACKUP_PLAN_CREATED = 'BACKUP_PLAN_CREATED', + /** BACKUP_PLAN_MODIFIED */ + BACKUP_PLAN_MODIFIED = 'BACKUP_PLAN_MODIFIED', +} + +/** + * A backup vault + */ +export class BackupVault extends Resource implements IBackupVault { + /** + * Import an existing backup vault + */ + public static fromBackupVaultName(scope: Construct, id: string, backupVaultName: string): IBackupVault { + class Import extends Resource implements IBackupVault { + public readonly backupVaultName = backupVaultName; + } + return new Import(scope, id); + } + + public readonly backupVaultName: string; + + /** + * The ARN of the backup vault + * + * @attribute + */ + public readonly backupVaultArn: string; + + constructor(scope: Construct, id: string, props: BackupVaultProps = {}) { + super(scope, id); + + if (props.backupVaultName && !/^[a-zA-Z0-9\-_\.]{1,50}$/.test(props.backupVaultName)) { + throw new Error('Expected vault name to match pattern `^[a-zA-Z0-9\-\_\.]{1,50}$`'); + } + + let notifications: CfnBackupVault.NotificationObjectTypeProperty | undefined; + if (props.notificationTopic) { + notifications = { + backupVaultEvents: props.notificationEvents || Object.values(BackupVaultEvents), + snsTopicArn: props.notificationTopic.topicArn, + }; + props.notificationTopic.grantPublish(new iam.ServicePrincipal('backup.amazonaws.com')); + } + + const vault = new CfnBackupVault(this, 'Resource', { + backupVaultName: props.backupVaultName || this.uniqueVaultName(), + accessPolicy: props.accessPolicy && props.accessPolicy.toJSON(), + encryptionKeyArn: props.encryptionKey && props.encryptionKey.keyArn, + notifications, + }); + vault.applyRemovalPolicy(props.removalPolicy); + + this.backupVaultName = vault.attrBackupVaultName; + this.backupVaultArn = vault.attrBackupVaultArn; + } + + private uniqueVaultName() { + // Max length of 50 chars, get the last 50 chars + const id = `${this.node.uniqueId}${Aws.STACK_NAME}`; + return id.substring(Math.max(id.length - 50, 0), id.length); + } +} diff --git a/packages/@aws-cdk/aws-backup/package.json b/packages/@aws-cdk/aws-backup/package.json index 84dfede5a7d74..6283f3ddd0fd4 100644 --- a/packages/@aws-cdk/aws-backup/package.json +++ b/packages/@aws-cdk/aws-backup/package.json @@ -83,14 +83,31 @@ "devDependencies": { "@aws-cdk/assert": "0.0.0", "cdk-build-tools": "0.0.0", + "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" }, "dependencies": { + "@aws-cdk/aws-dynamodb": "0.0.0", + "@aws-cdk/aws-ec2": "0.0.0", + "@aws-cdk/aws-efs": "0.0.0", + "@aws-cdk/aws-events": "0.0.0", + "@aws-cdk/aws-iam": "0.0.0", + "@aws-cdk/aws-kms": "0.0.0", + "@aws-cdk/aws-rds": "0.0.0", + "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/core": "0.0.0", "constructs": "^3.0.2" }, "peerDependencies": { + "@aws-cdk/aws-dynamodb": "0.0.0", + "@aws-cdk/aws-ec2": "0.0.0", + "@aws-cdk/aws-efs": "0.0.0", + "@aws-cdk/aws-events": "0.0.0", + "@aws-cdk/aws-iam": "0.0.0", + "@aws-cdk/aws-kms": "0.0.0", + "@aws-cdk/aws-rds": "0.0.0", + "@aws-cdk/aws-sns": "0.0.0", "@aws-cdk/core": "0.0.0", "constructs": "^3.0.2" }, diff --git a/packages/@aws-cdk/aws-backup/test/backup.test.ts b/packages/@aws-cdk/aws-backup/test/backup.test.ts deleted file mode 100644 index e394ef336bfb4..0000000000000 --- a/packages/@aws-cdk/aws-backup/test/backup.test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import '@aws-cdk/assert/jest'; -import {} from '../lib'; - -test('No tests are specified for this package', () => { - expect(true).toBe(true); -}); diff --git a/packages/@aws-cdk/aws-backup/test/integ.backup.expected.json b/packages/@aws-cdk/aws-backup/test/integ.backup.expected.json new file mode 100644 index 0000000000000..bad27ac4ec97f --- /dev/null +++ b/packages/@aws-cdk/aws-backup/test/integ.backup.expected.json @@ -0,0 +1,204 @@ +{ + "Resources": { + "TableCD117FA1": { + "Type": "AWS::DynamoDB::Table", + "Properties": { + "KeySchema": [ + { + "AttributeName": "id", + "KeyType": "HASH" + } + ], + "AttributeDefinitions": [ + { + "AttributeName": "id", + "AttributeType": "S" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "FileSystem": { + "Type": "AWS::EFS::FileSystem" + }, + "Vault23237E5B": { + "Type": "AWS::Backup::BackupVault", + "Properties": { + "BackupVaultName": { + "Fn::Join": [ + "", + [ + "cdkbackupVaultC2A6D3CB", + { + "Ref": "AWS::StackName" + } + ] + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "PlanDAF4E53A": { + "Type": "AWS::Backup::BackupPlan", + "Properties": { + "BackupPlan": { + "BackupPlanName": "Plan", + "BackupPlanRule": [ + { + "Lifecycle": { + "DeleteAfterDays": 35 + }, + "RuleName": "Daily", + "ScheduleExpression": "cron(0 5 * * ? *)", + "TargetBackupVault": { + "Fn::GetAtt": [ + "Vault23237E5B", + "BackupVaultName" + ] + } + }, + { + "Lifecycle": { + "DeleteAfterDays": 90 + }, + "RuleName": "Weekly", + "ScheduleExpression": "cron(0 5 ? * SAT *)", + "TargetBackupVault": { + "Fn::GetAtt": [ + "Vault23237E5B", + "BackupVaultName" + ] + } + }, + { + "Lifecycle": { + "DeleteAfterDays": 1825, + "MoveToColdStorageAfterDays": 90 + }, + "RuleName": "Monthly5Year", + "ScheduleExpression": "cron(0 5 1 * ? *)", + "TargetBackupVault": { + "Fn::GetAtt": [ + "Vault23237E5B", + "BackupVaultName" + ] + } + } + ] + } + } + }, + "PlanSelectionRole6D10F4B7": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "backup.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup" + ] + ] + } + ] + } + }, + "PlanSelectionF88CBC04": { + "Type": "AWS::Backup::BackupSelection", + "Properties": { + "BackupPlanId": { + "Fn::GetAtt": [ + "PlanDAF4E53A", + "BackupPlanId" + ] + }, + "BackupSelection": { + "IamRoleArn": { + "Fn::GetAtt": [ + "PlanSelectionRole6D10F4B7", + "Arn" + ] + }, + "ListOfTags": [ + { + "ConditionKey": "stage", + "ConditionType": "STRINGEQUALS", + "ConditionValue": "prod" + } + ], + "Resources": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":dynamodb:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":table/", + { + "Ref": "TableCD117FA1" + } + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":elasticfilesystem:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":file-system/", + { + "Ref": "FileSystem" + } + ] + ] + } + ], + "SelectionName": "Selection" + } + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-backup/test/integ.backup.ts b/packages/@aws-cdk/aws-backup/test/integ.backup.ts new file mode 100644 index 0000000000000..a45a5abbfa077 --- /dev/null +++ b/packages/@aws-cdk/aws-backup/test/integ.backup.ts @@ -0,0 +1,36 @@ +import * as dynamodb from '@aws-cdk/aws-dynamodb'; +import * as efs from '@aws-cdk/aws-efs'; +import { App, Construct, RemovalPolicy, Stack, StackProps } from '@aws-cdk/core'; +import * as backup from '../lib'; + +class TestStack extends Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + new dynamodb.Table(this, 'Table', { + partitionKey: { + name: 'id', + type: dynamodb.AttributeType.STRING, + }, + removalPolicy: RemovalPolicy.DESTROY, + }); + + new efs.CfnFileSystem(this, 'FileSystem'); + + const vault = new backup.BackupVault(this, 'Vault', { + removalPolicy: RemovalPolicy.DESTROY, + }); + const plan = backup.BackupPlan.dailyWeeklyMonthly5YearRetention(this, 'Plan', vault); + + plan.addSelection('Selection', { + resources: [ + backup.BackupResource.fromConstruct(this), // All backupable resources in this construct + backup.BackupResource.fromTag('stage', 'prod'), // Resources that are tagged stage=prod + ], + }); + } +} + +const app = new App(); +new TestStack(app, 'cdk-backup'); +app.synth(); diff --git a/packages/@aws-cdk/aws-backup/test/plan.test.ts b/packages/@aws-cdk/aws-backup/test/plan.test.ts new file mode 100644 index 0000000000000..9d2eef140846e --- /dev/null +++ b/packages/@aws-cdk/aws-backup/test/plan.test.ts @@ -0,0 +1,206 @@ +import '@aws-cdk/assert/jest'; +import * as events from '@aws-cdk/aws-events'; +import { App, Duration, Stack } from '@aws-cdk/core'; +import { BackupPlan, BackupPlanRule, BackupVault } from '../lib'; + +let stack: Stack; +beforeEach(() => { + stack = new Stack(); +}); + +test('create a plan and add rules', () => { + // GIVEN + const vault = new BackupVault(stack, 'Vault'); + const otherVault = new BackupVault(stack, 'OtherVault'); + + // WHEN + const plan = new BackupPlan(stack, 'Plan', { + backupVault: vault, + backupPlanRules: [ + new BackupPlanRule({ + completionWindow: Duration.hours(2), + startWindow: Duration.hours(1), + scheduleExpression: events.Schedule.cron({ + day: '15', + hour: '3', + minute: '30', + }), + moveToColdStorageAfter: Duration.days(30), + }), + ], + }); + plan.addRule(BackupPlanRule.monthly5Year(otherVault)); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupPlan', { + BackupPlan: { + BackupPlanName: 'Plan', + BackupPlanRule: [ + { + CompletionWindowMinutes: 120, + Lifecycle: { + MoveToColdStorageAfterDays: 30, + }, + RuleName: 'PlanRule0', + ScheduleExpression: 'cron(30 3 15 * ? *)', + StartWindowMinutes: 60, + TargetBackupVault: { + 'Fn::GetAtt': [ + 'Vault23237E5B', + 'BackupVaultName', + ], + }, + }, + { + Lifecycle: { + DeleteAfterDays: 1825, + MoveToColdStorageAfterDays: 90, + }, + RuleName: 'Monthly5Year', + ScheduleExpression: 'cron(0 5 1 * ? *)', + TargetBackupVault: { + 'Fn::GetAtt': [ + 'OtherVault3C99BCE2', + 'BackupVaultName', + ], + }, + }, + ], + }, + }); +}); + +test('daily35DayRetention', () => { + // WHEN + BackupPlan.daily35DayRetention(stack, 'D35'); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupPlan', { + BackupPlan: { + BackupPlanName: 'D35', + BackupPlanRule: [ + { + Lifecycle: { + DeleteAfterDays: 35, + }, + RuleName: 'Daily', + ScheduleExpression: 'cron(0 5 * * ? *)', + TargetBackupVault: { + 'Fn::GetAtt': [ + 'D35Vault2A9EB06F', + 'BackupVaultName', + ], + }, + }, + ], + }, + }); +}); + +test('dailyWeeklyMonthly7YearRetention', () => { + // WHEN + BackupPlan.dailyWeeklyMonthly7YearRetention(stack, 'DWM7'); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupPlan', { + BackupPlan: { + BackupPlanName: 'DWM7', + BackupPlanRule: [ + { + Lifecycle: { + DeleteAfterDays: 35, + }, + RuleName: 'Daily', + ScheduleExpression: 'cron(0 5 * * ? *)', + TargetBackupVault: { + 'Fn::GetAtt': [ + 'DWM7Vault21F17E61', + 'BackupVaultName', + ], + }, + }, + { + Lifecycle: { + DeleteAfterDays: 90, + }, + RuleName: 'Weekly', + ScheduleExpression: 'cron(0 5 ? * SAT *)', + TargetBackupVault: { + 'Fn::GetAtt': [ + 'DWM7Vault21F17E61', + 'BackupVaultName', + ], + }, + }, + { + Lifecycle: { + DeleteAfterDays: 2555, + MoveToColdStorageAfterDays: 90, + }, + RuleName: 'Monthly7Year', + ScheduleExpression: 'cron(0 5 1 * ? *)', + TargetBackupVault: { + 'Fn::GetAtt': [ + 'DWM7Vault21F17E61', + 'BackupVaultName', + ], + }, + }, + ], + }, + }); +}); + +test('automatically creates a new vault', () => { + // GIVEN + const plan = new BackupPlan(stack, 'Plan'); + + // WHEN + plan.addRule(BackupPlanRule.daily()); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupPlan', { + BackupPlan: { + BackupPlanName: 'Plan', + BackupPlanRule: [ + { + Lifecycle: { + DeleteAfterDays: 35, + }, + RuleName: 'Daily', + ScheduleExpression: 'cron(0 5 * * ? *)', + TargetBackupVault: { + 'Fn::GetAtt': [ + 'PlanVault0284B0C2', + 'BackupVaultName', + ], + }, + }, + ], + }, + }); +}); + +test('throws when deleteAfter is not greater than moveToColdStorageAfter', () => { + expect(() => new BackupPlanRule({ + deleteAfter: Duration.days(5), + moveToColdStorageAfter: Duration.days(6), + })).toThrow(/`deleteAfter` must be greater than `moveToColdStorageAfter`/); +}); + +test('throws when scheduleExpression is not of type cron', () => { + expect(() => new BackupPlanRule({ + scheduleExpression: events.Schedule.rate(Duration.hours(5)), + })).toThrow(/`scheduleExpression` must be of type `cron`/); +}); + +test('synth fails when plan has no rules', () => { + // GIVEN + const app = new App(); + const myStack = new Stack(app, 'Stack'); + + // WHEN + new BackupPlan(myStack, 'Plan'); + + expect(() => app.synth()).toThrow(/A backup plan must have at least 1 rule/); +}); diff --git a/packages/@aws-cdk/aws-backup/test/selection.test.ts b/packages/@aws-cdk/aws-backup/test/selection.test.ts new file mode 100644 index 0000000000000..4d8e7652a6925 --- /dev/null +++ b/packages/@aws-cdk/aws-backup/test/selection.test.ts @@ -0,0 +1,292 @@ +import '@aws-cdk/assert/jest'; +import * as dynamodb from '@aws-cdk/aws-dynamodb'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as efs from '@aws-cdk/aws-efs'; +import { Construct, Stack } from '@aws-cdk/core'; +import { BackupPlan, BackupResource, BackupSelection } from '../lib'; + +let stack: Stack; +let plan: BackupPlan; +beforeEach(() => { + stack = new Stack(); + plan = BackupPlan.dailyWeeklyMonthly5YearRetention(stack, 'Plan'); +}); + +test('create a selection', () => { + // WHEN + new BackupSelection(stack, 'Selection', { + backupPlan: plan, + resources: [ + BackupResource.fromArn('arn1'), + BackupResource.fromArn('arn2'), + BackupResource.fromTag('stage', 'prod'), + BackupResource.fromTag('cost center', 'cloud'), + ], + }); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupSelection', { + BackupPlanId: { + 'Fn::GetAtt': [ + 'PlanDAF4E53A', + 'BackupPlanId', + ], + }, + BackupSelection: { + IamRoleArn: { + 'Fn::GetAtt': [ + 'SelectionRoleD0EAEC83', + 'Arn', + ], + }, + ListOfTags: [ + { + ConditionKey: 'stage', + ConditionType: 'STRINGEQUALS', + ConditionValue: 'prod', + }, + { + ConditionKey: 'cost center', + ConditionType: 'STRINGEQUALS', + ConditionValue: 'cloud', + }, + ], + Resources: [ + 'arn1', + 'arn2', + ], + SelectionName: 'Selection', + }, + }); + + expect(stack).toHaveResource('AWS::IAM::Role', { + ManagedPolicyArns: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup', + ], + ], + }, + ], + }); +}); + +test('allow restores', () => { + // WHEN + new BackupSelection(stack, 'Selection', { + backupPlan: plan, + resources: [ + BackupResource.fromArn('arn1'), + ], + allowRestores: true, + }); + + // THEN + expect(stack).toHaveResource('AWS::IAM::Role', { + ManagedPolicyArns: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores', + ], + ], + }, + ], + }); +}); + +test('fromConstruct', () => { + // GIVEN + class EfsConstruct extends Construct { + constructor(scope: Construct, id: string) { + super(scope, id); + new efs.CfnFileSystem(this, 'FileSystem'); + } + } + class MyConstruct extends Construct { + constructor(scope: Construct, id: string) { + super(scope, id); + + new dynamodb.Table(this, 'Table', { + partitionKey: { + name: 'id', + type: dynamodb.AttributeType.STRING, + }, + }); + + new EfsConstruct(this, 'EFS'); + } + } + const myConstruct = new MyConstruct(stack, 'MyConstruct'); + const efsConstruct = new EfsConstruct(stack, 'EfsConstruct'); + + // WHEN + plan.addSelection('Selection', { + resources: [ + BackupResource.fromConstruct(myConstruct), + BackupResource.fromConstruct(efsConstruct), + ], + }); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupSelection', { + BackupSelection: { + IamRoleArn: { + 'Fn::GetAtt': [ + 'PlanSelectionRole6D10F4B7', + 'Arn', + ], + }, + Resources: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':dynamodb:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':table/', + { + Ref: 'MyConstructTable25959456', + }, + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':elasticfilesystem:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':file-system/', + { + Ref: 'MyConstructEFSFileSystemC68B6B78', + }, + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':elasticfilesystem:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':file-system/', + { + Ref: 'EfsConstructFileSystemFBE43F88', + }, + ], + ], + }, + ], + SelectionName: 'Selection', + }, + }); +}); + +test('fromEc2Instance', () => { + // GIVEN + const vpc = new ec2.Vpc(stack, 'Vpc'); + const instance = new ec2.Instance(stack, 'Instance', { + vpc, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO), + machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }), + }); + + // WHEN + plan.addSelection('Selection', { + resources: [ + BackupResource.fromEc2Instance(instance), + ], + }); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupSelection', { + BackupSelection: { + IamRoleArn: { + 'Fn::GetAtt': [ + 'PlanSelectionRole6D10F4B7', + 'Arn', + ], + }, + Resources: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ec2:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':instance/', + { + Ref: 'InstanceC1063A87', + }, + ], + ], + }, + ], + SelectionName: 'Selection', + }, + }); +}); diff --git a/packages/@aws-cdk/aws-backup/test/vault.test.ts b/packages/@aws-cdk/aws-backup/test/vault.test.ts new file mode 100644 index 0000000000000..31e202a16b163 --- /dev/null +++ b/packages/@aws-cdk/aws-backup/test/vault.test.ts @@ -0,0 +1,152 @@ +import '@aws-cdk/assert/jest'; +import * as iam from '@aws-cdk/aws-iam'; +import * as kms from '@aws-cdk/aws-kms'; +import * as sns from '@aws-cdk/aws-sns'; +import { Stack } from '@aws-cdk/core'; +import { BackupVault, BackupVaultEvents } from '../lib'; + +let stack: Stack; +beforeEach(() => { + stack = new Stack(); +}); + +test('create a vault', () => { + // WHEN + new BackupVault(stack, 'Vault'); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupVault', { + BackupVaultName: { + 'Fn::Join': [ + '', + [ + 'Vault', + { + Ref: 'AWS::StackName', + }, + ], + ], + }, + }); +}); + +test('with access policy', () => { + // GIVEN + const accessPolicy = new iam.PolicyDocument({ + statements: [ + new iam.PolicyStatement({ + effect: iam.Effect.DENY, + principals: [new iam.AnyPrincipal()], + actions: ['backup:DeleteRecoveryPoint'], + resources: ['*'], + conditions: { + StringNotLike: { + 'aws:userId': [ + 'user-arn', + ], + }, + }, + }), + ], + }); + + // WHEN + new BackupVault(stack, 'Vault', { + accessPolicy, + }); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupVault', { + AccessPolicy: { + Version: '2012-10-17', + Statement: [ + { + Effect: 'Deny', + Principal: '*', + Action: 'backup:DeleteRecoveryPoint', + Resource: '*', + Condition: { + StringNotLike: { + 'aws:userId': [ + 'user-arn', + ], + }, + }, + }, + ], + }, + }); +}); + +test('with encryption key', () => { + // GIVEN + const encryptionKey = new kms.Key(stack, 'Key'); + + // WHEN + new BackupVault(stack, 'Vault', { + encryptionKey, + }); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupVault', { + EncryptionKeyArn: { + 'Fn::GetAtt': [ + 'Key961B73FD', + 'Arn', + ], + }, + }); +}); + +test('with notifications', () => { + // GIVEN + const topic = new sns.Topic(stack, 'Topic'); + + // WHEN + new BackupVault(stack, 'Vault', { + notificationTopic: topic, + notificationEvents: [ + BackupVaultEvents.BACKUP_JOB_COMPLETED, + BackupVaultEvents.COPY_JOB_FAILED, + ], + }); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupVault', { + Notifications: { + BackupVaultEvents: [ + 'BACKUP_JOB_COMPLETED', + 'COPY_JOB_FAILED', + ], + SNSTopicArn: { + Ref: 'TopicBFC7AF6E', + }, + }, + }); +}); + +test('defaults to all notifications', () => { + // GIVEN + const topic = new sns.Topic(stack, 'Topic'); + + // WHEN + new BackupVault(stack, 'Vault', { + notificationTopic: topic, + }); + + // THEN + expect(stack).toHaveResource('AWS::Backup::BackupVault', { + Notifications: { + BackupVaultEvents: Object.values(BackupVaultEvents), + SNSTopicArn: { + Ref: 'TopicBFC7AF6E', + }, + }, + }); +}); + +test('throws with invalid name', () => { + expect(() => new BackupVault(stack, 'Vault', { + backupVaultName: 'Hello!Inv@lid', + })).toThrow(/Expected vault name to match pattern/); +}); From 8c687f598d881cb5bfb7ce624446a52ea9f1fc9c Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Thu, 23 Apr 2020 18:04:01 +0200 Subject: [PATCH 27/28] chore: don't repack monocdk-experiment (#7565) It causes it to be incorrectly packged, since it has already prepared it's packaging assets in `dist/` --- pack.sh | 3 ++- packages/monocdk-experiment/.gitignore | 2 ++ packages/monocdk-experiment/build.sh | 7 ++++++- packages/monocdk-experiment/package.json | 2 +- scripts/list-packages | 3 ++- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pack.sh b/pack.sh index 02b901f141273..596e81c9bd65d 100755 --- a/pack.sh +++ b/pack.sh @@ -15,7 +15,8 @@ rm -fr ${distdir} mkdir -p ${distdir} # Split out jsii and non-jsii packages. Jsii packages will be built all at once. -# Non-jsii packages will be run individually. +# Non-jsii packages will be run individually. Note that currently the monoCDK +# package is handled as non-jsii because of the way it is packaged. echo "Collecting package list..." >&2 scripts/list-packages $TMPDIR/jsii.txt $TMPDIR/nonjsii.txt diff --git a/packages/monocdk-experiment/.gitignore b/packages/monocdk-experiment/.gitignore index a25055f733262..5603865e24a28 100644 --- a/packages/monocdk-experiment/.gitignore +++ b/packages/monocdk-experiment/.gitignore @@ -4,3 +4,5 @@ !gen.js staging/ tsconfig.json +.jsii +*.tsbuildinfo diff --git a/packages/monocdk-experiment/build.sh b/packages/monocdk-experiment/build.sh index eea6710a3cc93..c386b738c7026 100755 --- a/packages/monocdk-experiment/build.sh +++ b/packages/monocdk-experiment/build.sh @@ -22,7 +22,10 @@ ${CDK_PACKAGE_JSII_PACMAK:-jsii-pacmak} tarball=$PWD/dist/js/monocdk-experiment@*.tgz echo "verifying package..." -cd $(mktemp -d) +checkdir=$(mktemp -d) + +cd ${checkdir} + npm init -y npm install ${tarball} constructs@${constructs_version} node -e "require('monocdk-experiment')" @@ -40,3 +43,5 @@ mv ${unpacked} ${scriptdir}/staging # this is needed because the generated code is hosted under staging/, but during # it's creation, it was directly in the package root. mv ${scriptdir}/staging/.jsii ${scriptdir} + +rm -fr ${outdir} ${checkdir} diff --git a/packages/monocdk-experiment/package.json b/packages/monocdk-experiment/package.json index 17bd0a871959a..34e48d31bb95b 100644 --- a/packages/monocdk-experiment/package.json +++ b/packages/monocdk-experiment/package.json @@ -45,7 +45,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "typescript": "~3.8.3", + "jsii": "^1.4.1", "constructs": "^3.0.2", "@aws-cdk/alexa-ask": "0.0.0", "@aws-cdk/app-delivery": "0.0.0", diff --git a/scripts/list-packages b/scripts/list-packages index 95a2c5ecc0379..b4d16d6d8fc52 100755 --- a/scripts/list-packages +++ b/scripts/list-packages @@ -24,7 +24,8 @@ child_process.exec('lerna ls --toposort --json', { shell: true }, (error, stdout for (const module of modules) { const pkgJson = require(path.join(module.location, 'package.json')); - if (pkgJson.jsii) { + // MonoCDK-Experiment does its own packaging, should be handled "non-JSII style" + if (pkgJson.jsii && pkgJson.name !== 'monocdk-experiment') { jsiiDirectories.push(module.location); } else { nonJsiiNames.push(pkgJson.name); From a60490991c8c49bc3dc2c62dc617bce0b808c5db Mon Sep 17 00:00:00 2001 From: AWS CDK Team Date: Thu, 23 Apr 2020 12:25:19 +0000 Subject: [PATCH 28/28] chore(release): 1.35.0 --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ lerna.json | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fddbe75d0bad1..af8b4bfe02d1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,33 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.35.0](https://github.com/aws/aws-cdk/compare/v1.34.1...v1.35.0) (2020-04-23) + + +### ⚠ BREAKING CHANGES + +* **assets:** `cdk deploy` now needs `s3:ListBucket` instead of `s3:HeadObject`. +* **efs:** Exported types no longer have the `Efs` prefix. +* **efs:** `provisionedThroughputInMibps` property is renamed to `provisionedThroughputPerSecond` and has the type `Size`. +* **efs:** The property `fileSystemID` is now renamed to `fileSystemId` in the now named `FileSystemAttributes` (previously, `EfsFileSystemAttributes`). +* **efs:** `LifecyclePolicyProperty` is now renamed to `LifecyclePolicy`. + +### Features + +* **cfnspec:** cloudformation spec v13.0.0 ([#7504](https://github.com/aws/aws-cdk/issues/7504)) ([6903869](https://github.com/aws/aws-cdk/commit/6903869def944f8100c8eef51dd7145c181984e2)) +* **cloudtrail:** Lambda Function data events ([4a70138](https://github.com/aws/aws-cdk/commit/4a70138faf2e863be37a66bec23ed29a784b486a)) +* **cognito:** user pool domain ([#7224](https://github.com/aws/aws-cdk/issues/7224)) ([feadd6c](https://github.com/aws/aws-cdk/commit/feadd6cb643b415ae002191ba2cb4622221a5af6)), closes [#6787](https://github.com/aws/aws-cdk/issues/6787) +* **stepfunctions:** retrieve all reachable states from a given state in a state machine definition ([#7324](https://github.com/aws/aws-cdk/issues/7324)) ([ac3b330](https://github.com/aws/aws-cdk/commit/ac3b330c71ef258afd145b86fd90a06db5d1c990)), closes [#7256](https://github.com/aws/aws-cdk/issues/7256) + + +### Bug Fixes + +* **assets:** infrequent "ValidationError: S3 error: Access Denied" ([#7556](https://github.com/aws/aws-cdk/issues/7556)) ([00c9deb](https://github.com/aws/aws-cdk/commit/00c9deb975fe794eef9003cd26a6453abc514928)), closes [#6430](https://github.com/aws/aws-cdk/issues/6430) [#7553](https://github.com/aws/aws-cdk/issues/7553) +* **route53:** cannot add tags to `HostedZone` ([#7531](https://github.com/aws/aws-cdk/issues/7531)) ([2729804](https://github.com/aws/aws-cdk/commit/272980492dc6b98d71ce9c3b23cab38f656dc632)), closes [#7445](https://github.com/aws/aws-cdk/issues/7445) + + +* **efs:** drop Efs prefix from all exported types ([#7481](https://github.com/aws/aws-cdk/issues/7481)) ([ddd47cd](https://github.com/aws/aws-cdk/commit/ddd47cd7e0735424d2e47891c32e4b7813035067)) + ## [1.34.1](https://github.com/aws/aws-cdk/compare/v1.34.0...v1.34.1) (2020-04-22) diff --git a/lerna.json b/lerna.json index 83473fa4f25e3..539c1710776a4 100644 --- a/lerna.json +++ b/lerna.json @@ -10,5 +10,5 @@ "tools/*" ], "rejectCycles": "true", - "version": "1.34.1" + "version": "1.35.0" }