From 118df88add6079bee65aad321d27661ed9a67151 Mon Sep 17 00:00:00 2001 From: Kendra Neil <53584728+TheRealAmazonKendra@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:25:42 -0700 Subject: [PATCH 1/2] remove cdk-assets folder --- packages/cdk-assets/.eslintrc.js | 3 - packages/cdk-assets/.gitignore | 28 - packages/cdk-assets/.npmignore | 30 - packages/cdk-assets/LICENSE | 201 ----- packages/cdk-assets/NOTICE | 2 - packages/cdk-assets/README.md | 190 ----- packages/cdk-assets/bin/cdk-assets | 2 - packages/cdk-assets/bin/cdk-assets.ts | 67 -- .../bin/docker-credential-cdk-assets | 2 - .../bin/docker-credential-cdk-assets.ts | 42 -- packages/cdk-assets/bin/list.ts | 9 - packages/cdk-assets/bin/logging.ts | 24 - packages/cdk-assets/bin/publish.ts | 56 -- packages/cdk-assets/jest.config.js | 11 - packages/cdk-assets/lib/asset-manifest.ts | 313 -------- packages/cdk-assets/lib/aws.ts | 163 ---- packages/cdk-assets/lib/index.ts | 4 - packages/cdk-assets/lib/private/archive.ts | 92 --- .../cdk-assets/lib/private/asset-handler.ts | 38 - .../lib/private/docker-credentials.ts | 93 --- packages/cdk-assets/lib/private/docker.ts | 279 ------- packages/cdk-assets/lib/private/fs-extra.ts | 31 - .../lib/private/handlers/container-images.ts | 238 ------ .../cdk-assets/lib/private/handlers/files.ts | 292 -------- .../cdk-assets/lib/private/handlers/index.ts | 15 - .../cdk-assets/lib/private/placeholders.ts | 34 - packages/cdk-assets/lib/private/shell.ts | 127 ---- packages/cdk-assets/lib/private/util.ts | 12 - packages/cdk-assets/lib/progress.ts | 86 --- packages/cdk-assets/lib/publishing.ts | 256 ------- packages/cdk-assets/package.json | 82 -- packages/cdk-assets/test/archive.test.ts | 94 --- .../cdk-assets/test/docker-images.test.ts | 706 ------------------ packages/cdk-assets/test/fake-listener.ts | 17 - packages/cdk-assets/test/files.test.ts | 344 --------- packages/cdk-assets/test/manifest.test.ts | 117 --- packages/cdk-assets/test/mock-aws.ts | 74 -- .../cdk-assets/test/mock-child_process.ts | 69 -- packages/cdk-assets/test/placeholders.test.ts | 82 -- .../test/private/docker-credentials.test.ts | 220 ------ .../cdk-assets/test/private/docker.test.ts | 94 --- packages/cdk-assets/test/progress.test.ts | 85 --- .../test/test-archive-follow/data/one.txt | 1 - .../test/test-archive-follow/linked/two.txt | 1 - .../test/test-archive/executable.txt | 0 .../cdk-assets/test/test-archive/file1.txt | 1 - .../cdk-assets/test/test-archive/file2.txt | 2 - .../test/test-archive/subdir/file3.txt | 1 - packages/cdk-assets/test/util.test.ts | 32 - packages/cdk-assets/test/zipping.test.ts | 53 -- packages/cdk-assets/tsconfig.json | 28 - 51 files changed, 4843 deletions(-) delete mode 100644 packages/cdk-assets/.eslintrc.js delete mode 100644 packages/cdk-assets/.gitignore delete mode 100644 packages/cdk-assets/.npmignore delete mode 100644 packages/cdk-assets/LICENSE delete mode 100644 packages/cdk-assets/NOTICE delete mode 100644 packages/cdk-assets/README.md delete mode 100755 packages/cdk-assets/bin/cdk-assets delete mode 100644 packages/cdk-assets/bin/cdk-assets.ts delete mode 100755 packages/cdk-assets/bin/docker-credential-cdk-assets delete mode 100644 packages/cdk-assets/bin/docker-credential-cdk-assets.ts delete mode 100644 packages/cdk-assets/bin/list.ts delete mode 100644 packages/cdk-assets/bin/logging.ts delete mode 100644 packages/cdk-assets/bin/publish.ts delete mode 100644 packages/cdk-assets/jest.config.js delete mode 100644 packages/cdk-assets/lib/asset-manifest.ts delete mode 100644 packages/cdk-assets/lib/aws.ts delete mode 100644 packages/cdk-assets/lib/index.ts delete mode 100644 packages/cdk-assets/lib/private/archive.ts delete mode 100644 packages/cdk-assets/lib/private/asset-handler.ts delete mode 100644 packages/cdk-assets/lib/private/docker-credentials.ts delete mode 100644 packages/cdk-assets/lib/private/docker.ts delete mode 100644 packages/cdk-assets/lib/private/fs-extra.ts delete mode 100644 packages/cdk-assets/lib/private/handlers/container-images.ts delete mode 100644 packages/cdk-assets/lib/private/handlers/files.ts delete mode 100644 packages/cdk-assets/lib/private/handlers/index.ts delete mode 100644 packages/cdk-assets/lib/private/placeholders.ts delete mode 100644 packages/cdk-assets/lib/private/shell.ts delete mode 100644 packages/cdk-assets/lib/private/util.ts delete mode 100644 packages/cdk-assets/lib/progress.ts delete mode 100644 packages/cdk-assets/lib/publishing.ts delete mode 100644 packages/cdk-assets/package.json delete mode 100644 packages/cdk-assets/test/archive.test.ts delete mode 100644 packages/cdk-assets/test/docker-images.test.ts delete mode 100644 packages/cdk-assets/test/fake-listener.ts delete mode 100644 packages/cdk-assets/test/files.test.ts delete mode 100644 packages/cdk-assets/test/manifest.test.ts delete mode 100644 packages/cdk-assets/test/mock-aws.ts delete mode 100644 packages/cdk-assets/test/mock-child_process.ts delete mode 100644 packages/cdk-assets/test/placeholders.test.ts delete mode 100644 packages/cdk-assets/test/private/docker-credentials.test.ts delete mode 100644 packages/cdk-assets/test/private/docker.test.ts delete mode 100644 packages/cdk-assets/test/progress.test.ts delete mode 100644 packages/cdk-assets/test/test-archive-follow/data/one.txt delete mode 100644 packages/cdk-assets/test/test-archive-follow/linked/two.txt delete mode 100755 packages/cdk-assets/test/test-archive/executable.txt delete mode 100644 packages/cdk-assets/test/test-archive/file1.txt delete mode 100644 packages/cdk-assets/test/test-archive/file2.txt delete mode 100644 packages/cdk-assets/test/test-archive/subdir/file3.txt delete mode 100644 packages/cdk-assets/test/util.test.ts delete mode 100644 packages/cdk-assets/test/zipping.test.ts delete mode 100644 packages/cdk-assets/tsconfig.json diff --git a/packages/cdk-assets/.eslintrc.js b/packages/cdk-assets/.eslintrc.js deleted file mode 100644 index 2658ee8727166..0000000000000 --- a/packages/cdk-assets/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc'); -baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; -module.exports = baseConfig; diff --git a/packages/cdk-assets/.gitignore b/packages/cdk-assets/.gitignore deleted file mode 100644 index d24092a6feda2..0000000000000 --- a/packages/cdk-assets/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -*.js -*.js.map -*.d.ts -!lib/init-templates/**/javascript/**/* -node_modules -dist - -# Generated by generate.sh -build-info.json - -.LAST_BUILD -.nyc_output -coverage -nyc.config.js -.LAST_PACKAGE -*.snk - -!test/integ/run-wrappers/dist -!test/integ/cli/**/* -assets.json -npm-shrinkwrap.json -!.eslintrc.js -!jest.config.js - -junit.xml - -# Ignore this symlink, we recreate it at test time -test/test-archive-follow/data/linked diff --git a/packages/cdk-assets/.npmignore b/packages/cdk-assets/.npmignore deleted file mode 100644 index 45b8808bdd7ac..0000000000000 --- a/packages/cdk-assets/.npmignore +++ /dev/null @@ -1,30 +0,0 @@ -# Don't include original .ts files when doing `npm pack` -*.ts -!*.template.ts -!*.d.ts -coverage -.nyc_output -*.tgz - -dist -.LAST_PACKAGE -.LAST_BUILD -*.snk - -!lib/init-templates/*/*/tsconfig.json -!test/integ/cli/**/*.js -!test/integ/run-wrappers/dist - -*.tsbuildinfo - -tsconfig.json - -# init templates include default tsconfig.json files which we need -!lib/init-templates/**/tsconfig.json -.eslintrc.js -jest.config.js - -# exclude cdk artifacts -**/cdk.out -junit.xml -test/ \ No newline at end of file diff --git a/packages/cdk-assets/LICENSE b/packages/cdk-assets/LICENSE deleted file mode 100644 index dcf28b52a83af..0000000000000 --- a/packages/cdk-assets/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-2024 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/cdk-assets/NOTICE b/packages/cdk-assets/NOTICE deleted file mode 100644 index c0b1f046c881a..0000000000000 --- a/packages/cdk-assets/NOTICE +++ /dev/null @@ -1,2 +0,0 @@ -AWS Cloud Development Kit (AWS CDK) -Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/cdk-assets/README.md b/packages/cdk-assets/README.md deleted file mode 100644 index 7c8bc78aca51b..0000000000000 --- a/packages/cdk-assets/README.md +++ /dev/null @@ -1,190 +0,0 @@ -# cdk-assets - - ---- - -![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge) - ---- - - - - -A tool for publishing CDK assets to AWS environments. - -## Overview - -`cdk-assets` requires an asset manifest file called `assets.json`, in a CDK -CloudAssembly (`cdk.out/assets.json`). It will take the assets listed in the -manifest, prepare them as required and upload them to the locations indicated in -the manifest. - -Currently the following asset types are supported: - -* Files and archives, uploaded to S3 -* Docker Images, uploaded to ECR -* Files, archives, and Docker images built by external utilities - -S3 buckets and ECR repositories to upload to are expected to exist already. - -We expect assets to be immutable, and we expect that immutability to be -reflected both in the asset ID and in the destination location. This reflects -itself in the following behaviors: - -* If the indicated asset already exists in the given destination location, it - will not be packaged and uploaded. -* If some locally cached artifact (depending on the asset type a file or an - image in the local Docker cache) already exists named after the asset's ID, it - will not be packaged, but will be uploaded directly to the destination - location. - -For assets build by external utilities, the contract is such that cdk-assets -expects the utility to manage dedupe detection as well as path/image tag generation. -This means that cdk-assets will call the external utility every time generation -is warranted, and it is up to the utility to a) determine whether to do a -full rebuild; and b) to return only one thing on stdout: the path to the file/archive -asset, or the name of the local Docker image. - -## Usage - -The `cdk-asset` tool can be used programmatically and via the CLI. Use -programmatic access if you need more control over authentication than the -default [`aws-sdk`](https://github.com/aws/aws-sdk-js) implementation allows. - -Command-line use looks like this: - -```console -$ cdk-assets /path/to/cdk.out [ASSET:DEST] [ASSET] [:DEST] [...] -``` - -Credentials will be taken from the `AWS_ACCESS_KEY...` environment variables -or the `default` profile (or another profile if `AWS_PROFILE` is set). - -A subset of the assets and destinations can be uploaded by specifying their -asset IDs or destination IDs. - -## Manifest Example - -An asset manifest looks like this: - -```json -{ - "version": "1.22.0", - "files": { - "7aac5b80b050e7e4e168f84feffa5893": { - "source": { - "path": "some_directory", - "packaging": "zip" - }, - "destinations": { - "us-east-1": { - "region": "us-east-1", - "assumeRoleArn": "arn:aws:iam::12345789012:role/my-account", - "bucketName": "MyBucket", - "objectKey": "7aac5b80b050e7e4e168f84feffa5893.zip" - } - } - }, - "3dfe2b80b050e7e4e168f84feff678d4": { - "source": { - "executable": ["myzip"] - }, - "destinations": { - "us-east-1": { - "region": "us-east-1", - "assumeRoleArn": "arn:aws:iam::12345789012:role/my-account", - "bucketName": "MySpecialBucket", - "objectKey": "3dfe2b80b050e7e4e168f84feff678d4.zip" - } - } - }, - }, - "dockerImages": { - "b48783c58a86f7b8c68a4591c4f9be31": { - "source": { - "directory": "dockerdir", - }, - "destinations": { - "us-east-1": { - "region": "us-east-1", - "assumeRoleArn": "arn:aws:iam::12345789012:role/my-account", - "repositoryName": "MyRepository", - "imageTag": "b48783c58a86f7b8c68a4591c4f9be31", - "imageUri": "123456789012.dkr.ecr.us-east-1.amazonaws.com/MyRepository:1234567891b48783c58a86f7b8c68a4591c4f9be31", - } - } - }, - "d92753c58a86f7b8c68a4591c4f9cf28": { - "source": { - "executable": ["mytool", "package", "dockerdir"], - }, - "destinations": { - "us-east-1": { - "region": "us-east-1", - "assumeRoleArn": "arn:aws:iam::12345789012:role/my-account", - "repositoryName": "MyRepository2", - "imageTag": "d92753c58a86f7b8c68a4591c4f9cf28", - "imageUri": "123456789987.dkr.ecr.us-east-1.amazonaws.com/MyRepository2:1234567891b48783c58a86f7b8c68a4591c4f9be31", - } - } - } - } -} -``` - -### Placeholders - -The `destination` block of an asset manifest may contain the following region -and account placeholders: - -* `${AWS::Region}` -* `${AWS::AccountId}` - -These will be substituted with the region and account IDs currently configured -on the AWS SDK (through environment variables or `~/.aws/...` config files). - -* The `${AWS::AccountId}` placeholder will *not* be re-evaluated after - performing the `AssumeRole` call. -* If `${AWS::Region}` is used, it will principally be replaced with the value - in the `region` key. If the default region is intended, leave the `region` - key out of the manifest at all. - -## Docker image credentials - -For Docker image asset publishing, `cdk-assets` will `docker login` with -credentials from ECR GetAuthorizationToken prior to building and publishing, so -that the Dockerfile can reference images in the account's ECR repo. - -`cdk-assets` can also be configured to read credentials from both ECR and -SecretsManager prior to build by creating a credential configuration at -'~/.cdk/cdk-docker-creds.json' (override this location by setting the -CDK_DOCKER_CREDS_FILE environment variable). The credentials file has the -following format: - -```json -{ - "version": "1.0", - "domainCredentials": { - "domain1.example.com": { - "secretsManagerSecretId": "mySecret", // Can be the secret ID or full ARN - "roleArn": "arn:aws:iam::0123456789012:role/my-role" // (Optional) role with permissions to the secret - }, - "domain2.example.com": { - "ecrRepository": true, - "roleArn": "arn:aws:iam::0123456789012:role/my-role" // (Optional) role with permissions to the repo - } - } -} -``` - -If the credentials file is present, `docker` will be configured to use the -`docker-credential-cdk-assets` credential helper for each of the domains listed -in the file. This helper will assume the role provided (if present), and then fetch -the login credentials from either SecretsManager or ECR. - -## Using Drop-in Docker Replacements - -By default, the AWS CDK will build and publish Docker image assets using the -`docker` command. However, by specifying the `CDK_DOCKER` environment variable, -you can override the command that will be used to build and publish your -assets. diff --git a/packages/cdk-assets/bin/cdk-assets b/packages/cdk-assets/bin/cdk-assets deleted file mode 100755 index 09c08dd446846..0000000000000 --- a/packages/cdk-assets/bin/cdk-assets +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node -require('./cdk-assets.js'); \ No newline at end of file diff --git a/packages/cdk-assets/bin/cdk-assets.ts b/packages/cdk-assets/bin/cdk-assets.ts deleted file mode 100644 index 4547051334449..0000000000000 --- a/packages/cdk-assets/bin/cdk-assets.ts +++ /dev/null @@ -1,67 +0,0 @@ -import * as yargs from 'yargs'; -import { list } from './list'; -import { setLogThreshold, VERSION } from './logging'; -import { publish } from './publish'; -import { AssetManifest } from '../lib'; - -async function main() { - const argv = yargs - .usage('$0 [args]') - .option('verbose', { - alias: 'v', - type: 'boolean', - desc: 'Increase logging verbosity', - count: true, - default: 0, - }) - .option('path', { - alias: 'p', - type: 'string', - desc: 'The path (file or directory) to load the assets from. If a directory, ' + - `the file '${AssetManifest.DEFAULT_FILENAME}' will be loaded from it.`, - default: '.', - requiresArg: true, - }) - .command('ls', 'List assets from the given manifest', command => command - , wrapHandler(async args => { - await list(args); - })) - .command('publish [ASSET..]', 'Publish assets in the given manifest', command => command - .option('profile', { type: 'string', describe: 'Profile to use from AWS Credentials file' }) - .positional('ASSET', { type: 'string', array: true, describe: 'Assets to publish (format: "ASSET[:DEST]"), default all' }) - , wrapHandler(async args => { - await publish({ - path: args.path, - assets: args.ASSET, - profile: args.profile, - }); - })) - .demandCommand() - .help() - .strict() // Error on wrong command - .version(VERSION) - .showHelpOnFail(false) - .argv; - - // Evaluating .argv triggers the parsing but the command gets implicitly executed, - // so we don't need the output. - Array.isArray(argv); -} - -/** - * Wrap a command's handler with standard pre- and post-work - */ -function wrapHandler(handler: (x: A) => Promise) { - return async (argv: A) => { - if (argv.verbose) { - setLogThreshold('verbose'); - } - await handler(argv); - }; -} - -main().catch(e => { - // eslint-disable-next-line no-console - console.error(e.stack); - process.exitCode = 1; -}); diff --git a/packages/cdk-assets/bin/docker-credential-cdk-assets b/packages/cdk-assets/bin/docker-credential-cdk-assets deleted file mode 100755 index 3829057860102..0000000000000 --- a/packages/cdk-assets/bin/docker-credential-cdk-assets +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node -require('./docker-credential-cdk-assets.js'); diff --git a/packages/cdk-assets/bin/docker-credential-cdk-assets.ts b/packages/cdk-assets/bin/docker-credential-cdk-assets.ts deleted file mode 100644 index 6dccb5521cf55..0000000000000 --- a/packages/cdk-assets/bin/docker-credential-cdk-assets.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Docker Credential Helper to retrieve credentials based on an external configuration file. - * Supports loading credentials from ECR repositories and from Secrets Manager, - * optionally via an assumed role. - * - * The only operation currently supported by this credential helper at this time is the `get` - * command, which receives a domain name as input on stdin and returns a Username/Secret in - * JSON format on stdout. - * - * IMPORTANT - The credential helper must not output anything else besides the final credentials - * in any success case; doing so breaks docker's parsing of the output and causes the login to fail. - */ - -import * as fs from 'fs'; -import { DefaultAwsClient } from '../lib'; - -import { cdkCredentialsConfig, cdkCredentialsConfigFile, fetchDockerLoginCredentials } from '../lib/private/docker-credentials'; - -async function main() { - // Expected invocation is [node, docker-credential-cdk-assets, get] with input fed via STDIN - // For other valid docker commands (store, list, erase), we no-op. - if (process.argv.length !== 3 || process.argv[2] !== 'get') { - process.exit(0); - } - - const config = cdkCredentialsConfig(); - if (!config) { - throw new Error(`unable to find CDK Docker credentials at: ${cdkCredentialsConfigFile()}`); - } - - // Read the domain to fetch from stdin - let endpoint = fs.readFileSync(0, { encoding: 'utf-8' }).trim(); - const credentials = await fetchDockerLoginCredentials(new DefaultAwsClient(), config, endpoint); - // Write the credentials back to stdout - fs.writeFileSync(1, JSON.stringify(credentials)); -} - -main().catch(e => { - // eslint-disable-next-line no-console - console.error(e.stack); - process.exitCode = 1; -}); diff --git a/packages/cdk-assets/bin/list.ts b/packages/cdk-assets/bin/list.ts deleted file mode 100644 index e93358cd729fd..0000000000000 --- a/packages/cdk-assets/bin/list.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { AssetManifest } from '../lib'; - -export async function list(args: { - path: string; -}) { - const manifest = AssetManifest.fromPath(args.path); - // eslint-disable-next-line no-console - console.log(manifest.list().join('\n')); -} \ No newline at end of file diff --git a/packages/cdk-assets/bin/logging.ts b/packages/cdk-assets/bin/logging.ts deleted file mode 100644 index ead34deeaa70c..0000000000000 --- a/packages/cdk-assets/bin/logging.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; - -export type LogLevel = 'verbose' | 'info' | 'error'; -let logThreshold: LogLevel = 'info'; - -export const VERSION = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), { encoding: 'utf-8' })).version; - -const LOG_LEVELS: Record = { - verbose: 1, - info: 2, - error: 3, -}; - -export function setLogThreshold(threshold: LogLevel) { - logThreshold = threshold; -} - -export function log(level: LogLevel, message: string) { - if (LOG_LEVELS[level] >= LOG_LEVELS[logThreshold]) { - // eslint-disable-next-line no-console - console.error(`${level.padEnd(7, ' ')}: ${message}`); - } -} \ No newline at end of file diff --git a/packages/cdk-assets/bin/publish.ts b/packages/cdk-assets/bin/publish.ts deleted file mode 100644 index 87ead6eac14ae..0000000000000 --- a/packages/cdk-assets/bin/publish.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { log, LogLevel } from './logging'; -import { - AssetManifest, AssetPublishing, DefaultAwsClient, DestinationPattern, EventType, - IPublishProgress, IPublishProgressListener, -} from '../lib'; - -export async function publish(args: { - path: string; - assets?: string[]; - profile?: string; -}) { - - let manifest = AssetManifest.fromPath(args.path); - log('verbose', `Loaded manifest from ${args.path}: ${manifest.entries.length} assets found`); - - if (args.assets && args.assets.length > 0) { - const selection = args.assets.map(a => DestinationPattern.parse(a)); - manifest = manifest.select(selection); - log('verbose', `Applied selection: ${manifest.entries.length} assets selected.`); - } - - const pub = new AssetPublishing(manifest, { - aws: new DefaultAwsClient(args.profile), - progressListener: new ConsoleProgress(), - throwOnError: false, - }); - - await pub.publish(); - - if (pub.hasFailures) { - for (const failure of pub.failures) { - // eslint-disable-next-line no-console - console.error('Failure:', failure.error.stack); - } - - process.exitCode = 1; - } -} - -const EVENT_TO_LEVEL: Record = { - build: 'verbose', - cached: 'verbose', - check: 'verbose', - debug: 'verbose', - fail: 'error', - found: 'verbose', - start: 'info', - success: 'info', - upload: 'verbose', -}; - -class ConsoleProgress implements IPublishProgressListener { - public onPublishEvent(type: EventType, event: IPublishProgress): void { - log(EVENT_TO_LEVEL[type], `[${event.percentComplete}%] ${type}: ${event.message}`); - } -} diff --git a/packages/cdk-assets/jest.config.js b/packages/cdk-assets/jest.config.js deleted file mode 100644 index 4147a830a714b..0000000000000 --- a/packages/cdk-assets/jest.config.js +++ /dev/null @@ -1,11 +0,0 @@ -const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config'); -module.exports = { - ...baseConfig, - coverageThreshold: { - global: { - ...baseConfig.coverageThreshold.global, - statements: 75, - branches: 60, - }, - }, -}; diff --git a/packages/cdk-assets/lib/asset-manifest.ts b/packages/cdk-assets/lib/asset-manifest.ts deleted file mode 100644 index 0cb92396ff424..0000000000000 --- a/packages/cdk-assets/lib/asset-manifest.ts +++ /dev/null @@ -1,313 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import { - AssetManifest as AssetManifestSchema, DockerImageDestination, DockerImageSource, - FileDestination, FileSource, Manifest, -} from '@aws-cdk/cloud-assembly-schema'; - -/** - * A manifest of assets - */ -export class AssetManifest { - /** - * The default name of the asset manifest in a cdk.out directory - */ - public static readonly DEFAULT_FILENAME = 'assets.json'; - - /** - * Load an asset manifest from the given file - */ - public static fromFile(fileName: string) { - try { - const obj = Manifest.loadAssetManifest(fileName); - return new AssetManifest(path.dirname(fileName), obj); - } catch (e: any) { - throw new Error(`Canot read asset manifest '${fileName}': ${e.message}`); - } - } - - /** - * Load an asset manifest from the given file or directory - * - * If the argument given is a directoy, the default asset file name will be used. - */ - public static fromPath(filePath: string) { - let st; - try { - st = fs.statSync(filePath); - } catch (e: any) { - throw new Error(`Cannot read asset manifest at '${filePath}': ${e.message}`); - } - if (st.isDirectory()) { - return AssetManifest.fromFile(path.join(filePath, AssetManifest.DEFAULT_FILENAME)); - } - return AssetManifest.fromFile(filePath); - } - - /** - * The directory where the manifest was found - */ - public readonly directory: string; - - constructor(directory: string, private readonly manifest: AssetManifestSchema) { - this.directory = directory; - } - - /** - * Select a subset of assets and destinations from this manifest. - * - * Only assets with at least 1 selected destination are retained. - * - * If selection is not given, everything is returned. - */ - public select(selection?: DestinationPattern[]): AssetManifest { - if (selection === undefined) { return this; } - - const ret: AssetManifestSchema & Required> - = { version: this.manifest.version, dockerImages: {}, files: {} }; - - for (const assetType of ASSET_TYPES) { - for (const [assetId, asset] of Object.entries(this.manifest[assetType] || {})) { - const filteredDestinations = filterDict( - asset.destinations, - (_, destId) => selection.some(sel => sel.matches(new DestinationIdentifier(assetId, destId)))); - - if (Object.keys(filteredDestinations).length > 0) { - ret[assetType][assetId] = { - ...asset, - destinations: filteredDestinations, - }; - } - } - } - - return new AssetManifest(this.directory, ret); - } - - /** - * Describe the asset manifest as a list of strings - */ - public list() { - return [ - ...describeAssets('file', this.manifest.files || {}), - ...describeAssets('docker-image', this.manifest.dockerImages || {}), - ]; - - function describeAssets(type: string, assets: Record }>) { - const ret = new Array(); - for (const [assetId, asset] of Object.entries(assets || {})) { - ret.push(`${assetId} ${type} ${JSON.stringify(asset.source)}`); - - const destStrings = Object.entries(asset.destinations).map(([destId, dest]) => ` ${assetId}:${destId} ${JSON.stringify(dest)}`); - ret.push(...prefixTreeChars(destStrings, ' ')); - } - return ret; - } - } - - /** - * List of assets per destination - * - * Returns one asset for every publishable destination. Multiple asset - * destinations may share the same asset source. - */ - public get entries(): IManifestEntry[] { - return [ - ...makeEntries(this.manifest.files || {}, FileManifestEntry), - ...makeEntries(this.manifest.dockerImages || {}, DockerImageManifestEntry), - ]; - } - - /** - * List of file assets, splat out to destinations - */ - public get files(): FileManifestEntry[] { - return makeEntries(this.manifest.files || {}, FileManifestEntry); - } -} - -function makeEntries( - assets: Record }>, - ctor: new (id: DestinationIdentifier, source: A, destination: B) => C): C[] { - - const ret = new Array(); - for (const [assetId, asset] of Object.entries(assets)) { - for (const [destId, destination] of Object.entries(asset.destinations)) { - ret.push(new ctor(new DestinationIdentifier(assetId, destId), asset.source, destination)); - } - } - return ret; -} - -type AssetType = 'files' | 'dockerImages'; - -const ASSET_TYPES: AssetType[] = ['files', 'dockerImages']; - -/** - * A single asset from an asset manifest' - */ -export interface IManifestEntry { - /** - * The identifier of the asset and its destination - */ - readonly id: DestinationIdentifier; - - /** - * The type of asset - */ - readonly type: string; - - /** - * Type-dependent source data - */ - readonly genericSource: unknown; - - /** - * Type-dependent destination data - */ - readonly genericDestination: unknown; -} - -/** - * A manifest entry for a file asset - */ -export class FileManifestEntry implements IManifestEntry { - public readonly genericSource: unknown; - public readonly genericDestination: unknown; - public readonly type = 'file'; - - constructor( - /** Identifier for this asset */ - public readonly id: DestinationIdentifier, - /** Source of the file asset */ - public readonly source: FileSource, - /** Destination for the file asset */ - public readonly destination: FileDestination, - ) { - this.genericSource = source; - this.genericDestination = destination; - } -} - -/** - * A manifest entry for a docker image asset - */ -export class DockerImageManifestEntry implements IManifestEntry { - public readonly genericSource: unknown; - public readonly genericDestination: unknown; - public readonly type = 'docker-image'; - - constructor( - /** Identifier for this asset */ - public readonly id: DestinationIdentifier, - /** Source of the file asset */ - public readonly source: DockerImageSource, - /** Destination for the file asset */ - public readonly destination: DockerImageDestination, - ) { - this.genericSource = source; - this.genericDestination = destination; - } -} - -/** - * Identify an asset destination in an asset manifest - * - * When stringified, this will be a combination of the source - * and destination IDs. - */ -export class DestinationIdentifier { - /** - * Identifies the asset, by source. - * - * The assetId will be the same between assets that represent - * the same physical file or image. - */ - public readonly assetId: string; - - /** - * Identifies the destination where this asset will be published - */ - public readonly destinationId: string; - - constructor(assetId: string, destinationId: string) { - this.assetId = assetId; - this.destinationId = destinationId; - } - - /** - * Return a string representation for this asset identifier - */ - public toString() { - return this.destinationId ? `${this.assetId}:${this.destinationId}` : this.assetId; - } -} - -function filterDict(xs: Record, pred: (x: A, key: string) => boolean): Record { - const ret: Record = {}; - for (const [key, value] of Object.entries(xs)) { - if (pred(value, key)) { - ret[key] = value; - } - } - return ret; -} - -/** - * A filter pattern for an destination identifier - */ -export class DestinationPattern { - /** - * Parse a ':'-separated string into an asset/destination identifier - */ - public static parse(s: string) { - if (!s) { throw new Error('Empty string is not a valid destination identifier'); } - const parts = s.split(':').map(x => x !== '*' ? x : undefined); - if (parts.length === 1) { return new DestinationPattern(parts[0]); } - if (parts.length === 2) { return new DestinationPattern(parts[0] || undefined, parts[1] || undefined); } - throw new Error(`Asset identifier must contain at most 2 ':'-separated parts, got '${s}'`); - } - - /** - * Identifies the asset, by source. - */ - public readonly assetId?: string; - - /** - * Identifies the destination where this asset will be published - */ - public readonly destinationId?: string; - - constructor(assetId?: string, destinationId?: string) { - this.assetId = assetId; - this.destinationId = destinationId; - } - - /** - * Whether or not this pattern matches the given identifier - */ - public matches(id: DestinationIdentifier) { - return (this.assetId === undefined || this.assetId === id.assetId) - && (this.destinationId === undefined || this.destinationId === id.destinationId); - } - - /** - * Return a string representation for this asset identifier - */ - public toString() { - return `${this.assetId ?? '*'}:${this.destinationId ?? '*'}`; - } -} - -/** - * Prefix box-drawing characters to make lines look like a hanging tree - */ -function prefixTreeChars(xs: string[], prefix = '') { - const ret = new Array(); - for (let i = 0; i < xs.length; i++) { - const isLast = i === xs.length - 1; - const boxChar = isLast ? '└' : '├'; - ret.push(`${prefix}${boxChar}${xs[i]}`); - } - return ret; -} diff --git a/packages/cdk-assets/lib/aws.ts b/packages/cdk-assets/lib/aws.ts deleted file mode 100644 index d78e29f24cc3e..0000000000000 --- a/packages/cdk-assets/lib/aws.ts +++ /dev/null @@ -1,163 +0,0 @@ -import * as os from 'os'; - -/** - * AWS SDK operations required by Asset Publishing - */ -export interface IAws { - discoverPartition(): Promise; - discoverDefaultRegion(): Promise; - discoverCurrentAccount(): Promise; - - discoverTargetAccount(options: ClientOptions): Promise; - s3Client(options: ClientOptions): Promise; - ecrClient(options: ClientOptions): Promise; - secretsManagerClient(options: ClientOptions): Promise; -} - -export interface ClientOptions { - region?: string; - assumeRoleArn?: string; - assumeRoleExternalId?: string; - quiet?: boolean; -} - -/** - * An AWS account - * - * An AWS account always exists in only one partition. Usually we don't care about - * the partition, but when we need to form ARNs we do. - */ -export interface Account { - /** - * The account number - */ - readonly accountId: string; - - /** - * The partition ('aws' or 'aws-cn' or otherwise) - */ - readonly partition: string; -} - -/** - * AWS client using the AWS SDK for JS with no special configuration - */ -export class DefaultAwsClient implements IAws { - private readonly AWS: typeof import('aws-sdk'); - private account?: Account; - - constructor(profile?: string) { - // Force AWS SDK to look in ~/.aws/credentials and potentially use the configured profile. - process.env.AWS_SDK_LOAD_CONFIG = '1'; - process.env.AWS_STS_REGIONAL_ENDPOINTS = 'regional'; - process.env.AWS_NODEJS_CONNECTION_REUSE_ENABLED = '1'; - if (profile) { - process.env.AWS_PROFILE = profile; - } - // Stop SDKv2 from displaying a warning for now. We are aware and will migrate at some point, - // our customer don't need to be bothered with this. - process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE = '1'; - - // We need to set the environment before we load this library for the first time. - // eslint-disable-next-line @typescript-eslint/no-require-imports - this.AWS = require('aws-sdk'); - } - - public async s3Client(options: ClientOptions) { - return new this.AWS.S3(await this.awsOptions(options)); - } - - public async ecrClient(options: ClientOptions) { - return new this.AWS.ECR(await this.awsOptions(options)); - } - - public async secretsManagerClient(options: ClientOptions) { - return new this.AWS.SecretsManager(await this.awsOptions(options)); - } - - public async discoverPartition(): Promise { - return (await this.discoverCurrentAccount()).partition; - } - - public async discoverDefaultRegion(): Promise { - return this.AWS.config.region || 'us-east-1'; - } - - public async discoverCurrentAccount(): Promise { - if (this.account === undefined) { - const sts = new this.AWS.STS(); - const response = await sts.getCallerIdentity().promise(); - if (!response.Account || !response.Arn) { - throw new Error(`Unrecognized response from STS: '${JSON.stringify(response)}'`); - } - this.account = { - accountId: response.Account!, - partition: response.Arn!.split(':')[1], - }; - } - - return this.account; - } - - public async discoverTargetAccount(options: ClientOptions): Promise { - const sts = new this.AWS.STS(await this.awsOptions(options)); - const response = await sts.getCallerIdentity().promise(); - if (!response.Account || !response.Arn) { - throw new Error(`Unrecognized response from STS: '${JSON.stringify(response)}'`); - } - return { - accountId: response.Account!, - partition: response.Arn!.split(':')[1], - }; - } - - private async awsOptions(options: ClientOptions) { - let credentials; - - if (options.assumeRoleArn) { - credentials = await this.assumeRole(options.region, options.assumeRoleArn, options.assumeRoleExternalId); - } - - return { - region: options.region, - customUserAgent: 'cdk-assets', - credentials, - }; - } - - /** - * Explicit manual AssumeRole call - * - * Necessary since I can't seem to get the built-in support for ChainableTemporaryCredentials to work. - * - * It needs an explicit configuration of `masterCredentials`, we need to put - * a `DefaultCredentialProverChain()` in there but that is not possible. - */ - private async assumeRole(region: string | undefined, roleArn: string, externalId?: string): Promise { - return new this.AWS.ChainableTemporaryCredentials({ - params: { - RoleArn: roleArn, - ExternalId: externalId, - RoleSessionName: `cdk-assets-${safeUsername()}`, - }, - stsConfig: { - region, - customUserAgent: 'cdk-assets', - }, - }); - } -} - -/** - * Return the username with characters invalid for a RoleSessionName removed - * - * @see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html#API_AssumeRole_RequestParameters - */ -function safeUsername() { - try { - return os.userInfo().username.replace(/[^\w+=,.@-]/g, '@'); - } catch { - return 'noname'; - } -} - diff --git a/packages/cdk-assets/lib/index.ts b/packages/cdk-assets/lib/index.ts deleted file mode 100644 index 26f81852f3601..0000000000000 --- a/packages/cdk-assets/lib/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './publishing'; -export * from './asset-manifest'; -export * from './aws'; -export * from './progress'; diff --git a/packages/cdk-assets/lib/private/archive.ts b/packages/cdk-assets/lib/private/archive.ts deleted file mode 100644 index 8e0d9a900b46e..0000000000000 --- a/packages/cdk-assets/lib/private/archive.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { createWriteStream, promises as fs } from 'fs'; -import * as path from 'path'; -import * as glob from 'glob'; - -// namespace object imports won't work in the bundle for function exports -// eslint-disable-next-line @typescript-eslint/no-require-imports -const archiver = require('archiver'); - -type Logger = (x: string) => void; - -export async function zipDirectory(directory: string, outputFile: string, logger: Logger): Promise { - // We write to a temporary file and rename at the last moment. This is so that if we are - // interrupted during this process, we don't leave a half-finished file in the target location. - const temporaryOutputFile = `${outputFile}.${randomString()}._tmp`; - await writeZipFile(directory, temporaryOutputFile); - await moveIntoPlace(temporaryOutputFile, outputFile, logger); -} - -function writeZipFile(directory: string, outputFile: string): Promise { - return new Promise(async (ok, fail) => { - // The below options are needed to support following symlinks when building zip files: - // - nodir: This will prevent symlinks themselves from being copied into the zip. - // - follow: This will follow symlinks and copy the files within. - const globOptions = { - dot: true, - nodir: true, - follow: true, - cwd: directory, - }; - const files = glob.sync('**', globOptions); // The output here is already sorted - - const output = createWriteStream(outputFile); - - const archive = archiver('zip'); - archive.on('warning', fail); - archive.on('error', fail); - - // archive has been finalized and the output file descriptor has closed, resolve promise - // this has to be done before calling `finalize` since the events may fire immediately after. - // see https://www.npmjs.com/package/archiver - output.once('close', ok); - - archive.pipe(output); - - // Append files serially to ensure file order - for (const file of files) { - const fullPath = path.resolve(directory, file); - const [data, stat] = await Promise.all([fs.readFile(fullPath), fs.stat(fullPath)]); - archive.append(data, { - name: file, - date: new Date('1980-01-01T00:00:00.000Z'), // reset dates to get the same hash for the same content - mode: stat.mode, - }); - } - - await archive.finalize(); - }); -} - -/** - * Rename the file to the target location, taking into account: - * - * - That we may see EPERM on Windows while an Antivirus scanner still has the - * file open, so retry a couple of times. - * - This same function may be called in parallel and be interrupted at any point. - */ -async function moveIntoPlace(source: string, target: string, logger: Logger) { - let delay = 100; - let attempts = 5; - while (true) { - try { - // 'rename' is guaranteed to overwrite an existing target, as long as it is a file (not a directory) - await fs.rename(source, target); - return; - } catch (e: any) { - if (e.code !== 'EPERM' || attempts-- <= 0) { - throw e; - } - logger(e.message); - await sleep(Math.floor(Math.random() * delay)); - delay *= 2; - } - } -} - -function sleep(ms: number) { - return new Promise(ok => setTimeout(ok, ms)); -} - -function randomString() { - return Math.random().toString(36).replace(/[^a-z0-9]+/g, ''); -} diff --git a/packages/cdk-assets/lib/private/asset-handler.ts b/packages/cdk-assets/lib/private/asset-handler.ts deleted file mode 100644 index baafb3cd0317e..0000000000000 --- a/packages/cdk-assets/lib/private/asset-handler.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { DockerFactory } from './docker'; -import { IAws } from '../aws'; -import { EventType } from '../progress'; - -/** - * Handler for asset building and publishing. - */ -export interface IAssetHandler { - /** - * Build the asset. - */ - build(): Promise; - - /** - * Publish the asset. - */ - publish(): Promise; - - /** - * Return whether the asset already exists - */ - isPublished(): Promise; -} - -export interface IHandlerHost { - readonly aws: IAws; - readonly aborted: boolean; - readonly dockerFactory: DockerFactory; - - emitMessage(type: EventType, m: string): void; -} - -export interface IHandlerOptions { - /** - * Suppress all output - */ - readonly quiet?: boolean; -} diff --git a/packages/cdk-assets/lib/private/docker-credentials.ts b/packages/cdk-assets/lib/private/docker-credentials.ts deleted file mode 100644 index c46add8caeefb..0000000000000 --- a/packages/cdk-assets/lib/private/docker-credentials.ts +++ /dev/null @@ -1,93 +0,0 @@ -import * as fs from 'fs'; -import * as os from 'os'; -import * as path from 'path'; -import { Logger } from './shell'; -import { IAws } from '../aws'; - -export interface DockerCredentials { - readonly Username: string; - readonly Secret: string; -} - -export interface DockerCredentialsConfig { - readonly version: string; - readonly domainCredentials: Record; -} - -export interface DockerDomainCredentialSource { - readonly secretsManagerSecretId?: string; - readonly secretsUsernameField?: string; - readonly secretsPasswordField?: string; - readonly ecrRepository?: boolean; - readonly assumeRoleArn?: string; -} - -/** Returns the presumed location of the CDK Docker credentials config file */ -export function cdkCredentialsConfigFile(): string { - return process.env.CDK_DOCKER_CREDS_FILE ?? path.join((os.userInfo().homedir ?? os.homedir()).trim() || '/', '.cdk', 'cdk-docker-creds.json'); -} - -let _cdkCredentials: DockerCredentialsConfig | undefined; -/** Loads and parses the CDK Docker credentials configuration, if it exists. */ -export function cdkCredentialsConfig(): DockerCredentialsConfig | undefined { - if (!_cdkCredentials) { - try { - _cdkCredentials = JSON.parse(fs.readFileSync(cdkCredentialsConfigFile(), { encoding: 'utf-8' })) as DockerCredentialsConfig; - } catch { } - } - return _cdkCredentials; -} - -/** Fetches login credentials from the configured source (e.g., SecretsManager, ECR) */ -export async function fetchDockerLoginCredentials(aws: IAws, config: DockerCredentialsConfig, endpoint: string) { - // Paranoid handling to ensure new URL() doesn't throw if the schema is missing - // For official docker registry, docker will pass https://index.docker.io/v1/ - endpoint = endpoint.includes('://') ? endpoint : `https://${endpoint}`; - const domain = new URL(endpoint).hostname; - - if (!Object.keys(config.domainCredentials).includes(domain) && !Object.keys(config.domainCredentials).includes(endpoint)) { - throw new Error(`unknown domain ${domain}`); - } - - let domainConfig = config.domainCredentials[domain] ?? config.domainCredentials[endpoint]; - - if (domainConfig.secretsManagerSecretId) { - const sm = await aws.secretsManagerClient({ assumeRoleArn: domainConfig.assumeRoleArn }); - const secretValue = await sm.getSecretValue({ SecretId: domainConfig.secretsManagerSecretId }).promise(); - if (!secretValue.SecretString) { throw new Error(`unable to fetch SecretString from secret: ${domainConfig.secretsManagerSecretId}`); }; - - const secret = JSON.parse(secretValue.SecretString); - - const usernameField = domainConfig.secretsUsernameField ?? 'username'; - const secretField = domainConfig.secretsPasswordField ?? 'secret'; - if (!secret[usernameField] || !secret[secretField]) { - throw new Error(`malformed secret string ("${usernameField}" or "${secretField}" field missing)`); - } - - return { Username: secret[usernameField], Secret: secret[secretField] }; - } else if (domainConfig.ecrRepository) { - const ecr = await aws.ecrClient({ assumeRoleArn: domainConfig.assumeRoleArn }); - const ecrAuthData = await obtainEcrCredentials(ecr); - - return { Username: ecrAuthData.username, Secret: ecrAuthData.password }; - } else { - throw new Error('unknown credential type: no secret ID or ECR repo'); - } -} - -export async function obtainEcrCredentials(ecr: AWS.ECR, logger?: Logger) { - if (logger) { logger('Fetching ECR authorization token'); } - const authData = (await ecr.getAuthorizationToken({ }).promise()).authorizationData || []; - if (authData.length === 0) { - throw new Error('No authorization data received from ECR'); - } - const token = Buffer.from(authData[0].authorizationToken!, 'base64').toString('ascii'); - const [username, password] = token.split(':'); - if (!username || !password) { throw new Error('unexpected ECR authData format'); } - - return { - username, - password, - endpoint: authData[0].proxyEndpoint!, - }; -} diff --git a/packages/cdk-assets/lib/private/docker.ts b/packages/cdk-assets/lib/private/docker.ts deleted file mode 100644 index f321bac3c11b6..0000000000000 --- a/packages/cdk-assets/lib/private/docker.ts +++ /dev/null @@ -1,279 +0,0 @@ -import * as fs from 'fs'; -import * as os from 'os'; -import * as path from 'path'; -import { cdkCredentialsConfig, obtainEcrCredentials } from './docker-credentials'; -import { Logger, shell, ShellOptions, ProcessFailedError } from './shell'; -import { createCriticalSection } from './util'; - -interface BuildOptions { - readonly directory: string; - - /** - * Tag the image with a given repoName:tag combination - */ - readonly tag: string; - readonly target?: string; - readonly file?: string; - readonly buildArgs?: Record; - readonly buildSecrets?: Record; - readonly buildSsh?: string; - readonly networkMode?: string; - readonly platform?: string; - readonly outputs?: string[]; - readonly cacheFrom?: DockerCacheOption[]; - readonly cacheTo?: DockerCacheOption; - readonly cacheDisabled?: boolean; - readonly quiet?: boolean; -} - -interface PushOptions { - readonly tag: string; - readonly quiet?: boolean; -} - -export interface DockerCredentialsConfig { - readonly version: string; - readonly domainCredentials: Record; -} - -export interface DockerDomainCredentials { - readonly secretsManagerSecretId?: string; - readonly ecrRepository?: string; -} - -enum InspectImageErrorCode { - Docker = 1, - Podman = 125, -} - -export interface DockerCacheOption { - readonly type: string; - readonly params?: { [key: string]: string }; -} - -export class Docker { - - private configDir: string | undefined = undefined; - - constructor(private readonly logger?: Logger) { - } - - /** - * Whether an image with the given tag exists - */ - public async exists(tag: string) { - try { - await this.execute(['inspect', tag], { quiet: true }); - return true; - } catch (e: any) { - const error: ProcessFailedError = e; - - /** - * The only error we expect to be thrown will have this property and value. - * If it doesn't, it's unrecognized so re-throw it. - */ - if (error.code !== 'PROCESS_FAILED') { - throw error; - } - - /** - * If we know the shell command above returned an error, check to see - * if the exit code is one we know to actually mean that the image doesn't - * exist. - */ - switch (error.exitCode) { - case InspectImageErrorCode.Docker: - case InspectImageErrorCode.Podman: - // Docker and Podman will return this exit code when an image doesn't exist, return false - // context: https://github.com/aws/aws-cdk/issues/16209 - return false; - default: - // This is an error but it's not an exit code we recognize, throw. - throw error; - } - } - } - - public async build(options: BuildOptions) { - const buildCommand = [ - 'build', - ...flatten(Object.entries(options.buildArgs || {}).map(([k, v]) => ['--build-arg', `${k}=${v}`])), - ...flatten(Object.entries(options.buildSecrets || {}).map(([k, v]) => ['--secret', `id=${k},${v}`])), - ...options.buildSsh ? ['--ssh', options.buildSsh] : [], - '--tag', options.tag, - ...options.target ? ['--target', options.target] : [], - ...options.file ? ['--file', options.file] : [], - ...options.networkMode ? ['--network', options.networkMode] : [], - ...options.platform ? ['--platform', options.platform] : [], - ...options.outputs ? options.outputs.map(output => [`--output=${output}`]) : [], - ...options.cacheFrom ? [...options.cacheFrom.map(cacheFrom => ['--cache-from', this.cacheOptionToFlag(cacheFrom)]).flat()] : [], - ...options.cacheTo ? ['--cache-to', this.cacheOptionToFlag(options.cacheTo)] : [], - ...options.cacheDisabled ? ['--no-cache'] : [], - '.', - ]; - await this.execute(buildCommand, { - cwd: options.directory, - quiet: options.quiet, - }); - } - - /** - * Get credentials from ECR and run docker login - */ - public async login(ecr: AWS.ECR) { - const credentials = await obtainEcrCredentials(ecr); - - // Use --password-stdin otherwise docker will complain. Loudly. - await this.execute(['login', - '--username', credentials.username, - '--password-stdin', - credentials.endpoint], { - input: credentials.password, - - // Need to quiet otherwise Docker will complain - // 'WARNING! Your password will be stored unencrypted' - // doesn't really matter since it's a token. - quiet: true, - }); - } - - public async tag(sourceTag: string, targetTag: string) { - await this.execute(['tag', sourceTag, targetTag]); - } - - public async push(options: PushOptions) { - await this.execute(['push', options.tag], { quiet: options.quiet }); - } - - /** - * If a CDK Docker Credentials file exists, creates a new Docker config directory. - * Sets up `docker-credential-cdk-assets` to be the credential helper for each domain in the CDK config. - * All future commands (e.g., `build`, `push`) will use this config. - * - * See https://docs.docker.com/engine/reference/commandline/login/#credential-helpers for more details on cred helpers. - * - * @returns true if CDK config was found and configured, false otherwise - */ - public configureCdkCredentials(): boolean { - const config = cdkCredentialsConfig(); - if (!config) { return false; } - - this.configDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdkDockerConfig')); - - const domains = Object.keys(config.domainCredentials); - const credHelpers = domains.reduce((map: Record, domain) => { - map[domain] = 'cdk-assets'; // Use docker-credential-cdk-assets for this domain - return map; - }, {}); - fs.writeFileSync(path.join(this.configDir, 'config.json'), JSON.stringify({ credHelpers }), { encoding: 'utf-8' }); - - return true; - } - - /** - * Removes any configured Docker config directory. - * All future commands (e.g., `build`, `push`) will use the default config. - * - * This is useful after calling `configureCdkCredentials` to reset to default credentials. - */ - public resetAuthPlugins() { - this.configDir = undefined; - } - - private async execute(args: string[], options: ShellOptions = {}) { - const configArgs = this.configDir ? ['--config', this.configDir] : []; - - const pathToCdkAssets = path.resolve(__dirname, '..', '..', 'bin'); - try { - await shell([getDockerCmd(), ...configArgs, ...args], { - logger: this.logger, - ...options, - env: { - ...process.env, - ...options.env, - PATH: `${pathToCdkAssets}${path.delimiter}${options.env?.PATH ?? process.env.PATH}`, - }, - }); - } catch (e: any) { - if (e.code === 'ENOENT') { - throw new Error('Unable to execute \'docker\' in order to build a container asset. Please install \'docker\' and try again.'); - } - throw e; - } - } - - private cacheOptionToFlag(option: DockerCacheOption): string { - let flag = `type=${option.type}`; - if (option.params) { - flag += ',' + Object.entries(option.params).map(([k, v]) => `${k}=${v}`).join(','); - } - return flag; - } -} - -export interface DockerFactoryOptions { - readonly repoUri: string; - readonly ecr: AWS.ECR; - readonly logger: (m: string) => void; -} - -/** - * Helps get appropriately configured Docker instances during the container - * image publishing process. - */ -export class DockerFactory { - private enterLoggedInDestinationsCriticalSection = createCriticalSection(); - private loggedInDestinations = new Set(); - - /** - * Gets a Docker instance for building images. - */ - public async forBuild(options: DockerFactoryOptions): Promise { - const docker = new Docker(options.logger); - - // Default behavior is to login before build so that the Dockerfile can reference images in the ECR repo - // However, if we're in a pipelines environment (for example), - // we may have alternative credentials to the default ones to use for the build itself. - // If the special config file is present, delay the login to the default credentials until the push. - // If the config file is present, we will configure and use those credentials for the build. - let cdkDockerCredentialsConfigured = docker.configureCdkCredentials(); - if (!cdkDockerCredentialsConfigured) { - await this.loginOncePerDestination(docker, options); - } - - return docker; - } - - /** - * Gets a Docker instance for pushing images to ECR. - */ - public async forEcrPush(options: DockerFactoryOptions) { - const docker = new Docker(options.logger); - await this.loginOncePerDestination(docker, options); - return docker; - } - - private async loginOncePerDestination(docker: Docker, options: DockerFactoryOptions) { - // Changes: 012345678910.dkr.ecr.us-west-2.amazonaws.com/tagging-test - // To this: 012345678910.dkr.ecr.us-west-2.amazonaws.com - const repositoryDomain = options.repoUri.split('/')[0]; - - // Ensure one-at-a-time access to loggedInDestinations. - await this.enterLoggedInDestinationsCriticalSection(async () => { - if (this.loggedInDestinations.has(repositoryDomain)) { - return; - } - - await docker.login(options.ecr); - this.loggedInDestinations.add(repositoryDomain); - }); - } -} - -function getDockerCmd(): string { - return process.env.CDK_DOCKER ?? 'docker'; -} - -function flatten(x: string[][]) { - return Array.prototype.concat([], ...x); -} diff --git a/packages/cdk-assets/lib/private/fs-extra.ts b/packages/cdk-assets/lib/private/fs-extra.ts deleted file mode 100644 index ac865789eb269..0000000000000 --- a/packages/cdk-assets/lib/private/fs-extra.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; - -const pfs = fs.promises; - -export async function pathExists(pathName: string) { - try { - await pfs.stat(pathName); - return true; - } catch (e: any) { - if (e.code !== 'ENOENT') { throw e; } - return false; - } -} - -export function emptyDirSync(dir: string) { - fs.readdirSync(dir, { withFileTypes: true }).forEach(dirent => { - const fullPath = path.join(dir, dirent.name); - if (dirent.isDirectory()) { - emptyDirSync(fullPath); - fs.rmdirSync(fullPath); - } else { - fs.unlinkSync(fullPath); - } - }); -} - -export function rmRfSync(dir: string) { - emptyDirSync(dir); - fs.rmdirSync(dir); -} diff --git a/packages/cdk-assets/lib/private/handlers/container-images.ts b/packages/cdk-assets/lib/private/handlers/container-images.ts deleted file mode 100644 index 8764b1e9c41b3..0000000000000 --- a/packages/cdk-assets/lib/private/handlers/container-images.ts +++ /dev/null @@ -1,238 +0,0 @@ -import * as path from 'path'; -import { DockerImageDestination } from '@aws-cdk/cloud-assembly-schema'; -import type * as AWS from 'aws-sdk'; -import { DockerImageManifestEntry } from '../../asset-manifest'; -import { EventType } from '../../progress'; -import { IAssetHandler, IHandlerHost, IHandlerOptions } from '../asset-handler'; -import { Docker } from '../docker'; -import { replaceAwsPlaceholders } from '../placeholders'; -import { shell } from '../shell'; - -interface ContainerImageAssetHandlerInit { - readonly ecr: AWS.ECR; - readonly repoUri: string; - readonly imageUri: string; - readonly destinationAlreadyExists: boolean; -} - -export class ContainerImageAssetHandler implements IAssetHandler { - private init?: ContainerImageAssetHandlerInit; - - constructor( - private readonly workDir: string, - private readonly asset: DockerImageManifestEntry, - private readonly host: IHandlerHost, - private readonly options: IHandlerOptions) { - } - - public async build(): Promise { - const initOnce = await this.initOnce(); - - if (initOnce.destinationAlreadyExists) { return; } - if (this.host.aborted) { return; } - - const dockerForBuilding = await this.host.dockerFactory.forBuild({ - repoUri: initOnce.repoUri, - logger: (m: string) => this.host.emitMessage(EventType.DEBUG, m), - ecr: initOnce.ecr, - }); - - const builder = new ContainerImageBuilder(dockerForBuilding, this.workDir, this.asset, this.host, { - quiet: this.options.quiet, - }); - const localTagName = await builder.build(); - - if (localTagName === undefined || this.host.aborted) { return; } - if (this.host.aborted) { return; } - - await dockerForBuilding.tag(localTagName, initOnce.imageUri); - } - - public async isPublished(): Promise { - try { - const initOnce = await this.initOnce({ quiet: true }); - return initOnce.destinationAlreadyExists; - } catch (e: any) { - this.host.emitMessage(EventType.DEBUG, `${e.message}`); - } - return false; - } - - public async publish(): Promise { - const initOnce = await this.initOnce(); - - if (initOnce.destinationAlreadyExists) { return; } - if (this.host.aborted) { return; } - - const dockerForPushing = await this.host.dockerFactory.forEcrPush({ - repoUri: initOnce.repoUri, - logger: (m: string) => this.host.emitMessage(EventType.DEBUG, m), - ecr: initOnce.ecr, - }); - - if (this.host.aborted) { return; } - - this.host.emitMessage(EventType.UPLOAD, `Push ${initOnce.imageUri}`); - await dockerForPushing.push({ tag: initOnce.imageUri, quiet: this.options.quiet }); - } - - private async initOnce(options: { quiet?: boolean } = {}): Promise { - if (this.init) { - return this.init; - } - - const destination = await replaceAwsPlaceholders(this.asset.destination, this.host.aws); - const ecr = await this.host.aws.ecrClient({ - ...destination, - quiet: options.quiet, - }); - const account = async () => (await this.host.aws.discoverCurrentAccount())?.accountId; - - const repoUri = await repositoryUri(ecr, destination.repositoryName); - if (!repoUri) { - throw new Error(`No ECR repository named '${destination.repositoryName}' in account ${await account()}. Is this account bootstrapped?`); - } - - const imageUri = `${repoUri}:${destination.imageTag}`; - - this.init = { - imageUri, - ecr, - repoUri, - destinationAlreadyExists: await this.destinationAlreadyExists(ecr, destination, imageUri), - }; - - return this.init; - } - - /** - * Check whether the image already exists in the ECR repo - * - * Use the fields from the destination to do the actual check. The imageUri - * should correspond to that, but is only used to print Docker image location - * for user benefit (the format is slightly different). - */ - private async destinationAlreadyExists(ecr: AWS.ECR, destination: DockerImageDestination, imageUri: string): Promise { - this.host.emitMessage(EventType.CHECK, `Check ${imageUri}`); - if (await imageExists(ecr, destination.repositoryName, destination.imageTag)) { - this.host.emitMessage(EventType.FOUND, `Found ${imageUri}`); - return true; - } - - return false; - } -} - -interface ContainerImageBuilderOptions { - readonly quiet?: boolean; -} - -class ContainerImageBuilder { - constructor( - private readonly docker: Docker, - private readonly workDir: string, - private readonly asset: DockerImageManifestEntry, - private readonly host: IHandlerHost, - private readonly options: ContainerImageBuilderOptions) { - } - - async build(): Promise { - return this.asset.source.executable - ? this.buildExternalAsset(this.asset.source.executable) - : this.buildDirectoryAsset(); - } - - /** - * Build a (local) Docker asset from a directory with a Dockerfile - * - * Tags under a deterministic, unique, local identifier wich will skip - * the build if it already exists. - */ - private async buildDirectoryAsset(): Promise { - const localTagName = `cdkasset-${this.asset.id.assetId.toLowerCase()}`; - - if (!(await this.isImageCached(localTagName))) { - if (this.host.aborted) { return undefined; } - - await this.buildImage(localTagName); - } - - return localTagName; - } - - /** - * Build a (local) Docker asset by running an external command - * - * External command is responsible for deduplicating the build if possible, - * and is expected to return the generated image identifier on stdout. - */ - private async buildExternalAsset(executable: string[], cwd?: string): Promise { - const assetPath = cwd ?? this.workDir; - - this.host.emitMessage(EventType.BUILD, `Building Docker image using command '${executable}'`); - if (this.host.aborted) { return undefined; } - - return (await shell(executable, { cwd: assetPath, quiet: true })).trim(); - } - - private async buildImage(localTagName: string): Promise { - const source = this.asset.source; - if (!source.directory) { - throw new Error(`'directory' is expected in the DockerImage asset source, got: ${JSON.stringify(source)}`); - } - - const fullPath = path.resolve(this.workDir, source.directory); - this.host.emitMessage(EventType.BUILD, `Building Docker image at ${fullPath}`); - - await this.docker.build({ - directory: fullPath, - tag: localTagName, - buildArgs: source.dockerBuildArgs, - buildSecrets: source.dockerBuildSecrets, - buildSsh: source.dockerBuildSsh, - target: source.dockerBuildTarget, - file: source.dockerFile, - networkMode: source.networkMode, - platform: source.platform, - outputs: source.dockerOutputs, - cacheFrom: source.cacheFrom, - cacheTo: source.cacheTo, - cacheDisabled: source.cacheDisabled, - quiet: this.options.quiet, - }); - } - - private async isImageCached(localTagName: string): Promise { - if (await this.docker.exists(localTagName)) { - this.host.emitMessage(EventType.CACHED, `Cached ${localTagName}`); - return true; - } - - return false; - } -} - -async function imageExists(ecr: AWS.ECR, repositoryName: string, imageTag: string) { - try { - await ecr.describeImages({ repositoryName, imageIds: [{ imageTag }] }).promise(); - return true; - } catch (e: any) { - if (e.code !== 'ImageNotFoundException') { throw e; } - return false; - } -} - -/** - * Return the URI for the repository with the given name - * - * Returns undefined if the repository does not exist. - */ -async function repositoryUri(ecr: AWS.ECR, repositoryName: string): Promise { - try { - const response = await ecr.describeRepositories({ repositoryNames: [repositoryName] }).promise(); - return (response.repositories || [])[0]?.repositoryUri; - } catch (e: any) { - if (e.code !== 'RepositoryNotFoundException') { throw e; } - return undefined; - } -} diff --git a/packages/cdk-assets/lib/private/handlers/files.ts b/packages/cdk-assets/lib/private/handlers/files.ts deleted file mode 100644 index 12008fd220323..0000000000000 --- a/packages/cdk-assets/lib/private/handlers/files.ts +++ /dev/null @@ -1,292 +0,0 @@ -import { createReadStream, promises as fs } from 'fs'; -import * as path from 'path'; -import { FileAssetPackaging, FileSource } from '@aws-cdk/cloud-assembly-schema'; -import * as mime from 'mime'; -import { FileManifestEntry } from '../../asset-manifest'; -import { EventType } from '../../progress'; -import { zipDirectory } from '../archive'; -import { IAssetHandler, IHandlerHost } from '../asset-handler'; -import { pathExists } from '../fs-extra'; -import { replaceAwsPlaceholders } from '../placeholders'; -import { shell } from '../shell'; - -/** - * The size of an empty zip file is 22 bytes - * - * Ref: https://en.wikipedia.org/wiki/ZIP_(file_format) - */ -const EMPTY_ZIP_FILE_SIZE = 22; - -export class FileAssetHandler implements IAssetHandler { - private readonly fileCacheRoot: string; - - constructor( - private readonly workDir: string, - private readonly asset: FileManifestEntry, - private readonly host: IHandlerHost) { - this.fileCacheRoot = path.join(workDir, '.cache'); - } - - public async build(): Promise {} - - public async isPublished(): Promise { - const destination = await replaceAwsPlaceholders(this.asset.destination, this.host.aws); - const s3Url = `s3://${destination.bucketName}/${destination.objectKey}`; - try { - const s3 = await this.host.aws.s3Client({ - ...destination, - quiet: true, - }); - this.host.emitMessage(EventType.CHECK, `Check ${s3Url}`); - - if (await objectExists(s3, destination.bucketName, destination.objectKey)) { - this.host.emitMessage(EventType.FOUND, `Found ${s3Url}`); - return true; - } - } catch (e: any) { - this.host.emitMessage(EventType.DEBUG, `${e.message}`); - } - return false; - } - - public async publish(): Promise { - const destination = await replaceAwsPlaceholders(this.asset.destination, this.host.aws); - const s3Url = `s3://${destination.bucketName}/${destination.objectKey}`; - const s3 = await this.host.aws.s3Client(destination); - this.host.emitMessage(EventType.CHECK, `Check ${s3Url}`); - - const bucketInfo = BucketInformation.for(this.host); - - // A thunk for describing the current account. Used when we need to format an error - // message, not in the success case. - const account = async () => (await this.host.aws.discoverTargetAccount(destination))?.accountId; - switch (await bucketInfo.bucketOwnership(s3, destination.bucketName)) { - case BucketOwnership.MINE: - break; - case BucketOwnership.DOES_NOT_EXIST: - throw new Error(`No bucket named '${destination.bucketName}'. Is account ${await account()} bootstrapped?`); - case BucketOwnership.SOMEONE_ELSES_OR_NO_ACCESS: - throw new Error(`Bucket named '${destination.bucketName}' exists, but not in account ${await account()}. Wrong account?`); - } - - if (await objectExists(s3, destination.bucketName, destination.objectKey)) { - this.host.emitMessage(EventType.FOUND, `Found ${s3Url}`); - return; - } - - // Identify the the bucket encryption type to set the header on upload - // required for SCP rules denying uploads without encryption header - let paramsEncryption: {[index: string]:any}= {}; - const encryption2 = await bucketInfo.bucketEncryption(s3, destination.bucketName); - switch (encryption2.type) { - case 'no_encryption': - break; - case 'aes256': - paramsEncryption = { ServerSideEncryption: 'AES256' }; - break; - case 'kms': - // We must include the key ID otherwise S3 will encrypt with the default key - paramsEncryption = { - ServerSideEncryption: 'aws:kms', - SSEKMSKeyId: encryption2.kmsKeyId, - }; - break; - case 'does_not_exist': - this.host.emitMessage(EventType.DEBUG, `No bucket named '${destination.bucketName}'. Is account ${await account()} bootstrapped?`); - break; - case 'access_denied': - this.host.emitMessage(EventType.DEBUG, `Could not read encryption settings of bucket '${destination.bucketName}': uploading with default settings ("cdk bootstrap" to version 9 if your organization's policies prevent a successful upload or to get rid of this message).`); - break; - } - - if (this.host.aborted) { return; } - const publishFile = this.asset.source.executable ? - await this.externalPackageFile(this.asset.source.executable) : await this.packageFile(this.asset.source); - - this.host.emitMessage(EventType.UPLOAD, `Upload ${s3Url}`); - - const params = Object.assign({}, { - Bucket: destination.bucketName, - Key: destination.objectKey, - Body: createReadStream(publishFile.packagedPath), - ContentType: publishFile.contentType, - }, - paramsEncryption); - - await s3.upload(params).promise(); - } - - private async packageFile(source: FileSource): Promise { - if (!source.path) { - throw new Error(`'path' is expected in the File asset source, got: ${JSON.stringify(source)}`); - } - - const fullPath = path.resolve(this.workDir, source.path); - - if (source.packaging === FileAssetPackaging.ZIP_DIRECTORY) { - const contentType = 'application/zip'; - - await fs.mkdir(this.fileCacheRoot, { recursive: true }); - const packagedPath = path.join(this.fileCacheRoot, `${this.asset.id.assetId}.zip`); - - if (await pathExists(packagedPath)) { - this.host.emitMessage(EventType.CACHED, `From cache ${packagedPath}`); - return { packagedPath, contentType }; - } - - this.host.emitMessage(EventType.BUILD, `Zip ${fullPath} -> ${packagedPath}`); - await zipDirectory(fullPath, packagedPath, (m) => this.host.emitMessage(EventType.DEBUG, m)); - return { packagedPath, contentType }; - } else { - const contentType = mime.getType(fullPath) ?? 'application/octet-stream'; - return { packagedPath: fullPath, contentType }; - } - } - - private async externalPackageFile(executable: string[]): Promise { - this.host.emitMessage(EventType.BUILD, `Building asset source using command: '${executable}'`); - - return { - packagedPath: (await shell(executable, { quiet: true })).trim(), - contentType: 'application/zip', - }; - } -} - -enum BucketOwnership { - DOES_NOT_EXIST, - MINE, - SOMEONE_ELSES_OR_NO_ACCESS, -} - -type BucketEncryption = - | { readonly type: 'no_encryption' } - | { readonly type: 'aes256' } - | { readonly type: 'kms'; readonly kmsKeyId?: string } - | { readonly type: 'access_denied' } - | { readonly type: 'does_not_exist' } - ; - -async function objectExists(s3: AWS.S3, bucket: string, key: string) { - /* - * The object existence check here refrains from using the `headObject` operation because this - * would create a negative cache entry, making GET-after-PUT eventually consistent. This has been - * observed to result in CloudFormation issuing "ValidationError: S3 error: Access Denied", for - * example in https://github.com/aws/aws-cdk/issues/6430. - * - * To prevent this, we are instead using the listObjectsV2 call, using the looked up key as the - * prefix, and limiting results to 1. Since the list operation returns keys ordered by binary - * UTF-8 representation, the key we are looking for is guaranteed to always be the first match - * returned if it exists. - * - * If the file is too small, we discount it as a cache hit. There is an issue - * somewhere that sometimes produces empty zip files, and we would otherwise - * never retry building those assets without users having to manually clear - * their bucket, which is a bad experience. - */ - const response = await s3.listObjectsV2({ Bucket: bucket, Prefix: key, MaxKeys: 1 }).promise(); - return ( - response.Contents != null && - response.Contents.some( - (object) => object.Key === key && (object.Size == null || object.Size > EMPTY_ZIP_FILE_SIZE), - ) - ); -} - -/** - * A packaged asset which can be uploaded (either a single file or directory) - */ -interface PackagedFileAsset { - /** - * Path of the file or directory - */ - readonly packagedPath: string; - - /** - * Content type to be added in the S3 upload action - * - * @default - No content type - */ - readonly contentType?: string; -} - -/** - * Cache for bucket information, so we don't have to keep doing the same calls again and again - * - * We scope the lifetime of the cache to the lifetime of the host, so that we don't have to do - * anything special for tests and yet the cache will live for the entire lifetime of the asset - * upload session when used by the CLI. - */ -class BucketInformation { - public static for(host: IHandlerHost) { - const existing = BucketInformation.caches.get(host); - if (existing) { return existing; } - - const fresh = new BucketInformation(); - BucketInformation.caches.set(host, fresh); - return fresh; - } - - private static readonly caches = new WeakMap(); - - private readonly ownerships = new Map(); - private readonly encryptions = new Map(); - - private constructor() { - } - - public async bucketOwnership(s3: AWS.S3, bucket: string): Promise { - return cached(this.ownerships, bucket, () => this._bucketOwnership(s3, bucket)); - } - - public async bucketEncryption(s3: AWS.S3, bucket: string): Promise { - return cached(this.encryptions, bucket, () => this._bucketEncryption(s3, bucket)); - } - - private async _bucketOwnership(s3: AWS.S3, bucket: string): Promise { - try { - await s3.getBucketLocation({ Bucket: bucket }).promise(); - return BucketOwnership.MINE; - } catch (e: any) { - if (e.code === 'NoSuchBucket') { return BucketOwnership.DOES_NOT_EXIST; } - if (['AccessDenied', 'AllAccessDisabled'].includes(e.code)) { return BucketOwnership.SOMEONE_ELSES_OR_NO_ACCESS; } - throw e; - } - } - - private async _bucketEncryption(s3: AWS.S3, bucket: string): Promise { - try { - const encryption = await s3.getBucketEncryption({ Bucket: bucket }).promise(); - const l = encryption?.ServerSideEncryptionConfiguration?.Rules?.length ?? 0; - if (l > 0) { - const apply = encryption?.ServerSideEncryptionConfiguration?.Rules[0]?.ApplyServerSideEncryptionByDefault; - let ssealgo = apply?.SSEAlgorithm; - if (ssealgo === 'AES256') return { type: 'aes256' }; - if (ssealgo === 'aws:kms') return { type: 'kms', kmsKeyId: apply?.KMSMasterKeyID }; - } - return { type: 'no_encryption' }; - } catch (e: any) { - if (e.code === 'NoSuchBucket') { - return { type: 'does_not_exist' }; - } - if (e.code === 'ServerSideEncryptionConfigurationNotFoundError') { - return { type: 'no_encryption' }; - } - - if (['AccessDenied', 'AllAccessDisabled'].includes(e.code)) { - return { type: 'access_denied' }; - } - return { type: 'no_encryption' }; - } - } -} - -async function cached(cache: Map, key: A, factory: (x: A) => Promise): Promise { - if (cache.has(key)) { - return cache.get(key)!; - } - - const fresh = await factory(key); - cache.set(key, fresh); - return fresh; -} diff --git a/packages/cdk-assets/lib/private/handlers/index.ts b/packages/cdk-assets/lib/private/handlers/index.ts deleted file mode 100644 index 2b3c767eb4963..0000000000000 --- a/packages/cdk-assets/lib/private/handlers/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ContainerImageAssetHandler } from './container-images'; -import { FileAssetHandler } from './files'; -import { AssetManifest, DockerImageManifestEntry, FileManifestEntry, IManifestEntry } from '../../asset-manifest'; -import { IAssetHandler, IHandlerHost, IHandlerOptions } from '../asset-handler'; - -export function makeAssetHandler(manifest: AssetManifest, asset: IManifestEntry, host: IHandlerHost, options: IHandlerOptions): IAssetHandler { - if (asset instanceof FileManifestEntry) { - return new FileAssetHandler(manifest.directory, asset, host); - } - if (asset instanceof DockerImageManifestEntry) { - return new ContainerImageAssetHandler(manifest.directory, asset, host, options); - } - - throw new Error(`Unrecognized asset type: '${asset}'`); -} diff --git a/packages/cdk-assets/lib/private/placeholders.ts b/packages/cdk-assets/lib/private/placeholders.ts deleted file mode 100644 index 50f76dfd3a7a6..0000000000000 --- a/packages/cdk-assets/lib/private/placeholders.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { EnvironmentPlaceholders } from '@aws-cdk/cx-api'; -import { IAws } from '../aws'; - -/** - * Replace the {ACCOUNT} and {REGION} placeholders in all strings found in a complex object. - * - * Duplicated between cdk-assets and aws-cdk CLI because we don't have a good single place to put it - * (they're nominally independent tools). - */ -export async function replaceAwsPlaceholders(object: A, aws: IAws): Promise { - let partition = async () => { - const p = await aws.discoverPartition(); - partition = () => Promise.resolve(p); - return p; - }; - - let account = async () => { - const a = await aws.discoverCurrentAccount(); - account = () => Promise.resolve(a); - return a; - }; - - return EnvironmentPlaceholders.replaceAsync(object, { - async region() { - return object.region ?? aws.discoverDefaultRegion(); - }, - async accountId() { - return (await account()).accountId; - }, - async partition() { - return partition(); - }, - }); -} \ No newline at end of file diff --git a/packages/cdk-assets/lib/private/shell.ts b/packages/cdk-assets/lib/private/shell.ts deleted file mode 100644 index 5e27452f98bab..0000000000000 --- a/packages/cdk-assets/lib/private/shell.ts +++ /dev/null @@ -1,127 +0,0 @@ -import * as child_process from 'child_process'; - -export type Logger = (x: string) => void; - -export interface ShellOptions extends child_process.SpawnOptions { - readonly quiet?: boolean; - readonly logger?: Logger; - readonly input?: string; -} - -/** - * OS helpers - * - * Shell function which both prints to stdout and collects the output into a - * string. - */ -export async function shell(command: string[], options: ShellOptions = {}): Promise { - if (options.logger) { - options.logger(renderCommandLine(command)); - } - const child = child_process.spawn(command[0], command.slice(1), { - ...options, - stdio: [options.input ? 'pipe' : 'ignore', 'pipe', 'pipe'], - }); - - return new Promise((resolve, reject) => { - if (options.input) { - child.stdin!.write(options.input); - child.stdin!.end(); - } - - const stdout = new Array(); - const stderr = new Array(); - - // Both write to stdout and collect - child.stdout!.on('data', chunk => { - if (!options.quiet) { - process.stdout.write(chunk); - } - stdout.push(chunk); - }); - - child.stderr!.on('data', chunk => { - if (!options.quiet) { - process.stderr.write(chunk); - } - - stderr.push(chunk); - }); - - child.once('error', reject); - - child.once('close', (code, signal) => { - if (code === 0) { - resolve(Buffer.concat(stdout).toString('utf-8')); - } else { - const out = Buffer.concat(stderr).toString('utf-8').trim(); - reject(new ProcessFailed(code, signal, `${renderCommandLine(command)} exited with ${code != null ? 'error code' : 'signal'} ${code ?? signal}: ${out}`)); - } - }); - }); -} - -export type ProcessFailedError = ProcessFailed - -class ProcessFailed extends Error { - public readonly code = 'PROCESS_FAILED'; - - constructor(public readonly exitCode: number | null, public readonly signal: NodeJS.Signals | null, message: string) { - super(message); - } -} - -/** - * Render the given command line as a string - * - * Probably missing some cases but giving it a good effort. - */ -function renderCommandLine(cmd: string[]) { - if (process.platform !== 'win32') { - return doRender(cmd, hasAnyChars(' ', '\\', '!', '"', "'", '&', '$'), posixEscape); - } else { - return doRender(cmd, hasAnyChars(' ', '"', '&', '^', '%'), windowsEscape); - } -} - -/** - * Render a UNIX command line - */ -function doRender(cmd: string[], needsEscaping: (x: string) => boolean, doEscape: (x: string) => string): string { - return cmd.map(x => needsEscaping(x) ? doEscape(x) : x).join(' '); -} - -/** - * Return a predicate that checks if a string has any of the indicated chars in it - */ -function hasAnyChars(...chars: string[]): (x: string) => boolean { - return (str: string) => { - return chars.some(c => str.indexOf(c) !== -1); - }; -} - -/** - * Escape a shell argument for POSIX shells - * - * Wrapping in single quotes and escaping single quotes inside will do it for us. - */ -function posixEscape(x: string) { - // Turn ' -> '"'"' - x = x.replace(/'/g, "'\"'\"'"); - return `'${x}'`; -} - -/** - * Escape a shell argument for cmd.exe - * - * This is how to do it right, but I'm not following everything: - * - * https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ - */ -function windowsEscape(x: string): string { - // First surround by double quotes, ignore the part about backslashes - x = `"${x}"`; - // Now escape all special characters - const shellMeta = new Set(['"', '&', '^', '%']); - return x.split('').map(c => shellMeta.has(x) ? '^' + c : c).join(''); -} diff --git a/packages/cdk-assets/lib/private/util.ts b/packages/cdk-assets/lib/private/util.ts deleted file mode 100644 index 88a87a18e6ba9..0000000000000 --- a/packages/cdk-assets/lib/private/util.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Creates a critical section, ensuring that at most one function can - * enter the critical section at a time. - */ -export function createCriticalSection() { - let lock = Promise.resolve(); - return async (criticalFunction: () => Promise) => { - const res = lock.then(() => criticalFunction()); - lock = res.catch(e => e); - return res; - }; -}; \ No newline at end of file diff --git a/packages/cdk-assets/lib/progress.ts b/packages/cdk-assets/lib/progress.ts deleted file mode 100644 index b2c8e77ddad78..0000000000000 --- a/packages/cdk-assets/lib/progress.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { IManifestEntry } from './asset-manifest'; - -/** - * A listener for progress events from the publisher - */ -export interface IPublishProgressListener { - /** - * Asset build event - */ - onPublishEvent(type: EventType, event: IPublishProgress): void; -} - -/** - * A single event for an asset - */ -export enum EventType { - /** - * Just starting on an asset - */ - START = 'start', - - /** - * When an asset is successfully finished - */ - SUCCESS = 'success', - - /** - * When an asset failed - */ - FAIL = 'fail', - - /** - * Checking whether an asset has already been published - */ - CHECK = 'check', - - /** - * The asset was already published - */ - FOUND = 'found', - - /** - * The asset was reused locally from a cached version - */ - CACHED = 'cached', - - /** - * The asset will be built - */ - BUILD = 'build', - - /** - * The asset will be uploaded - */ - UPLOAD = 'upload', - - /** - * Another type of detail message - */ - DEBUG = 'debug', -} - -/** - * Context object for publishing progress - */ -export interface IPublishProgress { - /** - * Current event message - */ - readonly message: string; - - /** - * Asset currently being packaged (if any) - */ - readonly currentAsset?: IManifestEntry; - - /** - * How far along are we? - */ - readonly percentComplete: number; - - /** - * Abort the current publishing operation - */ - abort(): void; -} diff --git a/packages/cdk-assets/lib/publishing.ts b/packages/cdk-assets/lib/publishing.ts deleted file mode 100644 index 03cf2683f3293..0000000000000 --- a/packages/cdk-assets/lib/publishing.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { AssetManifest, IManifestEntry } from './asset-manifest'; -import { IAws } from './aws'; -import { IAssetHandler, IHandlerHost } from './private/asset-handler'; -import { DockerFactory } from './private/docker'; -import { makeAssetHandler } from './private/handlers'; -import { EventType, IPublishProgress, IPublishProgressListener } from './progress'; - -export interface AssetPublishingOptions { - /** - * Entry point for AWS client - */ - readonly aws: IAws; - - /** - * Listener for progress events - * - * @default No listener - */ - readonly progressListener?: IPublishProgressListener; - - /** - * Whether to throw at the end if there were errors - * - * @default true - */ - readonly throwOnError?: boolean; - - /** - * Whether to publish in parallel, when 'publish()' is called - * - * @default false - */ - readonly publishInParallel?: boolean; - - /** - * Whether to build assets, when 'publish()' is called - * - * @default true - */ - readonly buildAssets?: boolean; - - /** - * Whether to publish assets, when 'publish()' is called - * - * @default true - */ - readonly publishAssets?: boolean; - - /** - * Whether to print publishing logs - * - * @default true - */ - readonly quiet?: boolean; -} - -/** - * A failure to publish an asset - */ -export interface FailedAsset { - /** - * The asset that failed to publish - */ - readonly asset: IManifestEntry; - - /** - * The failure that occurred - */ - readonly error: Error; -} - -export class AssetPublishing implements IPublishProgress { - /** - * The message for the IPublishProgress interface - */ - public message: string = 'Starting'; - - /** - * The current asset for the IPublishProgress interface - */ - public currentAsset?: IManifestEntry; - public readonly failures = new Array(); - private readonly assets: IManifestEntry[]; - - private readonly totalOperations: number; - private completedOperations: number = 0; - private aborted = false; - private readonly handlerHost: IHandlerHost; - private readonly publishInParallel: boolean; - private readonly buildAssets: boolean; - private readonly publishAssets: boolean; - private readonly handlerCache = new Map(); - - constructor(private readonly manifest: AssetManifest, private readonly options: AssetPublishingOptions) { - this.assets = manifest.entries; - this.totalOperations = this.assets.length; - this.publishInParallel = options.publishInParallel ?? false; - this.buildAssets = options.buildAssets ?? true; - this.publishAssets = options.publishAssets ?? true; - - const self = this; - this.handlerHost = { - aws: this.options.aws, - get aborted() { return self.aborted; }, - emitMessage(t, m) { self.progressEvent(t, m); }, - dockerFactory: new DockerFactory(), - }; - } - - /** - * Publish all assets from the manifest - */ - public async publish(): Promise { - if (this.publishInParallel) { - await Promise.all(this.assets.map(async (asset) => this.publishAsset(asset))); - } else { - for (const asset of this.assets) { - if (!await this.publishAsset(asset)) { - break; - } - } - } - - if ((this.options.throwOnError ?? true) && this.failures.length > 0) { - throw new Error(`Error publishing: ${this.failures.map(e => e.error.message)}`); - } - } - - /** - * Build a single asset from the manifest - */ - public async buildEntry(asset: IManifestEntry) { - try { - if (this.progressEvent(EventType.START, `Building ${asset.id}`)) { return false; } - - const handler = this.assetHandler(asset); - await handler.build(); - - if (this.aborted) { - throw new Error('Aborted'); - } - - this.completedOperations++; - if (this.progressEvent(EventType.SUCCESS, `Built ${asset.id}`)) { return false; } - } catch (e: any) { - this.failures.push({ asset, error: e }); - this.completedOperations++; - if (this.progressEvent(EventType.FAIL, e.message)) { return false; } - } - - return true; - } - - /** - * Publish a single asset from the manifest - */ - public async publishEntry(asset: IManifestEntry) { - try { - if (this.progressEvent(EventType.START, `Publishing ${asset.id}`)) { return false; } - - const handler = this.assetHandler(asset); - await handler.publish(); - - if (this.aborted) { - throw new Error('Aborted'); - } - - this.completedOperations++; - if (this.progressEvent(EventType.SUCCESS, `Published ${asset.id}`)) { return false; } - } catch (e: any) { - this.failures.push({ asset, error: e }); - this.completedOperations++; - if (this.progressEvent(EventType.FAIL, e.message)) { return false; } - } - - return true; - } - - /** - * Return whether a single asset is published - */ - public isEntryPublished(asset: IManifestEntry) { - const handler = this.assetHandler(asset); - return handler.isPublished(); - } - - /** - * publish an asset (used by 'publish()') - * @param asset The asset to publish - * @returns false when publishing should stop - */ - private async publishAsset(asset: IManifestEntry) { - try { - if (this.progressEvent(EventType.START, `Publishing ${asset.id}`)) { return false; } - - const handler = this.assetHandler(asset); - - if (this.buildAssets) { - await handler.build(); - } - - if (this.publishAssets) { - await handler.publish(); - } - - if (this.aborted) { - throw new Error('Aborted'); - } - - this.completedOperations++; - if (this.progressEvent(EventType.SUCCESS, `Published ${asset.id}`)) { return false; } - } catch (e: any) { - this.failures.push({ asset, error: e }); - this.completedOperations++; - if (this.progressEvent(EventType.FAIL, e.message)) { return false; } - } - - return true; - } - - public get percentComplete() { - if (this.totalOperations === 0) { return 100; } - return Math.floor((this.completedOperations / this.totalOperations) * 100); - } - - public abort(): void { - this.aborted = true; - } - - public get hasFailures() { - return this.failures.length > 0; - } - - /** - * Publish a progress event to the listener, if present. - * - * Returns whether an abort is requested. Helper to get rid of repetitive code in publish(). - */ - private progressEvent(event: EventType, message: string): boolean { - this.message = message; - if (this.options.progressListener) { this.options.progressListener.onPublishEvent(event, this); } - return this.aborted; - } - - private assetHandler(asset: IManifestEntry) { - const existing = this.handlerCache.get(asset); - if (existing) { - return existing; - } - const ret = makeAssetHandler(this.manifest, asset, this.handlerHost, { - quiet: this.options.quiet, - }); - this.handlerCache.set(asset, ret); - return ret; - } -} diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json deleted file mode 100644 index de40a5838def7..0000000000000 --- a/packages/cdk-assets/package.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "name": "cdk-assets", - "description": "CDK Asset Publishing Tool", - "version": "0.0.0", - "main": "lib/index.js", - "types": "lib/index.d.ts", - "bin": { - "cdk-assets": "bin/cdk-assets", - "docker-credential-cdk-assets": "bin/docker-credential-cdk-assets" - }, - "scripts": { - "build": "cdk-build", - "integ": "integ-runner --language javascript", - "lint": "cdk-lint", - "package": "cdk-package", - "awslint": "cdk-awslint", - "pkglint": "pkglint -f", - "test": "cdk-test", - "watch": "cdk-watch", - "build+test": "yarn build && yarn test", - "build+test+package": "yarn build+test && yarn package", - "compat": "cdk-compat", - "build+extract": "yarn build", - "build+test+extract": "yarn build+test" - }, - "author": { - "name": "Amazon Web Services", - "url": "https://aws.amazon.com", - "organization": true - }, - "license": "Apache-2.0", - "devDependencies": { - "@types/archiver": "^5.3.4", - "@types/glob": "^7.2.0", - "@types/jest": "^29.5.12", - "@types/mime": "^2.0.3", - "@types/mock-fs": "^4.13.4", - "@types/yargs": "^15.0.19", - "@aws-cdk/cdk-build-tools": "0.0.0", - "jest": "^29.7.0", - "jszip": "^3.10.1", - "mock-fs": "^4.14.0", - "@aws-cdk/pkglint": "0.0.0" - }, - "dependencies": { - "@aws-cdk/cloud-assembly-schema": "0.0.0", - "@aws-cdk/cx-api": "0.0.0", - "archiver": "^5.3.2", - "aws-sdk": "^2.1648.0", - "glob": "^7.2.3", - "mime": "^2.6.0", - "yargs": "^16.2.0" - }, - "repository": { - "url": "https://github.com/aws/aws-cdk.git", - "type": "git", - "directory": "packages/cdk-assets" - }, - "keywords": [ - "aws", - "cdk" - ], - "homepage": "https://github.com/aws/aws-cdk", - "engines": { - "node": ">= 14.15.0" - }, - "cdk-package": { - "shrinkWrap": true - }, - "nozem": { - "ostools": [ - "unzip", - "diff", - "rm" - ] - }, - "stability": "stable", - "maturity": "stable", - "publishConfig": { - "tag": "latest" - } -} diff --git a/packages/cdk-assets/test/archive.test.ts b/packages/cdk-assets/test/archive.test.ts deleted file mode 100644 index d0fe1e2b3dbe7..0000000000000 --- a/packages/cdk-assets/test/archive.test.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { exec as _exec } from 'child_process'; -import * as crypto from 'crypto'; -import { constants, exists, promises as fs } from 'fs'; -import * as os from 'os'; -import * as path from 'path'; -import { promisify } from 'util'; -import * as jszip from 'jszip'; -import { zipDirectory } from '../lib/private/archive'; -import { rmRfSync } from '../lib/private/fs-extra'; -const exec = promisify(_exec); -const pathExists = promisify(exists); - -function logger(x: string) { - // eslint-disable-next-line no-console - console.log(x); -} - -test('zipDirectory can take a directory and produce a zip from it', async () => { - const stagingDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test.archive')); - const extractDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test.archive.extract')); - try { - const zipFile = path.join(stagingDir, 'output.zip'); - const originalDir = path.join(__dirname, 'test-archive'); - await zipDirectory(originalDir, zipFile, logger); - - // unzip and verify that the resulting tree is the same - await exec(`unzip ${zipFile}`, { cwd: extractDir }); - - await expect(exec(`diff -bur ${originalDir} ${extractDir}`)).resolves.toBeTruthy(); - - // inspect the zip file to check that dates are reset - const zip = await fs.readFile(zipFile); - const zipData = await jszip.loadAsync(zip); - const dates = Object.values(zipData.files).map(file => file.date.toISOString()); - expect(dates[0]).toBe('1980-01-01T00:00:00.000Z'); - expect(new Set(dates).size).toBe(1); - - // check that mode is preserved - const stat = await fs.stat(path.join(extractDir, 'executable.txt')); - // eslint-disable-next-line no-bitwise - const isExec = (stat.mode & constants.S_IXUSR) || (stat.mode & constants.S_IXGRP) || (stat.mode & constants.S_IXOTH); - expect(isExec).toBeTruthy(); - } finally { - rmRfSync(stagingDir); - rmRfSync(extractDir); - } -}); - -test('md5 hash of a zip stays consistent across invocations', async () => { - const stagingDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test.archive')); - const zipFile1 = path.join(stagingDir, 'output.zip'); - const zipFile2 = path.join(stagingDir, 'output.zip'); - const originalDir = path.join(__dirname, 'test-archive'); - await zipDirectory(originalDir, zipFile1, logger); - await new Promise(ok => setTimeout(ok, 2000)); // wait 2s - await zipDirectory(originalDir, zipFile2, logger); - - const hash1 = contentHash(await fs.readFile(zipFile1)); - const hash2 = contentHash(await fs.readFile(zipFile2)); - - expect(hash1).toEqual(hash2); -}); - -test('zipDirectory follows symlinks', async () => { - const stagingDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test.archive')); - const extractDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test.archive.follow')); - try { - // First MAKE the symlink we're going to follow. We can't check it into git, because - // CodeBuild/CodePipeline (I forget which) is going to replace symlinks with a textual - // representation of its target upon checkout, for security reasons. So, to make sure - // the symlink exists, we need to create it at build time. - const symlinkPath = path.join(__dirname, 'test-archive-follow', 'data', 'linked'); - const symlinkTarget = '../linked'; - - if (await pathExists(symlinkPath)) { - await fs.unlink(symlinkPath); - } - await fs.symlink(symlinkTarget, symlinkPath, 'dir'); - - const originalDir = path.join(__dirname, 'test-archive-follow', 'data'); - const zipFile = path.join(stagingDir, 'output.zip'); - - await expect(zipDirectory(originalDir, zipFile, logger)).resolves.toBeUndefined(); - await expect(exec(`unzip ${zipFile}`, { cwd: extractDir })).resolves.toBeDefined(); - await expect(exec(`diff -bur ${originalDir} ${extractDir}`)).resolves.toBeDefined(); - } finally { - rmRfSync(stagingDir); - rmRfSync(extractDir); - } -}); - -function contentHash(data: string | Buffer | DataView) { - return crypto.createHash('sha256').update(data).digest('hex'); -} diff --git a/packages/cdk-assets/test/docker-images.test.ts b/packages/cdk-assets/test/docker-images.test.ts deleted file mode 100644 index c396853576c3e..0000000000000 --- a/packages/cdk-assets/test/docker-images.test.ts +++ /dev/null @@ -1,706 +0,0 @@ -jest.mock('child_process'); - -import * as fs from 'fs'; -import { Manifest } from '@aws-cdk/cloud-assembly-schema'; -import * as mockfs from 'mock-fs'; -import { mockAws, mockedApiFailure, mockedApiResult } from './mock-aws'; -import { mockSpawn } from './mock-child_process'; -import { AssetManifest, AssetPublishing } from '../lib'; -import * as dockercreds from '../lib/private/docker-credentials'; - -let aws: ReturnType; -const absoluteDockerPath = '/simple/cdk.out/dockerdir'; -beforeEach(() => { - jest.resetAllMocks(); - delete(process.env.CDK_DOCKER); - - // By default, assume no externally-configured credentials. - jest.spyOn(dockercreds, 'cdkCredentialsConfig').mockReturnValue(undefined); - - mockfs({ - '/simple/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset: { - source: { - directory: 'dockerdir', - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'abcdef', - }, - }, - }, - }, - }), - '/multi/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset1: { - source: { - directory: 'dockerdir', - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'theAsset1', - }, - }, - }, - theAsset2: { - source: { - directory: 'dockerdir', - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'theAsset2', - }, - }, - }, - }, - }), - '/external/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theExternalAsset: { - source: { - executable: ['sometool'], - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'ghijkl', - }, - }, - }, - }, - }), - '/simple/cdk.out/dockerdir/Dockerfile': 'FROM scratch', - '/abs/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset: { - source: { - directory: absoluteDockerPath, - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'abcdef', - }, - }, - }, - }, - }), - '/default-network/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset: { - source: { - directory: 'dockerdir', - networkMode: 'default', - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'nopqr', - }, - }, - }, - }, - }), - '/default-network/cdk.out/dockerdir/Dockerfile': 'FROM scratch', - '/platform-arm64/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset: { - source: { - directory: 'dockerdir', - platform: 'linux/arm64', - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'nopqr', - }, - }, - }, - }, - }), - '/cache/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset: { - source: { - directory: 'dockerdir', - cacheFrom: [{ type: 'registry', params: { ref: 'abcdef' } }], - cacheTo: { type: 'inline' }, - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'nopqr', - }, - }, - }, - }, - }), - '/cache-from-multiple/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset: { - source: { - directory: 'dockerdir', - cacheFrom: [ - { type: 'registry', params: { ref: 'cache:ref' } }, - { type: 'registry', params: { ref: 'cache:main' } }, - { type: 'gha' }, - ], - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'nopqr', - }, - }, - }, - }, - }), - '/cache-to-complex/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset: { - source: { - directory: 'dockerdir', - cacheTo: { type: 'registry', params: { ref: 'cache:main', mode: 'max', compression: 'zstd' } }, - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'nopqr', - }, - }, - }, - }, - }), - '/nocache/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - dockerImages: { - theAsset: { - source: { - directory: 'dockerdir', - cacheDisabled: true, - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - repositoryName: 'repo', - imageTag: 'nopqr', - }, - }, - }, - }, - }), - '/platform-arm64/cdk.out/dockerdir/Dockerfile': 'FROM scratch', - }); - - aws = mockAws(); -}); - -afterEach(() => { - mockfs.restore(); -}); - -test('pass destination properties to AWS client', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws, throwOnError: false }); - - await pub.publish(); - - expect(aws.ecrClient).toHaveBeenCalledWith(expect.objectContaining({ - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - })); -}); - -describe('with a complete manifest', () => { - let pub: AssetPublishing; - beforeEach(() => { - pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - }); - - test('Do nothing if docker image already exists', async () => { - aws.mockEcr.describeImages = mockedApiResult({ /* No error == image exists */ }); - - await pub.publish(); - - expect(aws.mockEcr.describeImages).toHaveBeenCalledWith(expect.objectContaining({ - imageIds: [{ imageTag: 'abcdef' }], - repositoryName: 'repo', - })); - }); - - test('Displays an error if the ECR repository cannot be found', async () => { - aws.mockEcr.describeImages = mockedApiFailure('RepositoryNotFoundException', 'Repository not Found'); - - await expect(pub.publish()).rejects.toThrow('Error publishing: Repository not Found'); - }); - - test('successful run does not need to query account ID', async () => { - aws.mockEcr.describeImages = mockedApiResult({ /* No error == image exists */ }); - await pub.publish(); - expect(aws.discoverCurrentAccount).not.toHaveBeenCalled(); - }); - - test('upload docker image if not uploaded yet but exists locally', async () => { - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset'] }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:abcdef'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:abcdef'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - }); - - test('build and upload docker image if not exists anywhere', async () => { - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '.'], cwd: absoluteDockerPath }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:abcdef'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:abcdef'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - }); - - test('build with networkMode option', async () => { - pub = new AssetPublishing(AssetManifest.fromPath('/default-network/cdk.out'), { aws }); - const defaultNetworkDockerpath = '/default-network/cdk.out/dockerdir'; - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '--network', 'default', '.'], cwd: defaultNetworkDockerpath }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - }); - - test('build with platform option', async () => { - pub = new AssetPublishing(AssetManifest.fromPath('/platform-arm64/cdk.out'), { aws }); - const defaultNetworkDockerpath = '/platform-arm64/cdk.out/dockerdir'; - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '--platform', 'linux/arm64', '.'], cwd: defaultNetworkDockerpath }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - }); - - test('build with cache option', async () => { - pub = new AssetPublishing(AssetManifest.fromPath('/cache/cdk.out'), { aws }); - const defaultNetworkDockerpath = '/cache/cdk.out/dockerdir'; - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '--cache-from', 'type=registry,ref=abcdef', '--cache-to', 'type=inline', '.'], cwd: defaultNetworkDockerpath }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - }); - - test('build with cache disabled', async () => { - pub = new AssetPublishing(AssetManifest.fromPath('/nocache/cdk.out'), { aws }); - const defaultNetworkDockerpath = '/nocache/cdk.out/dockerdir'; - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '--no-cache', '.'], cwd: defaultNetworkDockerpath }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - }); - - test('build with multiple cache from option', async () => { - pub = new AssetPublishing(AssetManifest.fromPath('/cache-from-multiple/cdk.out'), { aws }); - const defaultNetworkDockerpath = '/cache-from-multiple/cdk.out/dockerdir'; - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, - { - commandLine: [ - 'docker', 'build', '--tag', 'cdkasset-theasset', '--cache-from', 'type=registry,ref=cache:ref', '--cache-from', 'type=registry,ref=cache:main', '--cache-from', 'type=gha', '.', - ], - cwd: defaultNetworkDockerpath, - }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - }); - - test('build with cache to complex option', async () => { - pub = new AssetPublishing(AssetManifest.fromPath('/cache-to-complex/cdk.out'), { aws }); - const defaultNetworkDockerpath = '/cache-to-complex/cdk.out/dockerdir'; - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '--cache-to', 'type=registry,ref=cache:main,mode=max,compression=zstd', '.'], cwd: defaultNetworkDockerpath }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:nopqr'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:nopqr'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - }); -}); - -describe('external assets', () => { - let pub: AssetPublishing; - const externalTag = 'external:tag'; - beforeEach(() => { - pub = new AssetPublishing(AssetManifest.fromPath('/external/cdk.out'), { aws }); - }); - - test('upload externally generated Docker image', async () => { - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['sometool'], stdout: externalTag, cwd: '/external/cdk.out' }, - { commandLine: ['docker', 'tag', externalTag, '12345.amazonaws.com/repo:ghijkl'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:ghijkl'] }, - ); - - await pub.publish(); - - expect(aws.ecrClient).toHaveBeenCalledWith(expect.objectContaining({ - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - })); - expectAllSpawns(); - }); -}); - -test('correctly identify Docker directory if path is absolute', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/abs/cdk.out'), { aws }); - - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - // Only care about the 'build' command line - { commandLine: ['docker', 'login'], prefix: true }, - { commandLine: ['docker', 'inspect'], exitCode: 1, prefix: true }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset', '.'], cwd: absoluteDockerPath }, - { commandLine: ['docker', 'tag'], prefix: true }, - { commandLine: ['docker', 'push'], prefix: true }, - ); - - await pub.publish(); - - expect(true).toBeTruthy(); // Expect no exception, satisfy linter - expectAllSpawns(); -}); - -test('when external credentials are present, explicit Docker config directories are used', async () => { - // Setup -- Mock that we have CDK credentials, and mock fs operations. - jest.spyOn(dockercreds, 'cdkCredentialsConfig').mockReturnValue({ version: '0.1', domainCredentials: {} }); - jest.spyOn(fs, 'mkdtempSync').mockImplementationOnce(() => '/tmp/mockedTempDir'); - jest.spyOn(fs, 'writeFileSync').mockImplementation(jest.fn()); - - let pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - // Initally use the first created directory with the CDK credentials - { commandLine: ['docker', '--config', '/tmp/mockedTempDir', 'inspect', 'cdkasset-theasset'], exitCode: 1 }, - { commandLine: ['docker', '--config', '/tmp/mockedTempDir', 'build', '--tag', 'cdkasset-theasset', '.'], cwd: absoluteDockerPath }, - { commandLine: ['docker', '--config', '/tmp/mockedTempDir', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:abcdef'] }, - // Prior to push, revert to the default config directory - { commandLine: ['docker', 'login'], prefix: true }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:abcdef'] }, - ); - - await pub.publish(); - - expectAllSpawns(); -}); - -test('logging in only once for two assets', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/multi/cdk.out'), { aws, throwOnError: false }); - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset1'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset1', '.'], cwd: '/multi/cdk.out/dockerdir' }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset1', '12345.amazonaws.com/repo:theAsset1'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:theAsset1'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset2'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset2', '.'], cwd: '/multi/cdk.out/dockerdir' }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset2', '12345.amazonaws.com/repo:theAsset2'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/repo:theAsset2'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter -}); - -test('logging in twice for two repository domains (containing account id & region)', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/multi/cdk.out'), { aws, throwOnError: false }); - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - - let repoIdx = 12345; - aws.mockEcr.describeRepositories = jest.fn().mockReturnValue({ - promise: jest.fn().mockImplementation(() => Promise.resolve({ - repositories: [ - // Usually looks like: 012345678910.dkr.ecr.us-west-2.amazonaws.com/aws-cdk/assets - { repositoryUri: `${repoIdx++}.amazonaws.com/aws-cdk/assets` }, - ], - })), - }); - - let proxyIdx = 12345; - aws.mockEcr.getAuthorizationToken = jest.fn().mockReturnValue({ - promise: jest.fn().mockImplementation(() => Promise.resolve({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: `https://${proxyIdx++}.proxy.com/` }, - ], - })), - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://12345.proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset1'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset1', '.'], cwd: '/multi/cdk.out/dockerdir' }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset1', '12345.amazonaws.com/aws-cdk/assets:theAsset1'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/aws-cdk/assets:theAsset1'] }, - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://12346.proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset2'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset2', '.'], cwd: '/multi/cdk.out/dockerdir' }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset2', '12346.amazonaws.com/aws-cdk/assets:theAsset2'] }, - { commandLine: ['docker', 'push', '12346.amazonaws.com/aws-cdk/assets:theAsset2'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter -}); - -test('building only', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/multi/cdk.out'), { - aws, - throwOnError: false, - buildAssets: true, - publishAssets: false, - }); - - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset1'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset1', '.'], cwd: '/multi/cdk.out/dockerdir' }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset1', '12345.amazonaws.com/repo:theAsset1'] }, - { commandLine: ['docker', 'inspect', 'cdkasset-theasset2'], exitCode: 1 }, - { commandLine: ['docker', 'build', '--tag', 'cdkasset-theasset2', '.'], cwd: '/multi/cdk.out/dockerdir' }, - { commandLine: ['docker', 'tag', 'cdkasset-theasset2', '12345.amazonaws.com/repo:theAsset2'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter -}); - -test('publishing only', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/multi/cdk.out'), { - aws, - throwOnError: false, - buildAssets: false, - publishAssets: true, - }); - - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['docker', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/aws-cdk/assets:theAsset1'] }, - { commandLine: ['docker', 'push', '12345.amazonaws.com/aws-cdk/assets:theAsset2'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter -}); - -test('overriding the docker command', async () => { - process.env.CDK_DOCKER = 'custom'; - - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws, throwOnError: false }); - - aws.mockEcr.describeImages = mockedApiFailure('ImageNotFoundException', 'File does not exist'); - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { authorizationToken: 'dXNlcjpwYXNz', proxyEndpoint: 'https://proxy.com/' }, - ], - }); - - const expectAllSpawns = mockSpawn( - { commandLine: ['custom', 'login', '--username', 'user', '--password-stdin', 'https://proxy.com/'] }, - { commandLine: ['custom', 'inspect', 'cdkasset-theasset'] }, - { commandLine: ['custom', 'tag', 'cdkasset-theasset', '12345.amazonaws.com/repo:abcdef'] }, - { commandLine: ['custom', 'push', '12345.amazonaws.com/repo:abcdef'] }, - ); - - await pub.publish(); - - expectAllSpawns(); - expect(true).toBeTruthy(); // Expect no exception, satisfy linter -}); diff --git a/packages/cdk-assets/test/fake-listener.ts b/packages/cdk-assets/test/fake-listener.ts deleted file mode 100644 index 7aef7fbe9d9f6..0000000000000 --- a/packages/cdk-assets/test/fake-listener.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { IPublishProgressListener, EventType, IPublishProgress } from '../lib/progress'; - -export class FakeListener implements IPublishProgressListener { - public readonly types = new Array(); - public readonly messages = new Array(); - - constructor(private readonly doAbort = false) { - } - - public onPublishEvent(_type: EventType, event: IPublishProgress): void { - this.messages.push(event.message); - - if (this.doAbort) { - event.abort(); - } - } -} \ No newline at end of file diff --git a/packages/cdk-assets/test/files.test.ts b/packages/cdk-assets/test/files.test.ts deleted file mode 100644 index 83af51717bea6..0000000000000 --- a/packages/cdk-assets/test/files.test.ts +++ /dev/null @@ -1,344 +0,0 @@ -jest.mock('child_process'); - -import { Manifest } from '@aws-cdk/cloud-assembly-schema'; -import * as mockfs from 'mock-fs'; -import { FakeListener } from './fake-listener'; -import { mockAws, mockedApiFailure, mockedApiResult, mockUpload } from './mock-aws'; -import { mockSpawn } from './mock-child_process'; -import { AssetPublishing, AssetManifest } from '../lib'; - -const ABS_PATH = '/simple/cdk.out/some_external_file'; - -const DEFAULT_DESTINATION = { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - bucketName: 'some_bucket', - objectKey: 'some_key', -}; - -let aws: ReturnType; -beforeEach(() => { - jest.resetAllMocks(); - - mockfs({ - '/simple/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - theAsset: { - source: { - path: 'some_file', - }, - destinations: { theDestination: DEFAULT_DESTINATION }, - }, - }, - }), - '/simple/cdk.out/some_file': 'FILE_CONTENTS', - [ABS_PATH]: 'ZIP_FILE_THAT_IS_DEFINITELY_NOT_EMPTY', - '/abs/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - theAsset: { - source: { - path: '/simple/cdk.out/some_file', - }, - destinations: { theDestination: { ...DEFAULT_DESTINATION, bucketName: 'some_other_bucket' } }, - }, - }, - }), - '/external/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - externalAsset: { - source: { - executable: ['sometool'], - }, - destinations: { theDestination: { ...DEFAULT_DESTINATION, bucketName: 'some_external_bucket' } }, - }, - }, - }), - '/types/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - theTextAsset: { - source: { - path: 'plain_text.txt', - }, - destinations: { theDestination: { ...DEFAULT_DESTINATION, objectKey: 'some_key.txt' } }, - }, - theImageAsset: { - source: { - path: 'image.png', - }, - destinations: { theDestination: { ...DEFAULT_DESTINATION, objectKey: 'some_key.png' } }, - }, - }, - }), - '/types/cdk.out/plain_text.txt': 'FILE_CONTENTS', - '/types/cdk.out/image.png': 'FILE_CONTENTS', - '/emptyzip/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - theTextAsset: { - source: { - path: 'empty_dir', - packaging: 'zip', - }, - destinations: { theDestination: DEFAULT_DESTINATION }, - }, - }, - }), - '/emptyzip/cdk.out/empty_dir': { }, // Empty directory - }); - - aws = mockAws(); -}); - -afterEach(() => { - mockfs.restore(); -}); - -test('pass destination properties to AWS client', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws, throwOnError: false }); - aws.mockS3.listObjectsV2 = mockedApiResult({}); - - await pub.publish(); - - expect(aws.s3Client).toHaveBeenCalledWith(expect.objectContaining({ - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - })); -}); - -test('Do nothing if file already exists', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: [{ Key: 'some_key' }] }); - aws.mockS3.upload = mockUpload(); - await pub.publish(); - - expect(aws.mockS3.listObjectsV2).toHaveBeenCalledWith(expect.objectContaining({ - Bucket: 'some_bucket', - Prefix: 'some_key', - MaxKeys: 1, - })); - expect(aws.mockS3.upload).not.toHaveBeenCalled(); -}); - -test('tiny file does not count as cache hit', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: [{ Key: 'some_key', Size: 5 }] }); - aws.mockS3.upload = mockUpload(); - - await pub.publish(); - - expect(aws.mockS3.upload).toHaveBeenCalled(); -}); - -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', - ContentType: 'application/octet-stream', - })); - - // We'll just have to assume the contents are correct -}); - -test('upload with server side encryption AES256 header', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - - aws.mockS3.getBucketEncryption = mockedApiResult({ - ServerSideEncryptionConfiguration: { - Rules: [ - { - ApplyServerSideEncryptionByDefault: { - SSEAlgorithm: 'AES256', - }, - BucketKeyEnabled: false, - }, - ], - }, - }); - 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', - ContentType: 'application/octet-stream', - ServerSideEncryption: 'AES256', - })); - - // We'll just have to assume the contents are correct -}); - -test('upload with server side encryption aws:kms header and key id', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - - aws.mockS3.getBucketEncryption = mockedApiResult({ - ServerSideEncryptionConfiguration: { - Rules: [ - { - ApplyServerSideEncryptionByDefault: { - SSEAlgorithm: 'aws:kms', - KMSMasterKeyID: 'the-key-id', - }, - BucketKeyEnabled: false, - }, - ], - }, - }); - - 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', - ContentType: 'application/octet-stream', - ServerSideEncryption: 'aws:kms', - SSEKMSKeyId: 'the-key-id', - })); - - // We'll just have to assume the contents are correct -}); - -test('will only read bucketEncryption once even for multiple assets', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/types/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).toHaveBeenCalledTimes(2); - expect(aws.mockS3.getBucketEncryption).toHaveBeenCalledTimes(1); -}); - -test('no server side encryption header if access denied for bucket encryption', async () => { - const progressListener = new FakeListener(); - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws, progressListener }); - - aws.mockS3.getBucketEncryption = mockedApiFailure('AccessDenied', 'Access Denied'); - - 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.not.objectContaining({ - ServerSideEncryption: 'aws:kms', - })); - - expect(aws.mockS3.upload).toHaveBeenCalledWith(expect.not.objectContaining({ - ServerSideEncryption: 'AES256', - })); -}); - -test('correctly looks up content type', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/types/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.txt', - ContentType: 'text/plain', - })); - - expect(aws.mockS3.upload).toHaveBeenCalledWith(expect.objectContaining({ - Bucket: 'some_bucket', - Key: 'some_key.png', - ContentType: 'image/png', - })); - - // We'll just have to assume the contents are correct -}); - -test('upload file if new (list returns no key)', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); - 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('successful run does not need to query account ID', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); - aws.mockS3.upload = mockUpload('FILE_CONTENTS'); - - await pub.publish(); - - expect(aws.discoverCurrentAccount).not.toHaveBeenCalled(); - expect(aws.discoverTargetAccount).not.toHaveBeenCalled(); -}); - -test('correctly identify asset path if path is absolute', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/abs/cdk.out'), { aws }); - - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); - aws.mockS3.upload = mockUpload('FILE_CONTENTS'); - - await pub.publish(); - - expect(true).toBeTruthy(); // No exception, satisfy linter -}); - -describe('external assets', () => { - let pub: AssetPublishing; - beforeEach(() => { - pub = new AssetPublishing(AssetManifest.fromPath('/external/cdk.out'), { aws }); - }); - - test('do nothing if file exists already', async () => { - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: [{ Key: 'some_key' }] }); - - await pub.publish(); - - expect(aws.mockS3.listObjectsV2).toHaveBeenCalledWith(expect.objectContaining({ - Bucket: 'some_external_bucket', - Prefix: 'some_key', - MaxKeys: 1, - })); - }); - - test('upload external asset correctly', async () => { - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); - aws.mockS3.upload = mockUpload('ZIP_FILE_THAT_IS_DEFINITELY_NOT_EMPTY'); - const expectAllSpawns = mockSpawn({ commandLine: ['sometool'], stdout: ABS_PATH }); - - await pub.publish(); - - expect(aws.s3Client).toHaveBeenCalledWith(expect.objectContaining({ - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - })); - - expectAllSpawns(); - }); -}); diff --git a/packages/cdk-assets/test/manifest.test.ts b/packages/cdk-assets/test/manifest.test.ts deleted file mode 100644 index 605d6922b5e08..0000000000000 --- a/packages/cdk-assets/test/manifest.test.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { Manifest } from '@aws-cdk/cloud-assembly-schema'; -import * as mockfs from 'mock-fs'; -import { AssetManifest, DestinationIdentifier, DestinationPattern, DockerImageManifestEntry, FileManifestEntry } from '../lib'; - -beforeEach(() => { - mockfs({ - '/simple/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - asset1: { - type: 'file', - source: { path: 'S1' }, - destinations: { - dest1: { bucketName: 'D1', objectKey: 'X' }, - dest2: { bucketName: 'D2', objectKey: 'X' }, - }, - }, - }, - dockerImages: { - asset2: { - type: 'thing', - source: { directory: 'S2' }, - destinations: { - dest1: { repositoryName: 'D3', imageTag: 'X' }, - dest2: { repositoryName: 'D4', imageTag: 'X' }, - }, - }, - }, - }), - }); -}); - -afterEach(() => { - mockfs.restore(); -}); - -test('Can list manifest', () => { - const manifest = AssetManifest.fromPath('/simple/cdk.out'); - expect(manifest.list().join('\n')).toEqual(` -asset1 file {\"path\":\"S1\"} - ├ asset1:dest1 {\"bucketName\":\"D1\",\"objectKey\":\"X\"} - └ asset1:dest2 {\"bucketName\":\"D2\",\"objectKey\":\"X\"} -asset2 docker-image {\"directory\":\"S2\"} - ├ asset2:dest1 {\"repositoryName\":\"D3\",\"imageTag\":\"X\"} - └ asset2:dest2 {\"repositoryName\":\"D4\",\"imageTag\":\"X\"} -`.trim()); -}); - -test('.entries() iterates over all destinations', () => { - const manifest = AssetManifest.fromPath('/simple/cdk.out'); - - expect(manifest.entries).toEqual([ - new FileManifestEntry(new DestinationIdentifier('asset1', 'dest1'), { path: 'S1' }, { bucketName: 'D1', objectKey: 'X' }), - new FileManifestEntry(new DestinationIdentifier('asset1', 'dest2'), { path: 'S1' }, { bucketName: 'D2', objectKey: 'X' }), - new DockerImageManifestEntry(new DestinationIdentifier('asset2', 'dest1'), { directory: 'S2' }, { repositoryName: 'D3', imageTag: 'X' }), - new DockerImageManifestEntry(new DestinationIdentifier('asset2', 'dest2'), { directory: 'S2' }, { repositoryName: 'D4', imageTag: 'X' }), - ]); -}); - -test('can select by asset ID', () => { - const manifest = AssetManifest.fromPath('/simple/cdk.out'); - - const subset = manifest.select([DestinationPattern.parse('asset2')]); - - expect(subset.entries.map(e => f(e.genericDestination, 'repositoryName'))).toEqual(['D3', 'D4']); -}); - -test('can select by asset ID + destination ID', () => { - const manifest = AssetManifest.fromPath('/simple/cdk.out'); - - const subset = manifest.select([ - DestinationPattern.parse('asset1:dest1'), - DestinationPattern.parse('asset2:dest2'), - ]); - - expect(subset.entries.map(e => f(e.genericDestination, 'repositoryName', 'bucketName'))).toEqual(['D1', 'D4']); -}); - -test('can select by destination ID', () => { - const manifest = AssetManifest.fromPath('/simple/cdk.out'); - - const subset = manifest.select([ - DestinationPattern.parse(':dest1'), - ]); - - expect(subset.entries.map(e => f(e.genericDestination, 'repositoryName', 'bucketName'))).toEqual(['D1', 'D3']); -}); - -test('empty string is not a valid pattern', () => { - expect(() => { - DestinationPattern.parse(''); - }).toThrow(/Empty string is not a valid destination identifier/); -}); - -test('pattern must have two components', () => { - expect(() => { - DestinationPattern.parse('a:b:c'); - }).toThrow(/Asset identifier must contain at most 2/); -}); - -test('parse ASSET:* the same as ASSET and ASSET:', () => { - expect(DestinationPattern.parse('a:*')).toEqual(DestinationPattern.parse('a')); - expect(DestinationPattern.parse('a:*')).toEqual(DestinationPattern.parse('a:')); -}); - -test('parse *:DEST the same as :DEST', () => { - expect(DestinationPattern.parse('*:a')).toEqual(DestinationPattern.parse(':a')); -}); - -function f(obj: unknown, ...keys: string[]): any { - for (const k of keys) { - if (typeof obj === 'object' && obj !== null && k in obj) { - return (obj as any)[k]; - } - } - return undefined; -} diff --git a/packages/cdk-assets/test/mock-aws.ts b/packages/cdk-assets/test/mock-aws.ts deleted file mode 100644 index 10cb26da99727..0000000000000 --- a/packages/cdk-assets/test/mock-aws.ts +++ /dev/null @@ -1,74 +0,0 @@ -jest.mock('aws-sdk'); -import * as AWS from 'aws-sdk'; - -export function mockAws() { - const mockEcr = new AWS.ECR(); - const mockS3 = new AWS.S3(); - const mockSecretsManager = new AWS.SecretsManager(); - - // Sane defaults which can be overridden - mockS3.getBucketLocation = mockedApiResult({}); - mockS3.getBucketEncryption = mockedApiResult({}); - mockEcr.describeRepositories = mockedApiResult({ - repositories: [ - { - repositoryUri: '12345.amazonaws.com/repo', - }, - ], - }); - mockSecretsManager.getSecretValue = mockedApiFailure('NotImplemented', 'You need to supply an implementation for getSecretValue'); - - return { - mockEcr, - mockS3, - mockSecretsManager, - discoverPartition: jest.fn(() => Promise.resolve('swa')), - discoverCurrentAccount: jest.fn(() => Promise.resolve({ accountId: 'current_account', partition: 'swa' })), - discoverDefaultRegion: jest.fn(() => Promise.resolve('current_region')), - discoverTargetAccount: jest.fn(() => Promise.resolve({ accountId: 'target_account', partition: 'swa' })), - ecrClient: jest.fn(() => Promise.resolve(mockEcr)), - s3Client: jest.fn(() => Promise.resolve(mockS3)), - secretsManagerClient: jest.fn(() => Promise.resolve(mockSecretsManager)), - }; -} - -export function errorWithCode(code: string, message: string) { - const ret = new Error(message); - (ret as any).code = code; - return ret; -} - -export function mockedApiResult(returnValue: any) { - return jest.fn().mockReturnValue({ - promise: jest.fn().mockResolvedValue(returnValue), - }); -} - -export function mockedApiFailure(code: string, message: string) { - return jest.fn().mockReturnValue({ - promise: jest.fn().mockRejectedValue(errorWithCode(code, message)), - }); -} - -/** - * Mock upload, draining the stream that we get before returning - * so no race conditions happen with the uninstallation of mock-fs. - */ -export function mockUpload(expectContent?: string) { - return jest.fn().mockImplementation(request => ({ - promise: () => new Promise((ok, ko) => { - const didRead = new Array(); - - const bodyStream: NodeJS.ReadableStream = request.Body; - bodyStream.on('data', (chunk) => { didRead.push(chunk.toString()); }); // This listener must exist - bodyStream.on('error', ko); - bodyStream.on('close', () => { - const actualContent = didRead.join(''); - if (expectContent !== undefined && expectContent !== actualContent) { - throw new Error(`Expected to read '${expectContent}' but read: '${actualContent}'`); - } - ok(); - }); - }), - })); -} diff --git a/packages/cdk-assets/test/mock-child_process.ts b/packages/cdk-assets/test/mock-child_process.ts deleted file mode 100644 index 2cb513e24fff7..0000000000000 --- a/packages/cdk-assets/test/mock-child_process.ts +++ /dev/null @@ -1,69 +0,0 @@ -import * as child_process from 'child_process'; -import * as events from 'events'; - -if (!(child_process as any).spawn.mockImplementationOnce) { - throw new Error('Call "jest.mock(\'child_process\');" at the top of the test file!'); -} - -export interface Invocation { - commandLine: string[]; - cwd?: string; - exitCode?: number; - stdout?: string; - - /** - * Only match a prefix of the command (don't care about the details of the arguments) - */ - prefix?: boolean; -} - -export function mockSpawn(...invocations: Invocation[]): () => void { - let mock = (child_process.spawn as any); - for (const _invocation of invocations) { - const invocation = _invocation; // Mirror into variable for closure - mock = mock.mockImplementationOnce((binary: string, args: string[], options: child_process.SpawnOptions) => { - if (invocation.prefix) { - // Match command line prefix - expect([binary, ...args].slice(0, invocation.commandLine.length)).toEqual(invocation.commandLine); - } else { - // Match full command line - expect([binary, ...args]).toEqual(invocation.commandLine); - } - - if (invocation.cwd != null) { - expect(options.cwd).toBe(invocation.cwd); - } - - const child: any = new events.EventEmitter(); - child.stdin = new events.EventEmitter(); - child.stdin.write = jest.fn(); - child.stdin.end = jest.fn(); - child.stdout = new events.EventEmitter(); - child.stderr = new events.EventEmitter(); - - if (invocation.stdout) { - mockEmit(child.stdout, 'data', Buffer.from(invocation.stdout)); - } - mockEmit(child, 'close', invocation.exitCode ?? 0); - - return child; - }); - } - - mock.mockImplementation((binary: string, args: string[], _options: any) => { - throw new Error(`Did not expect call of ${JSON.stringify([binary, ...args])}`); - }); - - return () => { - expect(mock).toHaveBeenCalledTimes(invocations.length); - }; -} - -/** - * Must do this on the next tick, as emitter.emit() expects all listeners to have been attached already - */ -function mockEmit(emitter: events.EventEmitter, event: string, data: any) { - setImmediate(() => { - emitter.emit(event, data); - }); -} diff --git a/packages/cdk-assets/test/placeholders.test.ts b/packages/cdk-assets/test/placeholders.test.ts deleted file mode 100644 index 87944ca673c32..0000000000000 --- a/packages/cdk-assets/test/placeholders.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Manifest } from '@aws-cdk/cloud-assembly-schema'; -import * as mockfs from 'mock-fs'; -import { mockAws, mockedApiResult } from './mock-aws'; -import { AssetManifest, AssetPublishing } from '../lib'; - -let aws: ReturnType; -beforeEach(() => { - mockfs({ - '/simple/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - fileAsset: { - type: 'file', - source: { - path: 'some_file', - }, - destinations: { - theDestination: { - // Absence of region - assumeRoleArn: 'arn:aws:role-${AWS::AccountId}', - bucketName: 'some_bucket-${AWS::AccountId}-${AWS::Region}', - objectKey: 'some_key-${AWS::AccountId}-${AWS::Region}', - }, - }, - }, - }, - dockerImages: { - dockerAsset: { - type: 'docker-image', - source: { - directory: 'dockerdir', - }, - destinations: { - theDestination: { - // Explicit region - region: 'explicit_region', - assumeRoleArn: 'arn:aws:role-${AWS::AccountId}', - repositoryName: 'repo-${AWS::AccountId}-${AWS::Region}', - imageTag: 'abcdef', - }, - }, - }, - }, - }), - '/simple/cdk.out/some_file': 'FILE_CONTENTS', - }); - - aws = mockAws(); -}); - -afterEach(() => { - mockfs.restore(); -}); - -test('check that placeholders are replaced', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws }); - aws.mockS3.getBucketLocation = mockedApiResult({}); - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: [{ Key: 'some_key-current_account-current_region' }] }); - aws.mockEcr.describeImages = mockedApiResult({ /* No error == image exists */ }); - - await pub.publish(); - - expect(aws.s3Client).toHaveBeenCalledWith(expect.objectContaining({ - assumeRoleArn: 'arn:aws:role-current_account', - })); - - expect(aws.ecrClient).toHaveBeenCalledWith(expect.objectContaining({ - region: 'explicit_region', - assumeRoleArn: 'arn:aws:role-current_account', - })); - - expect(aws.mockS3.listObjectsV2).toHaveBeenCalledWith(expect.objectContaining({ - Bucket: 'some_bucket-current_account-current_region', - Prefix: 'some_key-current_account-current_region', - MaxKeys: 1, - })); - - expect(aws.mockEcr.describeImages).toHaveBeenCalledWith(expect.objectContaining({ - imageIds: [{ imageTag: 'abcdef' }], - repositoryName: 'repo-current_account-explicit_region', - })); -}); diff --git a/packages/cdk-assets/test/private/docker-credentials.test.ts b/packages/cdk-assets/test/private/docker-credentials.test.ts deleted file mode 100644 index c7e6957f9bc66..0000000000000 --- a/packages/cdk-assets/test/private/docker-credentials.test.ts +++ /dev/null @@ -1,220 +0,0 @@ -import * as os from 'os'; -import * as path from 'path'; -import * as mockfs from 'mock-fs'; -import { cdkCredentialsConfig, cdkCredentialsConfigFile, DockerCredentialsConfig, fetchDockerLoginCredentials } from '../../lib/private/docker-credentials'; -import { mockAws, mockedApiFailure, mockedApiResult } from '../mock-aws'; - -const _ENV = process.env; - -let aws: ReturnType; -beforeEach(() => { - jest.resetModules(); - jest.resetAllMocks(); - - aws = mockAws(); - - process.env = { ..._ENV }; -}); - -afterEach(() => { - mockfs.restore(); - process.env = _ENV; -}); - -describe('cdkCredentialsConfigFile', () => { - test('Can be overridden by CDK_DOCKER_CREDS_FILE', () => { - const credsFile = '/tmp/insertfilenamehere_cdk_config.json'; - process.env.CDK_DOCKER_CREDS_FILE = credsFile; - - expect(cdkCredentialsConfigFile()).toEqual(credsFile); - }); - - test('Uses homedir if no process env is set', () => { - expect(cdkCredentialsConfigFile()).toEqual(path.join(os.userInfo().homedir, '.cdk', 'cdk-docker-creds.json')); - }); -}); - -describe('cdkCredentialsConfig', () => { - const credsFile = '/tmp/foo/bar/does/not/exist/config.json'; - beforeEach(() => { process.env.CDK_DOCKER_CREDS_FILE = credsFile; }); - - test('returns undefined if no config exists', () => { - expect(cdkCredentialsConfig()).toBeUndefined(); - }); - - test('returns parsed config if it exists', () => { - mockfs({ - [credsFile]: JSON.stringify({ - version: '0.1', - domainCredentials: { - 'test1.example.com': { secretsManagerSecretId: 'mySecret' }, - 'test2.example.com': { ecrRepository: 'arn:aws:ecr:bar' }, - }, - }), - }); - - const config = cdkCredentialsConfig(); - expect(config).toBeDefined(); - expect(config?.version).toEqual('0.1'); - expect(config?.domainCredentials['test1.example.com']?.secretsManagerSecretId).toEqual('mySecret'); - expect(config?.domainCredentials['test2.example.com']?.ecrRepository).toEqual('arn:aws:ecr:bar'); - }); -}); - -describe('fetchDockerLoginCredentials', () => { - let config: DockerCredentialsConfig; - - beforeEach(() => { - config = { - version: '0.1', - domainCredentials: { - 'misconfigured.example.com': {}, - 'secret.example.com': { secretsManagerSecretId: 'mySecret' }, - 'secretwithrole.example.com': { - secretsManagerSecretId: 'mySecret', - assumeRoleArn: 'arn:aws:iam::0123456789012:role/my-role', - }, - 'secretwithcustomfields.example.com': { - secretsManagerSecretId: 'mySecret', - secretsUsernameField: 'name', - secretsPasswordField: 'apiKey', - assumeRoleArn: 'arn:aws:iam::0123456789012:role/my-role', - }, - 'ecr.example.com': { ecrRepository: true }, - 'ecrwithrole.example.com': { - ecrRepository: true, - assumeRoleArn: 'arn:aws:iam::0123456789012:role/my-role', - }, - }, - }; - }); - - test('throws on unknown domain', async () => { - await expect(fetchDockerLoginCredentials(aws, config, 'unknowndomain.example.com')).rejects.toThrow(/unknown domain/); - }); - - test('throws on misconfigured domain (no ECR or SM)', async () => { - await expect(fetchDockerLoginCredentials(aws, config, 'misconfigured.example.com')).rejects.toThrow(/unknown credential type/); - }); - - test('does not throw on correctly configured raw domain', async () => { - mockSecretWithSecretString({ username: 'secretUser', secret: 'secretPass' }); - - await expect(fetchDockerLoginCredentials(aws, config, 'https://secret.example.com/v1/')).resolves.toBeTruthy(); - }); - - describe('SecretsManager', () => { - test('returns the credentials successfully if configured correctly - domain', async () => { - mockSecretWithSecretString({ username: 'secretUser', secret: 'secretPass' }); - - const creds = await fetchDockerLoginCredentials(aws, config, 'secret.example.com'); - - expect(creds).toEqual({ Username: 'secretUser', Secret: 'secretPass' }); - }); - - test('returns the credentials successfully if configured correctly - raw domain', async () => { - mockSecretWithSecretString({ username: 'secretUser', secret: 'secretPass' }); - - const creds = await fetchDockerLoginCredentials(aws, config, 'https://secret.example.com'); - - expect(creds).toEqual({ Username: 'secretUser', Secret: 'secretPass' }); - }); - - test('throws when SecretsManager returns an error', async () => { - const errMessage = "Secrets Manager can't find the specified secret."; - aws.mockSecretsManager.getSecretValue = mockedApiFailure('ResourceNotFoundException', errMessage); - - await expect(fetchDockerLoginCredentials(aws, config, 'secret.example.com')).rejects.toThrow(errMessage); - }); - - test('supports assuming a role', async () => { - mockSecretWithSecretString({ username: 'secretUser', secret: 'secretPass' }); - - const creds = await fetchDockerLoginCredentials(aws, config, 'secretwithrole.example.com'); - - expect(creds).toEqual({ Username: 'secretUser', Secret: 'secretPass' }); - expect(aws.secretsManagerClient).toHaveBeenCalledWith({ assumeRoleArn: 'arn:aws:iam::0123456789012:role/my-role' }); - }); - - test('supports configuring the secret fields', async () => { - mockSecretWithSecretString({ name: 'secretUser', apiKey: '01234567' }); - - const creds = await fetchDockerLoginCredentials(aws, config, 'secretwithcustomfields.example.com'); - - expect(creds).toEqual({ Username: 'secretUser', Secret: '01234567' }); - }); - - test('throws when secret does not have the correct fields - key/value', async () => { - mockSecretWithSecretString({ principal: 'foo', credential: 'bar' }); - - await expect(fetchDockerLoginCredentials(aws, config, 'secret.example.com')).rejects.toThrow(/malformed secret string/); - }); - - test('throws when secret does not have the correct fields - plaintext', async () => { - mockSecretWithSecretString('myAPIKey'); - - await expect(fetchDockerLoginCredentials(aws, config, 'secret.example.com')).rejects.toThrow(/malformed secret string/); - }); - }); - - describe('ECR getAuthorizationToken', () => { - test('returns the credentials successfully', async () => { - mockEcrAuthorizationData(Buffer.from('myFoo:myBar', 'utf-8').toString('base64')); - - const creds = await fetchDockerLoginCredentials(aws, config, 'ecr.example.com'); - - expect(creds).toEqual({ Username: 'myFoo', Secret: 'myBar' }); - }); - - test('throws if ECR errors', async () => { - aws.mockEcr.getAuthorizationToken = mockedApiFailure('ServerException', 'uhoh'); - - await expect(fetchDockerLoginCredentials(aws, config, 'ecr.example.com')).rejects.toThrow(/uhoh/); - }); - - test('supports assuming a role', async () => { - mockEcrAuthorizationData(Buffer.from('myFoo:myBar', 'utf-8').toString('base64')); - - const creds = await fetchDockerLoginCredentials(aws, config, 'ecrwithrole.example.com'); - - expect(creds).toEqual({ Username: 'myFoo', Secret: 'myBar' }); - expect(aws.ecrClient).toHaveBeenCalledWith({ assumeRoleArn: 'arn:aws:iam::0123456789012:role/my-role' }); - }); - - test('throws if ECR returns no authData', async () => { - aws.mockEcr.getAuthorizationToken = mockedApiResult({ authorizationData: [] }); - - await expect(fetchDockerLoginCredentials(aws, config, 'ecr.example.com')).rejects.toThrow(/No authorization data received from ECR/); - }); - - test('throws if ECR authData is in an incorrect format', async () => { - mockEcrAuthorizationData('notabase64encodedstring'); - - await expect(fetchDockerLoginCredentials(aws, config, 'ecr.example.com')).rejects.toThrow(/unexpected ECR authData format/); - }); - }); - -}); - -function mockSecretWithSecretString(secretString: any) { - aws.mockSecretsManager.getSecretValue = mockedApiResult({ - ARN: 'arn:aws:secretsmanager:eu-west-1:0123456789012:secret:mySecret', - Name: 'mySecret', - VersionId: 'fa81fe61-c167-4aca-969e-4d8df74d4814', - SecretString: JSON.stringify(secretString), - VersionStages: [ - 'AWSCURRENT', - ], - }); -} - -function mockEcrAuthorizationData(authorizationToken: string) { - aws.mockEcr.getAuthorizationToken = mockedApiResult({ - authorizationData: [ - { - authorizationToken, - proxyEndpoint: 'https://0123456789012.dkr.ecr.eu-west-1.amazonaws.com', - }, - ], - }); -} diff --git a/packages/cdk-assets/test/private/docker.test.ts b/packages/cdk-assets/test/private/docker.test.ts deleted file mode 100644 index 40c37ca35f271..0000000000000 --- a/packages/cdk-assets/test/private/docker.test.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Docker } from '../../lib/private/docker'; -import { ShellOptions, ProcessFailedError } from '../../lib/private/shell'; - -type ShellExecuteMock = jest.SpyInstance, Parameters>; - -describe('Docker', () => { - describe('exists', () => { - let docker: Docker; - - const makeShellExecuteMock = ( - fn: (params: string[]) => void, - ): ShellExecuteMock => - jest.spyOn<{ execute: Docker['execute'] }, 'execute'>(Docker.prototype as any, 'execute').mockImplementation( - async (params: string[], _options?: ShellOptions) => fn(params), - ); - - afterEach(() => { - jest.restoreAllMocks(); - }); - - beforeEach(() => { - docker = new Docker(); - }); - - test('returns true when image inspect command does not throw', async () => { - const spy = makeShellExecuteMock(() => undefined); - - const imageExists = await docker.exists('foo'); - - expect(imageExists).toBe(true); - expect(spy.mock.calls[0][0]).toEqual(['inspect', 'foo']); - }); - - test('throws when an arbitrary error is caught', async () => { - makeShellExecuteMock(() => { - throw new Error(); - }); - - await expect(docker.exists('foo')).rejects.toThrow(); - }); - - test('throws when the error is a shell failure but the exit code is unrecognized', async () => { - makeShellExecuteMock(() => { - throw new (class extends Error implements ProcessFailedError { - public readonly code = 'PROCESS_FAILED' - public readonly exitCode = 47 - public readonly signal = null - - constructor() { - super('foo'); - } - }); - }); - - await expect(docker.exists('foo')).rejects.toThrow(); - }); - - test('returns false when the error is a shell failure and the exit code is 1 (Docker)', async () => { - makeShellExecuteMock(() => { - throw new (class extends Error implements ProcessFailedError { - public readonly code = 'PROCESS_FAILED' - public readonly exitCode = 1 - public readonly signal = null - - constructor() { - super('foo'); - } - }); - }); - - const imageExists = await docker.exists('foo'); - - expect(imageExists).toBe(false); - }); - - test('returns false when the error is a shell failure and the exit code is 125 (Podman)', async () => { - makeShellExecuteMock(() => { - throw new (class extends Error implements ProcessFailedError { - public readonly code = 'PROCESS_FAILED' - public readonly exitCode = 125 - public readonly signal = null - - constructor() { - super('foo'); - } - }); - }); - - const imageExists = await docker.exists('foo'); - - expect(imageExists).toBe(false); - }); - }); -}); diff --git a/packages/cdk-assets/test/progress.test.ts b/packages/cdk-assets/test/progress.test.ts deleted file mode 100644 index 2cca80311942a..0000000000000 --- a/packages/cdk-assets/test/progress.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Manifest } from '@aws-cdk/cloud-assembly-schema'; -import * as mockfs from 'mock-fs'; -import { FakeListener } from './fake-listener'; -import { mockAws, mockedApiResult, mockUpload } from './mock-aws'; -import { AssetManifest, AssetPublishing } from '../lib'; - -let aws: ReturnType; -beforeEach(() => { - mockfs({ - '/simple/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - theAsset: { - source: { - path: 'some_file', - }, - destinations: { - theDestination1: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - bucketName: 'some_bucket', - objectKey: 'some_key', - }, - theDestination2: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - bucketName: 'some_bucket', - objectKey: 'some_key2', - }, - }, - }, - }, - }), - '/simple/cdk.out/some_file': 'FILE_CONTENTS', - }); - - aws = mockAws(); - - // Accept all S3 uploads as new - aws.mockS3.getBucketLocation = mockedApiResult({}); - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); - aws.mockS3.upload = mockUpload(); -}); - -afterEach(() => { - mockfs.restore(); -}); - -test('test listener', async () => { - const progressListener = new FakeListener(); - - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws, progressListener }); - await pub.publish(); - - const allMessages = progressListener.messages.join('\n'); - - // Log mentions asset/destination ids - expect(allMessages).toContain('theAsset:theDestination1'); - expect(allMessages).toContain('theAsset:theDestination2'); -}); - -test('test publishing in parallel', async () => { - const progressListener = new FakeListener(); - - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws, progressListener, publishInParallel: true }); - await pub.publish(); - - const allMessages = progressListener.messages.join('\n'); - - // Log mentions asset/destination ids - expect(allMessages).toContain('theAsset:theDestination1'); - expect(allMessages).toContain('theAsset:theDestination2'); -}); - -test('test abort', async () => { - const progressListener = new FakeListener(true); - - const pub = new AssetPublishing(AssetManifest.fromPath('/simple/cdk.out'), { aws, progressListener }); - await pub.publish(); - - const allMessages = progressListener.messages.join('\n'); - - // We never get to asset 2 - expect(allMessages).not.toContain('theAsset:theDestination2'); -}); \ No newline at end of file diff --git a/packages/cdk-assets/test/test-archive-follow/data/one.txt b/packages/cdk-assets/test/test-archive-follow/data/one.txt deleted file mode 100644 index 56a6051ca2b02..0000000000000 --- a/packages/cdk-assets/test/test-archive-follow/data/one.txt +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/packages/cdk-assets/test/test-archive-follow/linked/two.txt b/packages/cdk-assets/test/test-archive-follow/linked/two.txt deleted file mode 100644 index d8263ee986059..0000000000000 --- a/packages/cdk-assets/test/test-archive-follow/linked/two.txt +++ /dev/null @@ -1 +0,0 @@ -2 \ No newline at end of file diff --git a/packages/cdk-assets/test/test-archive/executable.txt b/packages/cdk-assets/test/test-archive/executable.txt deleted file mode 100755 index e69de29bb2d1d..0000000000000 diff --git a/packages/cdk-assets/test/test-archive/file1.txt b/packages/cdk-assets/test/test-archive/file1.txt deleted file mode 100644 index 7bb7edbd4b634..0000000000000 --- a/packages/cdk-assets/test/test-archive/file1.txt +++ /dev/null @@ -1 +0,0 @@ -I am file1 \ No newline at end of file diff --git a/packages/cdk-assets/test/test-archive/file2.txt b/packages/cdk-assets/test/test-archive/file2.txt deleted file mode 100644 index ccb69856e7157..0000000000000 --- a/packages/cdk-assets/test/test-archive/file2.txt +++ /dev/null @@ -1,2 +0,0 @@ -I am file2 -BLA! \ No newline at end of file diff --git a/packages/cdk-assets/test/test-archive/subdir/file3.txt b/packages/cdk-assets/test/test-archive/subdir/file3.txt deleted file mode 100644 index 976606ef5a8ac..0000000000000 --- a/packages/cdk-assets/test/test-archive/subdir/file3.txt +++ /dev/null @@ -1 +0,0 @@ -I am in a subdirectory diff --git a/packages/cdk-assets/test/util.test.ts b/packages/cdk-assets/test/util.test.ts deleted file mode 100644 index 8e498076913f2..0000000000000 --- a/packages/cdk-assets/test/util.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { createCriticalSection } from '../lib/private/util'; - -test('critical section', async () => { - // GIVEN - const criticalSection = createCriticalSection(); - - // WHEN - const arr = new Array(); - void criticalSection(async () => { - await new Promise(res => setTimeout(res, 500)); - arr.push('first'); - }); - await criticalSection(async () => { - arr.push('second'); - }); - - // THEN - expect(arr).toEqual([ - 'first', - 'second', - ]); -}); - -test('exceptions in critical sections', async () => { - // GIVEN - const criticalSection = createCriticalSection(); - - // WHEN/THEN - await expect(() => criticalSection(async () => { - throw new Error('Thrown'); - })).rejects.toThrow('Thrown'); -}); \ No newline at end of file diff --git a/packages/cdk-assets/test/zipping.test.ts b/packages/cdk-assets/test/zipping.test.ts deleted file mode 100644 index 71651289070b8..0000000000000 --- a/packages/cdk-assets/test/zipping.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -// Separate test file since the archiving module doesn't work well with 'mock-fs' -import { bockfs } from '@aws-cdk/cdk-build-tools'; -import { Manifest } from '@aws-cdk/cloud-assembly-schema'; -import { mockAws, mockedApiResult, mockUpload } from './mock-aws'; -import { AssetManifest, AssetPublishing } from '../lib'; - -let aws: ReturnType; -beforeEach(() => { - bockfs({ - '/simple/cdk.out/assets.json': JSON.stringify({ - version: Manifest.version(), - files: { - theAsset: { - source: { - path: 'some_dir', - packaging: 'zip', - }, - destinations: { - theDestination: { - region: 'us-north-50', - assumeRoleArn: 'arn:aws:role', - bucketName: 'some_bucket', - objectKey: 'some_key', - }, - }, - }, - }, - }), - '/simple/cdk.out/some_dir/some_file': 'FILE_CONTENTS', - }); - - aws = mockAws(); - - // Accept all S3 uploads as new - aws.mockS3.listObjectsV2 = mockedApiResult({ Contents: undefined }); - aws.mockS3.upload = mockUpload(); -}); - -afterEach(() => { - bockfs.restore(); -}); - -test('Take a zipped upload', async () => { - const pub = new AssetPublishing(AssetManifest.fromPath(bockfs.path('/simple/cdk.out')), { aws }); - - await pub.publish(); - - expect(aws.mockS3.upload).toHaveBeenCalledWith(expect.objectContaining({ - Bucket: 'some_bucket', - Key: 'some_key', - ContentType: 'application/zip', - })); -}); diff --git a/packages/cdk-assets/tsconfig.json b/packages/cdk-assets/tsconfig.json deleted file mode 100644 index b238d46998d26..0000000000000 --- a/packages/cdk-assets/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "module": "commonjs", - "lib": ["es2020", "dom"], - "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", - "**/*.d.ts", - "lib/init-templates/*/*/add-project.hook.ts" - ], - "exclude": [ - "lib/init-templates/*/typescript/**/*.ts" - ] -} - From 4f1fe4919168e2564eb9d7fd6c1347836964ef56 Mon Sep 17 00:00:00 2001 From: Kendra Neil <53584728+TheRealAmazonKendra@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:40:40 -0700 Subject: [PATCH 2/2] cleanup references to cdk-assets --- .github/workflows/request-cli-integ-test.yml | 3 - lerna.json | 3 +- package.json | 3 +- .../cli-lib-alpha/THIRD_PARTY_LICENSES | 83 +- packages/@aws-cdk/cli-lib-alpha/package.json | 4 +- .../integ-runner/THIRD_PARTY_LICENSES | 2700 ++++++++++++++--- .../lib/runner/private/cloud-assembly.ts | 2 +- packages/@aws-cdk/integ-runner/package.json | 5 +- packages/aws-cdk/THIRD_PARTY_LICENSES | 17 + packages/aws-cdk/package.json | 7 +- packages/aws-cdk/tsconfig.json | 3 - tools/@aws-cdk/pkglint/lib/rules.ts | 2 - yarn.lock | 76 +- 13 files changed, 2439 insertions(+), 469 deletions(-) diff --git a/.github/workflows/request-cli-integ-test.yml b/.github/workflows/request-cli-integ-test.yml index fcac8f5814c46..56c7896c1c11e 100644 --- a/.github/workflows/request-cli-integ-test.yml +++ b/.github/workflows/request-cli-integ-test.yml @@ -27,9 +27,6 @@ jobs: - packages/aws-cdk/bin/** - packages/aws-cdk/lib/** - packages/aws-cdk/test/** - - packages/cdk-assets/bin/** - - packages/cdk-assets/lib/** - - packages/cdk-assets/test/** - packages/aws-cdk-lib/cloud-assembly-schema/lib/** - packages/aws-cdk-lib/cloud-assembly-schema/schema/** - packages/aws-cdk-lib/cloud-assembly-schema/scripts/** diff --git a/lerna.json b/lerna.json index 9a431094ac9a7..45baeccd2d79d 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,6 @@ "npmClient": "yarn", "packages": [ "packages/aws-cdk-lib", - "packages/cdk-assets", "packages/aws-cdk", "packages/cdk", "packages/@aws-cdk/*", @@ -25,4 +24,4 @@ "rejectCycles": true, "version": "0.0.0", "$schema": "node_modules/lerna/schemas/lerna-schema.json" -} +} \ No newline at end of file diff --git a/package.json b/package.json index 9e90622eb6d65..be322f9167b39 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "packages/aws-cdk-lib", "packages/aws-cdk", "packages/cdk", - "packages/cdk-assets", "packages/@aws-cdk/*", "packages/awslint", "packages/@aws-cdk-testing/*", @@ -177,4 +176,4 @@ "dependencies": { "string-width": "^4.2.3" } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES b/packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES index 2c9a5a75dad60..40161f1c5bab2 100644 --- a/packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES +++ b/packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES @@ -207,7 +207,7 @@ The @aws-cdk/cli-lib-alpha package includes the following third-party software/l ---------------- -** @jsii/check-node@1.97.0 - https://www.npmjs.com/package/@jsii/check-node/v/1.97.0 | Apache-2.0 +** @jsii/check-node@1.101.0 - https://www.npmjs.com/package/@jsii/check-node/v/1.101.0 | Apache-2.0 jsii Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -266,7 +266,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------- -** ajv@8.12.0 - https://www.npmjs.com/package/ajv/v/8.12.0 | MIT +** ajv@8.16.0 - https://www.npmjs.com/package/ajv/v/8.16.0 | MIT The MIT License (MIT) Copyright (c) 2015-2021 Evgeny Poberezkin @@ -493,7 +493,17 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE ---------------- -** aws-sdk@2.1596.0 - https://www.npmjs.com/package/aws-sdk/v/2.1596.0 | Apache-2.0 +** aws-sdk@2.1648.0 - https://www.npmjs.com/package/aws-sdk/v/2.1648.0 | Apache-2.0 +AWS SDK for JavaScript +Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +This product includes software developed at +Amazon Web Services, Inc. (http://aws.amazon.com/). + + +---------------- + +** aws-sdk@2.1649.0 - https://www.npmjs.com/package/aws-sdk/v/2.1649.0 | Apache-2.0 AWS SDK for JavaScript Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -601,10 +611,10 @@ SOFTWARE. ---------------- -** braces@3.0.2 - https://www.npmjs.com/package/braces/v/3.0.2 | MIT +** braces@3.0.3 - https://www.npmjs.com/package/braces/v/3.0.3 | MIT The MIT License (MIT) -Copyright (c) 2014-2018, Jon Schlinkert. +Copyright (c) 2014-present, Jon Schlinkert. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -691,7 +701,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ---------------- -** cdk-from-cfn@0.156.0 - https://www.npmjs.com/package/cdk-from-cfn/v/0.156.0 | MIT OR Apache-2.0 +** cdk-assets@2.147.1 - https://www.npmjs.com/package/cdk-assets/v/2.147.1 | Apache-2.0 +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + +---------------- + +** cdk-from-cfn@0.162.0 - https://www.npmjs.com/package/cdk-from-cfn/v/0.162.0 | MIT OR Apache-2.0 ---------------- @@ -1123,7 +1140,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------- -** debug@4.3.4 - https://www.npmjs.com/package/debug/v/4.3.4 | MIT +** debug@4.3.5 - https://www.npmjs.com/package/debug/v/4.3.5 | MIT (The MIT License) Copyright (c) 2014-2017 TJ Holowaychuk @@ -1390,7 +1407,7 @@ SOFTWARE. ---------------- -** fill-range@7.0.1 - https://www.npmjs.com/package/fill-range/v/7.0.1 | MIT +** fill-range@7.1.1 - https://www.npmjs.com/package/fill-range/v/7.1.1 | MIT The MIT License (MIT) Copyright (c) 2014-present, Jon Schlinkert. @@ -2315,26 +2332,6 @@ licenses; we recommend you read them, as their terms may differ from the terms above. ----------------- - -** lru-cache@6.0.0 - https://www.npmjs.com/package/lru-cache/v/6.0.0 | ISC -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------- ** lru-cache@7.18.3 - https://www.npmjs.com/package/lru-cache/v/7.18.3 | ISC @@ -3094,10 +3091,10 @@ THE SOFTWARE. ---------------- -** sax@1.3.0 - https://www.npmjs.com/package/sax/v/1.3.0 | ISC +** sax@1.4.1 - https://www.npmjs.com/package/sax/v/1.4.1 | ISC The ISC License -Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors +Copyright (c) 2010-2024 Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -3116,7 +3113,7 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. `String.fromCodePoint` by Mathias Bynens used according to terms of MIT License, as follows: -Copyright (c) 2010-2022 Mathias Bynens +Copyright (c) 2010-2024 Mathias Bynens Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -3140,7 +3137,7 @@ Copyright (c) 2010-2022 Mathias Bynens ---------------- -** semver@7.6.0 - https://www.npmjs.com/package/semver/v/7.6.0 | ISC +** semver@7.6.2 - https://www.npmjs.com/package/semver/v/7.6.2 | ISC The ISC License Copyright (c) Isaac Z. Schlueter and Contributors @@ -3545,7 +3542,7 @@ THE SOFTWARE. ---------------- -** tslib@2.6.2 - https://www.npmjs.com/package/tslib/v/2.6.2 | 0BSD +** tslib@2.6.3 - https://www.npmjs.com/package/tslib/v/2.6.3 | 0BSD Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any @@ -3723,26 +3720,6 @@ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ----------------- - -** yallist@4.0.0 - https://www.npmjs.com/package/yallist/v/4.0.0 | ISC -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ---------------- ** yaml@1.10.2 - https://www.npmjs.com/package/yaml/v/1.10.2 | ISC diff --git a/packages/@aws-cdk/cli-lib-alpha/package.json b/packages/@aws-cdk/cli-lib-alpha/package.json index b2cecc23c8d3c..86cb0dcc109e1 100644 --- a/packages/@aws-cdk/cli-lib-alpha/package.json +++ b/packages/@aws-cdk/cli-lib-alpha/package.json @@ -43,7 +43,7 @@ } }, "scripts": { - "attribute": "node-bundle validate --external=fsevents:optional --entrypoint=lib/index.js --fix --dont-attribute \"^@aws-cdk/|^cdk-assets$|^cdk-cli-wrapper$|^aws-cdk$\"", + "attribute": "node-bundle validate --external=fsevents:optional --entrypoint=lib/index.js --fix --dont-attribute \"^@aws-cdk/|^cdk-cli-wrapper$|^aws-cdk$\"", "awslint": "cdk-awslint", "build": "cdk-build", "build+extract": "yarn build && yarn rosetta:extract", @@ -122,4 +122,4 @@ }, "dependencies": {}, "peerDependencies": {} -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES b/packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES index 893b93cf2cd93..3cc06f4d2ddef 100644 --- a/packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES +++ b/packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES @@ -1,5 +1,212 @@ The @aws-cdk/integ-runner package includes the following third-party software/licensing: +** @cdklabs/tskb@0.0.3 - https://www.npmjs.com/package/@cdklabs/tskb/v/0.0.3 | Apache-2.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 [yyyy] [name of copyright owner] + + 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. + + +---------------- + ** ajv@8.16.0 - https://www.npmjs.com/package/ajv/v/8.16.0 | MIT The MIT License (MIT) @@ -75,36 +282,88 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ---------------- -** astral-regex@2.0.0 - https://www.npmjs.com/package/astral-regex/v/2.0.0 | MIT -MIT License +** archiver-utils@2.1.0 - https://www.npmjs.com/package/archiver-utils/v/2.1.0 | MIT +Copyright (c) 2015 Chris Talkington. -Copyright (c) Kevin Mårtensson (github.com/kevva) +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------- + +** archiver-utils@3.0.4 - https://www.npmjs.com/package/archiver-utils/v/3.0.4 | MIT +Copyright (c) 2015 Chris Talkington. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. ---------------- -** at-least-node@1.0.0 - https://www.npmjs.com/package/at-least-node/v/1.0.0 | ISC -The ISC License -Copyright (c) 2020 Ryan Zimmerman +** archiver@5.3.2 - https://www.npmjs.com/package/archiver/v/5.3.2 | MIT +Copyright (c) 2012-2014 Chris Talkington, contributors. -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. ---------------- -** binary-extensions@2.3.0 - https://www.npmjs.com/package/binary-extensions/v/2.3.0 | MIT +** astral-regex@2.0.0 - https://www.npmjs.com/package/astral-regex/v/2.0.0 | MIT MIT License -Copyright (c) Sindre Sorhus (https://sindresorhus.com) -Copyright (c) Paul Miller (https://paulmillr.com) +Copyright (c) Kevin Mårtensson (github.com/kevva) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -115,10 +374,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ---------------- -** braces@3.0.3 - https://www.npmjs.com/package/braces/v/3.0.3 | MIT -The MIT License (MIT) - -Copyright (c) 2014-present, Jon Schlinkert. +** async@3.2.5 - https://www.npmjs.com/package/async/v/3.2.5 | MIT +Copyright (c) 2010-2018 Caolan McMahon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -141,94 +398,36 @@ THE SOFTWARE. ---------------- -** chalk@4.1.2 - https://www.npmjs.com/package/chalk/v/4.1.2 | MIT -MIT License +** at-least-node@1.0.0 - https://www.npmjs.com/package/at-least-node/v/1.0.0 | ISC +The ISC License +Copyright (c) 2020 Ryan Zimmerman -Copyright (c) Sindre Sorhus (sindresorhus.com) +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------- + +** aws-sdk@2.1649.0 - https://www.npmjs.com/package/aws-sdk/v/2.1649.0 | Apache-2.0 +AWS SDK for JavaScript +Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +This product includes software developed at +Amazon Web Services, Inc. (http://aws.amazon.com/). ---------------- -** chokidar@3.6.0 - https://www.npmjs.com/package/chokidar/v/3.6.0 | MIT -The MIT License (MIT) +** balanced-match@1.0.2 - https://www.npmjs.com/package/balanced-match/v/1.0.2 | MIT -Copyright (c) 2012-2019 Paul Miller (https://paulmillr.com), Elan Shanker +---------------- -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the “Software”), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ----------------- - -** cliui@7.0.4 - https://www.npmjs.com/package/cliui/v/7.0.4 | ISC -Copyright (c) 2015, Contributors - -Permission to use, copy, modify, and/or distribute this software -for any purpose with or without fee is hereby granted, provided -that the above copyright notice and this permission notice -appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE -LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ----------------- - -** color-convert@2.0.1 - https://www.npmjs.com/package/color-convert/v/2.0.1 | MIT -Copyright (c) 2011-2016 Heather Arthur - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - - ----------------- +** binary-extensions@2.3.0 - https://www.npmjs.com/package/binary-extensions/v/2.3.0 | MIT +MIT License -** color-name@1.1.4 - https://www.npmjs.com/package/color-name/v/1.1.4 | MIT -The MIT License (MIT) -Copyright (c) 2015 Dmitry Ivanov +Copyright (c) Sindre Sorhus (https://sindresorhus.com) +Copyright (c) Paul Miller (https://paulmillr.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -236,85 +435,43 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------- - -** diff@5.2.0 - https://www.npmjs.com/package/diff/v/5.2.0 | BSD-3-Clause -BSD 3-Clause License - -Copyright (c) 2009-2015, Kevin Decker -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---------------- -** emoji-regex@8.0.0 - https://www.npmjs.com/package/emoji-regex/v/8.0.0 | MIT -Copyright Mathias Bynens - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - +** bl@4.1.0 - https://www.npmjs.com/package/bl/v/4.1.0 | MIT ---------------- -** escalade@3.1.2 - https://www.npmjs.com/package/escalade/v/3.1.2 | MIT +** brace-expansion@1.1.11 - https://www.npmjs.com/package/brace-expansion/v/1.1.11 | MIT MIT License -Copyright (c) Luke Edwards (lukeed.com) +Copyright (c) 2013 Julian Gruber -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. ---------------- -** fast-deep-equal@3.1.3 - https://www.npmjs.com/package/fast-deep-equal/v/3.1.3 | MIT +** brace-expansion@2.0.1 - https://www.npmjs.com/package/brace-expansion/v/2.0.1 | MIT MIT License -Copyright (c) 2017 Evgeny Poberezkin +Copyright (c) 2013 Julian Gruber Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -337,7 +494,7 @@ SOFTWARE. ---------------- -** fill-range@7.1.1 - https://www.npmjs.com/package/fill-range/v/7.1.1 | MIT +** braces@3.0.3 - https://www.npmjs.com/package/braces/v/3.0.3 | MIT The MIT License (MIT) Copyright (c) 2014-present, Jon Schlinkert. @@ -363,71 +520,38 @@ THE SOFTWARE. ---------------- -** fs-extra@9.1.0 - https://www.npmjs.com/package/fs-extra/v/9.1.0 | MIT -(The MIT License) - -Copyright (c) 2011-2017 JP Richardson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files -(the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, - merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - ----------------- - -** get-caller-file@2.0.5 - https://www.npmjs.com/package/get-caller-file/v/2.0.5 | ISC - ----------------- +** buffer-crc32@0.2.13 - https://www.npmjs.com/package/buffer-crc32/v/0.2.13 | MIT +The MIT License -** glob-parent@5.1.2 - https://www.npmjs.com/package/glob-parent/v/5.1.2 | ISC -The ISC License +Copyright (c) 2013 Brian J. Brennan -Copyright (c) 2015, 2019 Elan Shanker +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------- -** graceful-fs@4.2.11 - https://www.npmjs.com/package/graceful-fs/v/4.2.11 | ISC -The ISC License - -Copyright (c) 2011-2022 Isaac Z. Schlueter, Ben Noordhuis, and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +** cdk-assets@2.147.1 - https://www.npmjs.com/package/cdk-assets/v/2.147.1 | Apache-2.0 +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. ---------------- -** has-flag@4.0.0 - https://www.npmjs.com/package/has-flag/v/4.0.0 | MIT +** chalk@4.1.2 - https://www.npmjs.com/package/chalk/v/4.1.2 | MIT MIT License Copyright (c) Sindre Sorhus (sindresorhus.com) @@ -441,27 +565,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ---------------- -** is-binary-path@2.1.0 - https://www.npmjs.com/package/is-binary-path/v/2.1.0 | MIT -MIT License - -Copyright (c) 2019 Sindre Sorhus (https://sindresorhus.com), Paul Miller (https://paulmillr.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - ----------------- - -** is-extglob@2.1.1 - https://www.npmjs.com/package/is-extglob/v/2.1.1 | MIT +** chokidar@3.6.0 - https://www.npmjs.com/package/chokidar/v/3.6.0 | MIT The MIT License (MIT) -Copyright (c) 2014-2016, Jon Schlinkert +Copyright (c) 2012-2019 Paul Miller (https://paulmillr.com), Elan Shanker Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal +of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is @@ -470,7 +580,7 @@ furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER @@ -481,27 +591,1396 @@ THE SOFTWARE. ---------------- -** is-fullwidth-code-point@3.0.0 - https://www.npmjs.com/package/is-fullwidth-code-point/v/3.0.0 | MIT -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +** cliui@7.0.4 - https://www.npmjs.com/package/cliui/v/7.0.4 | ISC +Copyright (c) 2015, Contributors -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice +appear in all copies. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE +LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ---------------- -** is-glob@4.0.3 - https://www.npmjs.com/package/is-glob/v/4.0.3 | MIT -The MIT License (MIT) - -Copyright (c) 2014-2017, Jon Schlinkert. +** color-convert@2.0.1 - https://www.npmjs.com/package/color-convert/v/2.0.1 | MIT +Copyright (c) 2011-2016 Heather Arthur -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +---------------- + +** color-name@1.1.4 - https://www.npmjs.com/package/color-name/v/1.1.4 | MIT +The MIT License (MIT) +Copyright (c) 2015 Dmitry Ivanov + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +---------------- + +** compress-commons@4.1.2 - https://www.npmjs.com/package/compress-commons/v/4.1.2 | MIT +Copyright (c) 2014 Chris Talkington, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +---------------- + +** concat-map@0.0.1 - https://www.npmjs.com/package/concat-map/v/0.0.1 | MIT +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** core-util-is@1.0.3 - https://www.npmjs.com/package/core-util-is/v/1.0.3 | MIT +Copyright Node.js contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + + +---------------- + +** crc-32@1.2.2 - https://www.npmjs.com/package/crc-32/v/1.2.2 | Apache-2.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 (C) 2014-present SheetJS LLC + + 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. + + +---------------- + +** crc32-stream@4.0.3 - https://www.npmjs.com/package/crc32-stream/v/4.0.3 | MIT +Copyright (c) 2014 Chris Talkington, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +---------------- + +** diff@5.2.0 - https://www.npmjs.com/package/diff/v/5.2.0 | BSD-3-Clause +BSD 3-Clause License + +Copyright (c) 2009-2015, Kevin Decker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +---------------- + +** emoji-regex@8.0.0 - https://www.npmjs.com/package/emoji-regex/v/8.0.0 | MIT +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** end-of-stream@1.4.4 - https://www.npmjs.com/package/end-of-stream/v/1.4.4 | MIT +The MIT License (MIT) + +Copyright (c) 2014 Mathias Buus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------- + +** escalade@3.1.2 - https://www.npmjs.com/package/escalade/v/3.1.2 | MIT +MIT License + +Copyright (c) Luke Edwards (lukeed.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** fast-deep-equal@3.1.3 - https://www.npmjs.com/package/fast-deep-equal/v/3.1.3 | MIT +MIT License + +Copyright (c) 2017 Evgeny Poberezkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +---------------- + +** fill-range@7.1.1 - https://www.npmjs.com/package/fill-range/v/7.1.1 | MIT +The MIT License (MIT) + +Copyright (c) 2014-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** fs-constants@1.0.0 - https://www.npmjs.com/package/fs-constants/v/1.0.0 | MIT +The MIT License (MIT) + +Copyright (c) 2018 Mathias Buus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** fs-extra@9.1.0 - https://www.npmjs.com/package/fs-extra/v/9.1.0 | MIT +(The MIT License) + +Copyright (c) 2011-2017 JP Richardson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files +(the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** fs.realpath@1.0.0 - https://www.npmjs.com/package/fs.realpath/v/1.0.0 | ISC +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +---- + +This library bundles a version of the `fs.realpath` and `fs.realpathSync` +methods from Node.js v0.10 under the terms of the Node.js MIT license. + +Node's license follows, also included at the header of `old.js` which contains +the licensed code: + + Copyright Joyent, Inc. and other Node contributors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + +---------------- + +** get-caller-file@2.0.5 - https://www.npmjs.com/package/get-caller-file/v/2.0.5 | ISC + +---------------- + +** glob-parent@5.1.2 - https://www.npmjs.com/package/glob-parent/v/5.1.2 | ISC +The ISC License + +Copyright (c) 2015, 2019 Elan Shanker + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +---------------- + +** glob@7.2.3 - https://www.npmjs.com/package/glob/v/7.2.3 | ISC +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +## Glob Logo + +Glob's logo created by Tanya Brassie , licensed +under a Creative Commons Attribution-ShareAlike 4.0 International License +https://creativecommons.org/licenses/by-sa/4.0/ + + +---------------- + +** graceful-fs@4.2.11 - https://www.npmjs.com/package/graceful-fs/v/4.2.11 | ISC +The ISC License + +Copyright (c) 2011-2022 Isaac Z. Schlueter, Ben Noordhuis, and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +---------------- + +** has-flag@4.0.0 - https://www.npmjs.com/package/has-flag/v/4.0.0 | MIT +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** inflight@1.0.6 - https://www.npmjs.com/package/inflight/v/1.0.6 | ISC +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +---------------- + +** inherits@2.0.4 - https://www.npmjs.com/package/inherits/v/2.0.4 | ISC +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + + + +---------------- + +** is-binary-path@2.1.0 - https://www.npmjs.com/package/is-binary-path/v/2.1.0 | MIT +MIT License + +Copyright (c) 2019 Sindre Sorhus (https://sindresorhus.com), Paul Miller (https://paulmillr.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** is-extglob@2.1.1 - https://www.npmjs.com/package/is-extglob/v/2.1.1 | MIT +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** is-fullwidth-code-point@3.0.0 - https://www.npmjs.com/package/is-fullwidth-code-point/v/3.0.0 | MIT +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** is-glob@4.0.3 - https://www.npmjs.com/package/is-glob/v/4.0.3 | MIT +The MIT License (MIT) + +Copyright (c) 2014-2017, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** is-number@7.0.0 - https://www.npmjs.com/package/is-number/v/7.0.0 | MIT +The MIT License (MIT) + +Copyright (c) 2014-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** isarray@1.0.0 - https://www.npmjs.com/package/isarray/v/1.0.0 | MIT + +---------------- + +** jmespath@0.16.0 - https://www.npmjs.com/package/jmespath/v/0.16.0 | Apache-2.0 +Copyright 2014 James Saryerwinnie + +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. + + +---------------- + +** jsonfile@6.1.0 - https://www.npmjs.com/package/jsonfile/v/6.1.0 | MIT +(The MIT License) + +Copyright (c) 2012-2015, JP Richardson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files +(the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** jsonschema@1.4.1 - https://www.npmjs.com/package/jsonschema/v/1.4.1 | MIT +jsonschema is licensed under MIT license. + +Copyright (C) 2012-2015 Tom de Grunt + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +---------------- + +** lazystream@1.0.1 - https://www.npmjs.com/package/lazystream/v/1.0.1 | MIT +Copyright (c) 2013 J. Pommerening, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + + +---------------- + +** lodash.defaults@4.2.0 - https://www.npmjs.com/package/lodash.defaults/v/4.2.0 | MIT +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + + +---------------- + +** lodash.difference@4.5.0 - https://www.npmjs.com/package/lodash.difference/v/4.5.0 | MIT +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + + +---------------- + +** lodash.flatten@4.4.0 - https://www.npmjs.com/package/lodash.flatten/v/4.4.0 | MIT +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + + +---------------- + +** lodash.isplainobject@4.0.6 - https://www.npmjs.com/package/lodash.isplainobject/v/4.0.6 | MIT +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + + +---------------- + +** lodash.truncate@4.4.2 - https://www.npmjs.com/package/lodash.truncate/v/4.4.2 | MIT +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + + +---------------- + +** lodash.union@4.6.0 - https://www.npmjs.com/package/lodash.union/v/4.6.0 | MIT +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + + +---------------- + +** mime@2.6.0 - https://www.npmjs.com/package/mime/v/2.6.0 | MIT +The MIT License (MIT) + +Copyright (c) 2010 Benjamin Thomas, Robert Kieffer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** minimatch@3.1.2 - https://www.npmjs.com/package/minimatch/v/3.1.2 | ISC +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +---------------- + +** minimatch@5.1.6 - https://www.npmjs.com/package/minimatch/v/5.1.6 | ISC +The ISC License + +Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +---------------- + +** normalize-path@3.0.0 - https://www.npmjs.com/package/normalize-path/v/3.0.0 | MIT +The MIT License (MIT) + +Copyright (c) 2014-2018, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** once@1.4.0 - https://www.npmjs.com/package/once/v/1.4.0 | ISC +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +---------------- + +** path-is-absolute@1.0.1 - https://www.npmjs.com/package/path-is-absolute/v/1.0.1 | MIT +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** picomatch@2.3.1 - https://www.npmjs.com/package/picomatch/v/2.3.1 | MIT +The MIT License (MIT) + +Copyright (c) 2017-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is @@ -514,23 +1993,104 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ----------------- +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +---------------- + +** process-nextick-args@2.0.1 - https://www.npmjs.com/package/process-nextick-args/v/2.0.1 | MIT + +---------------- + +** readable-stream@2.3.8 - https://www.npmjs.com/package/readable-stream/v/2.3.8 | MIT +Node.js is licensed for use as follows: + +""" +Copyright Node.js contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" + +This license applies to parts of Node.js originating from the +https://github.com/joyent/node repository: + +""" +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" + + +---------------- + +** readable-stream@3.6.2 - https://www.npmjs.com/package/readable-stream/v/3.6.2 | MIT +Node.js is licensed for use as follows: + +""" +Copyright Node.js contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" -** is-number@7.0.0 - https://www.npmjs.com/package/is-number/v/7.0.0 | MIT -The MIT License (MIT) - -Copyright (c) 2014-present, Jon Schlinkert. +This license applies to parts of Node.js originating from the +https://github.com/joyent/node repository: +""" +Copyright Joyent, Inc. and other Node contributors. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in @@ -540,115 +2100,223 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" ---------------- -** jsonfile@6.1.0 - https://www.npmjs.com/package/jsonfile/v/6.1.0 | MIT -(The MIT License) +** readdir-glob@1.1.3 - https://www.npmjs.com/package/readdir-glob/v/1.1.3 | Apache-2.0 + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Copyright (c) 2012-2015, JP Richardson + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files -(the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, - merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + 1. Definitions. -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + "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. -** jsonschema@1.4.1 - https://www.npmjs.com/package/jsonschema/v/1.4.1 | MIT -jsonschema is licensed under MIT license. + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. -Copyright (C) 2012-2015 Tom de Grunt + "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. -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: + "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). -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + "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. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + "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. -** lodash.truncate@4.4.2 - https://www.npmjs.com/package/lodash.truncate/v/4.4.2 | MIT -Copyright jQuery Foundation and other contributors + 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. -Based on Underscore.js, copyright Jeremy Ashkenas, -DocumentCloud and Investigative Reporters & Editors + 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: -This software consists of voluntary contributions made by many -individuals. For exact contribution history, see the revision history -available at https://github.com/lodash/lodash + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and -The following license applies to all parts of this software except as -documented below: + (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 -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: + (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. -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. + 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. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + 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. -Copyright and related rights for sample code are waived via CC0. Sample -code is defined as all source code displayed within the prose of the -documentation. + 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. -CC0: http://creativecommons.org/publicdomain/zero/1.0/ + 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. -Files located in the node_modules and vendor directories are externally -maintained libraries used by this software which have their own -licenses; we recommend you read them, as their terms may differ from the -terms above. + 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 2020 Yann Armelin + + 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. ---------------- -** normalize-path@3.0.0 - https://www.npmjs.com/package/normalize-path/v/3.0.0 | MIT -The MIT License (MIT) +** readdirp@3.6.0 - https://www.npmjs.com/package/readdirp/v/3.6.0 | MIT +MIT License -Copyright (c) 2014-2018, Jon Schlinkert. +Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -657,24 +2325,51 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. ---------------- -** picomatch@2.3.1 - https://www.npmjs.com/package/picomatch/v/2.3.1 | MIT +** require-directory@2.1.1 - https://www.npmjs.com/package/require-directory/v/2.1.1 | MIT The MIT License (MIT) -Copyright (c) 2017-present, Jon Schlinkert. +Copyright (c) 2011 Troy Goode + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** safe-buffer@5.1.2 - https://www.npmjs.com/package/safe-buffer/v/5.1.2 | MIT +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -697,10 +2392,10 @@ THE SOFTWARE. ---------------- -** readdirp@3.6.0 - https://www.npmjs.com/package/readdirp/v/3.6.0 | MIT -MIT License +** safe-buffer@5.2.1 - https://www.npmjs.com/package/safe-buffer/v/5.2.1 | MIT +The MIT License (MIT) -Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com) +Copyright (c) Feross Aboukhadijeh Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -709,43 +2404,62 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. ---------------- -** require-directory@2.1.1 - https://www.npmjs.com/package/require-directory/v/2.1.1 | MIT -The MIT License (MIT) +** sax@1.4.1 - https://www.npmjs.com/package/sax/v/1.4.1 | ISC +The ISC License -Copyright (c) 2011 Troy Goode +Copyright (c) 2010-2024 Isaac Z. Schlueter and Contributors -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +==== + +`String.fromCodePoint` by Mathias Bynens used according to terms of MIT +License, as follows: + +Copyright (c) 2010-2024 Mathias Bynens + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------- @@ -783,6 +2497,112 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------- + +** string_decoder@1.1.1 - https://www.npmjs.com/package/string_decoder/v/1.1.1 | MIT +Node.js is licensed for use as follows: + +""" +Copyright Node.js contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" + +This license applies to parts of Node.js originating from the +https://github.com/joyent/node repository: + +""" +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" + + + +---------------- + +** string_decoder@1.3.0 - https://www.npmjs.com/package/string_decoder/v/1.3.0 | MIT +Node.js is licensed for use as follows: + +""" +Copyright Node.js contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" + +This license applies to parts of Node.js originating from the +https://github.com/joyent/node repository: + +""" +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" + + + ---------------- ** string-width@4.2.3 - https://www.npmjs.com/package/string-width/v/4.2.3 | MIT @@ -854,6 +2674,31 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +---------------- + +** tar-stream@2.2.0 - https://www.npmjs.com/package/tar-stream/v/2.2.0 | MIT +The MIT License (MIT) + +Copyright (c) 2014 Mathias Buus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + ---------------- ** to-regex-range@5.0.1 - https://www.npmjs.com/package/to-regex-range/v/5.0.1 | MIT @@ -905,6 +2750,39 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------- + +** util-deprecate@1.0.2 - https://www.npmjs.com/package/util-deprecate/v/1.0.2 | MIT +(The MIT License) + +Copyright (c) 2014 Nathan Rajlich + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + +---------------- + +** uuid@8.0.0 - https://www.npmjs.com/package/uuid/v/8.0.0 | MIT + ---------------- ** workerpool@6.5.1 - https://www.npmjs.com/package/workerpool/v/6.5.1 | Apache-2.0 @@ -1125,6 +3003,76 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------- + +** wrappy@1.0.2 - https://www.npmjs.com/package/wrappy/v/1.0.2 | ISC +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +---------------- + +** xml2js@0.6.2 - https://www.npmjs.com/package/xml2js/v/0.6.2 | MIT +Copyright 2010, 2011, 2012, 2013. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + + +---------------- + +** xmlbuilder@11.0.1 - https://www.npmjs.com/package/xmlbuilder/v/11.0.1 | MIT +The MIT License (MIT) + +Copyright (c) 2013 Ozgur Ozcitak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + ---------------- ** y18n@5.0.8 - https://www.npmjs.com/package/y18n/v/5.0.8 | ISC @@ -1188,4 +3136,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------- + +** zip-stream@4.1.1 - https://www.npmjs.com/package/zip-stream/v/4.1.1 | MIT +Copyright (c) 2014 Chris Talkington, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + ---------------- diff --git a/packages/@aws-cdk/integ-runner/lib/runner/private/cloud-assembly.ts b/packages/@aws-cdk/integ-runner/lib/runner/private/cloud-assembly.ts index 861a62bd56ee4..f5003ba24cb2c 100644 --- a/packages/@aws-cdk/integ-runner/lib/runner/private/cloud-assembly.ts +++ b/packages/@aws-cdk/integ-runner/lib/runner/private/cloud-assembly.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import { AssemblyManifest, Manifest, ArtifactType, AwsCloudFormationStackProperties, ArtifactManifest, MetadataEntry, AssetManifestProperties, ArtifactMetadataEntryType, ContainerImageAssetMetadataEntry, FileAssetMetadataEntry } from '@aws-cdk/cloud-assembly-schema'; -import { AssetManifest, FileManifestEntry, DockerImageManifestEntry } from 'cdk-assets/lib/asset-manifest'; +import { AssetManifest, FileManifestEntry, DockerImageManifestEntry } from 'cdk-assets'; import * as fs from 'fs-extra'; /** diff --git a/packages/@aws-cdk/integ-runner/package.json b/packages/@aws-cdk/integ-runner/package.json index eed5311ce7825..2a9b3193f0682 100644 --- a/packages/@aws-cdk/integ-runner/package.json +++ b/packages/@aws-cdk/integ-runner/package.json @@ -45,7 +45,7 @@ "BSD-2-Clause", "0BSD" ], - "dontAttribute": "^@aws-cdk/|^@cdklabs/|^cdk-assets$", + "dontAttribute": "^@aws-cdk/|^@cdklabs$", "test": "bin/integ-runner --version" } }, @@ -75,9 +75,8 @@ "@aws-cdk/cloudformation-diff": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/aws-service-spec": "^0.1.8", - "cdk-assets": "0.0.0", "@aws-cdk/cdk-cli-wrapper": "0.0.0", - "aws-cdk": "0.0.0", + "cdk-assets": "^2.147.1", "chalk": "^4", "fs-extra": "^9.1.0", "workerpool": "^6.5.1", diff --git a/packages/aws-cdk/THIRD_PARTY_LICENSES b/packages/aws-cdk/THIRD_PARTY_LICENSES index 93e7edcf8234d..2e19eba3b75f0 100644 --- a/packages/aws-cdk/THIRD_PARTY_LICENSES +++ b/packages/aws-cdk/THIRD_PARTY_LICENSES @@ -294,6 +294,16 @@ This product includes software developed at Amazon Web Services, Inc. (http://aws.amazon.com/). +---------------- + +** aws-sdk@2.1649.0 - https://www.npmjs.com/package/aws-sdk/v/2.1649.0 | Apache-2.0 +AWS SDK for JavaScript +Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +This product includes software developed at +Amazon Web Services, Inc. (http://aws.amazon.com/). + + ---------------- ** balanced-match@1.0.2 - https://www.npmjs.com/package/balanced-match/v/1.0.2 | MIT @@ -482,6 +492,13 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +---------------- + +** cdk-assets@2.147.1 - https://www.npmjs.com/package/cdk-assets/v/2.147.1 | Apache-2.0 +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + ---------------- ** cdk-from-cfn@0.162.0 - https://www.npmjs.com/package/cdk-from-cfn/v/0.162.0 | MIT OR Apache-2.0 diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index ab4a8f995e026..351a514fb04cf 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -24,7 +24,7 @@ "gen": "./generate.sh", "build+extract": "yarn build", "build+test+extract": "yarn build+test", - "attributions:update": "yarn node-bundle validate --entrypoint lib/index.ts --dont-attribute \"^@aws-cdk/|^cdk-assets|^cdk-cli-wrapper$\" --fix" + "attributions:update": "yarn node-bundle validate --entrypoint lib/index.ts --dont-attribute \"^@aws-cdk/|^cdk-cli-wrapper$\" --fix" }, "cdk-build": { "post": [ @@ -48,7 +48,7 @@ "0BSD", "MIT OR Apache-2.0" ], - "dontAttribute": "^@aws-cdk/|^@cdklabs/|^cdk-assets$|^cdk-cli-wrapper$", + "dontAttribute": "^@aws-cdk/|^@cdklabs/|^cdk-cli-wrapper$", "test": "bin/cdk --version", "entryPoints": [ "lib/index.js" @@ -71,6 +71,7 @@ "@types/fs-extra": "^9.0.13", "@types/glob": "^7.2.0", "@types/jest": "^29.5.12", + "@types/mime": "^2.0.3", "@types/mockery": "^1.4.33", "@types/promptly": "^3.0.5", "@types/semver": "^7.5.8", @@ -104,7 +105,7 @@ "archiver": "^5.3.2", "aws-sdk": "^2.1648.0", "camelcase": "^6.3.0", - "cdk-assets": "0.0.0", + "cdk-assets": "^2.147.1", "cdk-from-cfn": "^0.162.0", "chalk": "^4", "chokidar": "^3.6.0", diff --git a/packages/aws-cdk/tsconfig.json b/packages/aws-cdk/tsconfig.json index c810cbc0b0aab..86529a2bdeb65 100644 --- a/packages/aws-cdk/tsconfig.json +++ b/packages/aws-cdk/tsconfig.json @@ -35,9 +35,6 @@ "references": [ { "path": "../@aws-cdk/cloudformation-diff" - }, - { - "path": "../cdk-assets" } ] } diff --git a/tools/@aws-cdk/pkglint/lib/rules.ts b/tools/@aws-cdk/pkglint/lib/rules.ts index 11a435fdeb803..3b91f6fdc2790 100644 --- a/tools/@aws-cdk/pkglint/lib/rules.ts +++ b/tools/@aws-cdk/pkglint/lib/rules.ts @@ -63,7 +63,6 @@ export class PublishConfigTagIsRequired extends ValidationRule { '@aws-cdk/region-info', 'aws-cdk', 'awslint', - 'cdk-assets', ]; public validate(pkg: PackageJson): void { @@ -1685,7 +1684,6 @@ export class UbergenPackageVisibility extends ValidationRule { 'aws-cdk', 'awslint', 'cdk', - 'cdk-assets', '@aws-cdk/integ-runner', '@aws-cdk-testing/cli-integ', ]; diff --git a/yarn.lock b/yarn.lock index a2b1fdf03b171..70c88cc719b79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -59,6 +59,21 @@ "@aws-cdk/service-spec-types" "^0.0.76" "@cdklabs/tskb" "^0.0.3" +"@aws-cdk/cloud-assembly-schema@2.147.1": + version "2.147.1" + resolved "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-2.147.1.tgz#a875614331320919a7883d7dc016268ef77d17d4" + integrity sha512-PygVPGsmfQnlrXHfIoWn/NCGBrT2wGxyC1Zr03n1b+ZzgZ1n2YCmjvaFrJXN+d/QViSmIgQKlS8BrLaQdVRcsA== + dependencies: + jsonschema "^1.4.1" + semver "^7.6.2" + +"@aws-cdk/cx-api@2.147.1": + version "2.147.1" + resolved "https://registry.npmjs.org/@aws-cdk/cx-api/-/cx-api-2.147.1.tgz#fd4cea601ede9109bbc1d1d86a0db09d47cb6eb2" + integrity sha512-UVrWEkusmnOb785uA20h42DMZlDJ0gYbWrvMNJtQGou9jdFbItWg0nnGbFfoCXfpcT0iownX++Qu05gjkWIEEg== + dependencies: + semver "^7.6.2" + "@aws-cdk/lambda-layer-kubectl-v24@^2.0.242": version "2.0.242" resolved "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl-v24/-/lambda-layer-kubectl-v24-2.0.242.tgz#4273a5ad7714f933a7eba155eb9280823086db71" @@ -7240,6 +7255,22 @@ aws-sdk@^2.1231.0, aws-sdk@^2.1648.0, aws-sdk@^2.928.0: uuid "8.0.0" xml2js "0.6.2" +aws-sdk@^2.1639.0: + version "2.1649.0" + resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1649.0.tgz#346bbb2d64024144474883b34c59e1e7144b0149" + integrity sha512-iKwUomvBwzlrcX83PU60SW8KgLP+zNSQtl+lVnJkxRdbehS/p/wTdofby88TgMGDBHrWppreiaYC1fToB8Wznw== + dependencies: + buffer "4.9.2" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.16.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + util "^0.12.4" + uuid "8.0.0" + xml2js "0.6.2" + axios@^0.27.2: version "0.27.2" resolved "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" @@ -7677,6 +7708,19 @@ case@1.6.3, case@^1.6.3: resolved "https://registry.npmjs.org/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== +cdk-assets@^2.147.1: + version "2.147.1" + resolved "https://registry.npmjs.org/cdk-assets/-/cdk-assets-2.147.1.tgz#bcc3df68f5421301eb34def8dd15a5f6b663f0d6" + integrity sha512-viXAulSpYBOIzkC21KZ2SSpNrGqx/4IoHUcRp2wbWP1jsPNmo6GqG0J4MXtK34qcGjHrbXPG75QPoxmuRExy0w== + dependencies: + "@aws-cdk/cloud-assembly-schema" "2.147.1" + "@aws-cdk/cx-api" "2.147.1" + archiver "^5.3.2" + aws-sdk "^2.1639.0" + glob "^7.2.3" + mime "^2.6.0" + yargs "^16.2.0" + cdk-from-cfn@^0.162.0: version "0.162.0" resolved "https://registry.npmjs.org/cdk-from-cfn/-/cdk-from-cfn-0.162.0.tgz#7cde2acead7a150884b505caabeab9891708bdd9" @@ -10547,11 +10591,6 @@ ignore@^5.0.4, ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1, ignore@~5.3.1: resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== -immediate@~3.0.5: - version "3.0.6" - resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" - integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== - import-fresh@^3.0.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -11813,16 +11852,6 @@ jsonschema@^1.4.1: resolved "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== -jszip@^3.10.1: - version "3.10.1" - resolved "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" - integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== - dependencies: - lie "~3.3.0" - pako "~1.0.2" - readable-stream "~2.3.6" - setimmediate "^1.0.5" - just-diff-apply@^5.2.0: version "5.5.0" resolved "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz#771c2ca9fa69f3d2b54e7c3f5c1dfcbcc47f9f0f" @@ -12174,13 +12203,6 @@ license-checker@^25.0.1: spdx-satisfies "^4.0.0" treeify "^1.1.0" -lie@~3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" - integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== - dependencies: - immediate "~3.0.5" - line-reader@^0.2.4: version "0.2.4" resolved "https://registry.npmjs.org/line-reader/-/line-reader-0.2.4.tgz#c4392b587dea38580c9678570e6e8e49fce52622" @@ -13975,11 +13997,6 @@ pacote@^18.0.0, pacote@^18.0.6: ssri "^10.0.0" tar "^6.1.11" -pako@~1.0.2: - version "1.0.11" - resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" - integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== - param-case@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" @@ -15042,11 +15059,6 @@ set-function-name@^2.0.1: functions-have-names "^1.2.3" has-property-descriptors "^1.0.2" -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"