├── .editorconfig ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── nodejs.yml │ └── publish.yml ├── .gitignore ├── .gitpod.yml ├── .npmignore ├── .nvmrc ├── CONTRIBUTING.md ├── CONTRIBUTORS.md ├── Dockerfile ├── LICENSE ├── README.md ├── docs └── architecture │ └── ADR_001_Latest_aws_and_nodejs_in_Docker.md ├── eslint.config.mjs ├── index.js ├── jasmine.json ├── package-lock.json ├── package.json ├── scripts ├── build-packages ├── deploy-docker ├── postversion ├── preversion └── validate-features └── src ├── clean-aws-credentials-cache ├── index.js └── index.spec.js ├── get-profile-list ├── index.js └── index.spec.js ├── get-profile-options-values ├── index.js └── index.spec.js ├── index.js ├── is-role-arn └── index.js ├── is-windows └── index.js ├── load-profiles-from-config └── index.js ├── options └── index.js └── remove-object-entries ├── index.js └── index.spec.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = true 9 | quote_type = single 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Checklist 2 | 3 | If any of the items on this list can't be resolved independently, please 4 | feel welcome to request assistance in the comments of the pull request. 5 | 6 | * [ ] `scripts/validate-features` runs successfully 7 | * [ ] PR is marked as ready for review (i.e. not a draft) 8 | 9 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI test 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [18.x, 20.x] 13 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v4 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | cache: 'npm' 22 | - run: npm ci 23 | - run: npm test -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | workflow_run: 5 | workflows: ["Node.js CI test"] 6 | types: 7 | - completed 8 | push: 9 | tags: 10 | - "v*" 11 | 12 | jobs: 13 | Publish: 14 | runs-on: ubuntu-latest 15 | if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') 16 | 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@v4 20 | 21 | - name: Setup Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version-file: '.nvmrc' 25 | cache: "npm" 26 | registry-url: https://registry.npmjs.org 27 | cache-dependency-path: package-lock.json 28 | env: 29 | NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} 30 | 31 | - name: Install dependencies 32 | run: npm ci 33 | 34 | - name: Publish package 35 | run: npm publish 36 | 37 | - name: Build package 38 | run: | 39 | sudo apt-get update 40 | sudo apt-get install -y ruby-dev build-essential rpm 41 | sudo gem install fpm 42 | sudo scripts/build-packages 43 | 44 | - name: Create Release 45 | uses: ncipollo/release-action@v1 46 | with: 47 | artifacts: "*.deb,*.rpm" 48 | name: ${{ github.ref_name }} 49 | tag: ${{ github.ref }} 50 | 51 | Deploy_Docker_Image: 52 | runs-on: ubuntu-latest 53 | needs: Publish 54 | if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') 55 | 56 | steps: 57 | - name: Checkout code 58 | uses: actions/checkout@v4 59 | 60 | - name: Setup Node.js 61 | uses: actions/setup-node@v4 62 | with: 63 | node-version-file: '.nvmrc' 64 | cache: "npm" 65 | registry-url: https://registry.npmjs.org 66 | cache-dependency-path: package-lock.json 67 | env: 68 | NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} 69 | 70 | - name: Build and Deploy Docker Image 71 | run: | 72 | sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} 73 | sudo scripts/deploy-docker 74 | sudo docker logout 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | 4 | .screen_layout 5 | npm-debug.log* 6 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: npm ci 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | docker/ 2 | scripts/ 3 | 4 | .github 5 | .drone.yml 6 | .editorconfig 7 | .eslintrc 8 | .gitpod.yml 9 | .nvmrc 10 | PULL_REQUEST_TEMPLATE.md 11 | jasmine.json 12 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/iron 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Policy 2 | We will accept contributions of good code that we can use from anyone. 3 | 4 | ## What this means 5 | 6 | ### “We will accept” 7 | This means that we will incorporate your contribution into the project’s codebase, adapt it as needed, and give you full credit for your work. 8 | 9 | ### “contributions” 10 | This means just about anything you wish to contribute to the project, as long as it is good code we can use. The easier you make it for us to accept your contribution, the happier we are, but if it’s good enough, we will do a reasonable amount of work to use it. 11 | 12 | ### “of good code” 13 | This means that we will accept contributions that work well and efficiently, that fit in with the goals of the project, that match the project’s coding style, and that do not impose an undue maintenance workload on us going forward. This does not mean just program code, either, but documentation and artistic works as appropriate to the project. 14 | 15 | ### “that we can use” 16 | This means that your contribution must be given freely and irrevocably, that you must have the right to contribute it for our unrestricted use, and that your contribution is made under a license that is compatible with the license the project has chosen and that permits us to include, distribute, and modify your work without restriction. 17 | 18 | ### “from anyone” 19 | This means exactly that. We don’t care about anything but your code. We don’t care about your race, religion, national origin, biological gender, perceived gender, sexual orientation, lifestyle, political viewpoint, or anything extraneous like that. We will neither reject your contribution nor grant it preferential treatment on any basis except the code itself. We do, however, reserve the right to tell you to go away if you behave too obnoxiously toward us. 20 | 21 | ## If Your Contribution Is Rejected 22 | If we reject your contribution, it means only that we do not consider it suitable for our project in the form it was submitted. It is not personal. If you ask civilly, we will be happy to discuss it with you and help you understand why it was rejected, and if possible improve it so we can accept it. If we are not able to reach an agreement, then you are free to fork our project, as with any Open Source project, and add your contribution to your fork. 23 | 24 | ###### *This text was pulled verbatim from a [wonderful post](https://medium.com/@jmaynard/a-contribution-policy-for-open-source-that-works-bfc4600c9d83) by [Jay Maynard](https://medium.com/@jmaynard?source=post_header_lockup)* -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Thank you to everyone who has contributed! 2 | 3 | [jtheriault](https://github.com/jtheriault)|[jtheriault](https://github.com/jtheriault) 4 | ---- | ---- 5 | [terodox](https://github.com/terodox)|[terodox](https://github.com/terodox) 6 | [spier](https://github.com/spier)|[spier](https://github.com/spier) 7 | [rclmenezes](https://github.com/rclmenezes)|[rclmenezes](https://github.com/rclmenezes) 8 | [rclmenezes](https://github.com/ozeebee)|[ozeebee](https://github.com/ozeebee) 9 | [mattquinlan440](https://github.com/mattquinlan440)|[mattquinlan440](https://github.com/mattquinlan440) 10 | [juneeighteen](https://github.com/juneeighteen)|[juneeighteen](https://github.com/juneeighteen) 11 | [PoofyFoopy](https://github.com/PoofyFoopy)|[PoofyFoopy](https://github.com/PoofyFoopy) 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG node_lts 2 | ARG version 3 | 4 | FROM node:${node_lts} 5 | 6 | LABEL name=awsudo/awsudo 7 | LABEL version="v${version}" 8 | LABEL maintainer="awsudo opensource " 9 | 10 | RUN npm i -g awsudo@${version} 11 | 12 | RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \ 13 | unzip awscliv2.zip && \ 14 | ./aws/install 15 | RUN rm -rf awscliv2.zip aws/ 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Meltwater 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # awsudo 2 | 3 | [![Node.js CI test](https://github.com/meltwater/awsudo/actions/workflows/nodejs.yml/badge.svg?branch=master)](https://github.com/meltwater/awsudo/actions/workflows/nodejs.yml) 4 | 5 | A simple utility for easily executing AWS cli commands with an assumed role. 6 | 7 | For more information about the motiviation behind developing this utility, please read our blog post [Assuming roles in AWS with sudo-like agility](http://underthehood.meltwater.com/blog/2018/01/22/assuming-roles-in-aws-with-sudo-like-agility/). 8 | 9 | ## Usage 10 | 11 | ```bash 12 | awsudo [-d|--duration] [-p|--profile] [-n|--session-name] [-e|--external-id] [-v|--verbose] 13 | [-m|--mfa-token-arn] [-t|--mfa-token] 14 | 15 | Assume an IAM role for the duration of a command 16 | 17 | Positionals: 18 | arn ARN to assume [string] 19 | command Command to run 20 | 21 | Options: 22 | --help Show help [boolean] 23 | --version Show version number [boolean] 24 | -d, --duration The duration to assume this role in seconds. See 25 | https://docs.aws.amazon.com/STS/latest/APIReference/API_A 26 | ssumeRole.html#API_AssumeRole_RequestParameters 27 | [number] [default: 900] 28 | -p, --profile The profile used to assume the role 29 | [string] [default: ""] 30 | -n, --session-name The role session name to use 31 | [string] [default: "RoleSession"] 32 | -e, --external-id The external id string used to authenticate role 33 | assumption [string] [default: false] 34 | -v, --verbose Show debug information [boolean] [default: false] 35 | -t, --mfa-token Current MFA token [Must also supply mfa-token-arn] 36 | [string] [default: false] 37 | -m, --mfa-token-arn ARN for users MFA [Must also supply mfa-token] 38 | [string] [default: false] 39 | --preserve-credentials-cache Retain the AWS credentials cache folder when 40 | command is complete; otherwise remove it 41 | [boolean] [default: false] 42 | ``` 43 | 44 | ### Install 45 | 46 | awsudo can be installed as a global utility to use alongside the AWS cli for 47 | day-to-day operations, local troubleshooting, etc: 48 | 49 | ```bash 50 | npm install -g awsudo 51 | ``` 52 | 53 | #### Node.js 54 | 55 | awsudo can also be installed for use by specific Node.js projects (i.e. as part 56 | of a CI/CD build process) by adding it as a dependency like any other: 57 | 58 | ```bash 59 | npm install --save-dev awsudo 60 | ``` 61 | 62 | npm will place it in the execution PATH for any scripts defined in 63 | it package.json that it runs (e.g. start, test). 64 | 65 | #### deb and rpm packages 66 | 67 | In addition to the native npm package and Docker image, there are .deb and .rpm 68 | packages avaialble. 69 | 70 | These can be downloaded from 71 | 72 | 1. the [releases tab](https://github.com/meltwater/awsudo/releases) in your browser 73 | 2. the command-line: 74 | 75 | **Latest .deb** 76 | 77 | ```bash 78 | curl -LO $(curl -s https://api.github.com/repos/meltwater/awsudo/releases/latest | grep -Eo 'https://github\.com/meltwater/awsudo/releases/download/v.*\.deb') 79 | ``` 80 | 81 | **Latest .rpm** 82 | 83 | ```bash 84 | curl -LO $(curl -s https://api.github.com/repos/meltwater/awsudo/releases/latest | grep -Eo 'https://github\.com/meltwater/awsudo/releases/download/v.*\.rpm') 85 | ``` 86 | 87 | > **Warning:** You must install Node.js separately, because these packages are not 88 | > marked as dependent on Node.js within the Debian or Red Hat ecosystems. This 89 | > facilitates portability across distributions and better accomodates the 90 | > multitude of ways Node.js can be installed (e.g. using nvm). 91 | 92 | #### Docker 93 | 94 | awsudo can also be used from its official Docker image, which packages it along 95 | with its dependencies and the AWS cli. 96 | 97 | ```bash 98 | docker pull awsudo/awsudo 99 | ``` 100 | 101 | > **Note:** See Docker under Usage for details of what the image includes. 102 | 103 | ## Usage 104 | 105 | Basic usage when awsudo is on the PATH resembles this example: 106 | 107 | ```bash 108 | awsudo arn:aws:iam::123456789012:role/S3Access aws s3 cp ./some/directory s3://some-bucket 109 | ``` 110 | 111 | **💡 Tip: awsudo shell!** 112 | 113 | When running multiple commands as the same role (especially when using MFA), 114 | it can be convenient to temporarily authenticate all commands as that role by 115 | launching a new shell using awsudo: 116 | 117 | ```bash 118 | awsudo arn:aws:iam::123456789012:role/S3Access /bin/bash 119 | aws s3 cp ./some/directory s3://some-bucket 120 | aws s3 cp ./another/directory s3://some-bucket 121 | aws s3api list-objects --bucket some-bucket 122 | ``` 123 | 124 | > **Note:** the lifespan of the authentication within the shell is dictated by 125 | > the `--duration` argument to awsudo 126 | 127 | ### Docker 128 | 129 | The Docker image can be used as a direct command: 130 | 131 | ```bash 132 | docker run awsudo/awsudo awsudo --help 133 | ``` 134 | 135 | In order to assume roles, the AWS configuration needs to be mounted as a 136 | volume in the container: 137 | 138 | ```bash 139 | docker run -v ~/.aws:/root/.aws \ 140 | awsudo/awsudo \ 141 | awsudo arn:aws:iam::123456789012:role/S3Access aws s3 ls 142 | ``` 143 | 144 | If you need to operate on local files, those need to be mounted to a working 145 | directory for the container as well: 146 | 147 | ```bash 148 | docker run -v ~/.aws:/root/.aws awsudo/awsudo \ 149 | --volume $PWD:/docker-working-directory --workdir /docker-working-directory \ 150 | awsudo/awsudo \ 151 | awsudo arn:aws:iam::123456789012:role/S3Access aws s3 cp ./some/directory s3://some-bucket 152 | ``` 153 | 154 | #### Docker image contents 155 | 156 | The main focus of the Docker image is to provide awsudo, however it includes 157 | some other tools that may be of use: 158 | 159 | * `aws` - a key component for many uses of awsudo 160 | * `node` - the runtime engine of awsudo itself 161 | * an OS with a package manager to facilitate installing additional software 162 | 163 | Each of these have their own releases which may affect a consumer of the awsudo 164 | image. To provide a predictable environment for consumers we guarantee that, 165 | starting with [v1.7.2]: 166 | 167 | * an image for each version of awsudo is available 168 | * an image for each active or maintenance [Node.js LTS] version is available 169 | * an image for each combination of awsudo and Node.js LTS is available 170 | * the latest release of the v2 AWS CLI will be included 171 | * the choice of base OS is tied to a Node.js LTS version 172 | 173 | To allow selection across all of these possibilities, the awsudo image is 174 | published with a selection of tags. 175 | 176 | The table below illustrates what version of each tool can be expected 177 | for a given image tag: 178 | 179 | | | `:latest` |`:vX.Y.Z` | `:nodeLTS` | `:vX.Y.Z-nodeLTS` | 180 | | ------- | --------- | -------- | ---------- | ----------------- | 181 | | awsudo | latest | vX.Y.Z | latest | vX.Y.Z | 182 | | aws | latest v2 | latest v2 | latest v2 | latest v2 | 183 | | Node.js | latest | latest | nodeLTS | nodeLTS | 184 | | OS | [debian][debian-docker] | [debian][debian-docker] | [debian][debian-docker] | [debian][debian-docker] | 185 | 186 | #### Docker-based CI/CD 187 | 188 | The Docker image can also be used with CI/CD tools like [Drone](https://drone.io) 189 | or [CircleCI](https://circleci.com/). 190 | 191 | Here is an example **Drone** pipeline step which uses the awsudo Docker image to 192 | deploy into AWS: 193 | 194 | ```yaml 195 | deploy: 196 | image: awsudo/awsudo:iron 197 | commands: 198 | # Copy build artifacts to publicly-readable S3 bucket 199 | - awsudo arn:aws:iam::${AWS_ACCOUNT_ID}:role/S3Access aws s3 cp ./build s3://some-bucket --acl public-read --recursive 200 | environment: 201 | - AWS_DEFAULT_REGION=us-east-1 202 | secrets: 203 | - aws_access_key_id 204 | - aws_account_id 205 | - aws_secret_access_key 206 | ``` 207 | 208 | ## Prerequisites 209 | 210 | ### Valid AWS Configuration 211 | 212 | Any one of the following is required for awsudo to function correctly 213 | 214 | - Appropriate [environment variables are set](https://docs.aws.amazon.com/cli/latest/userguide/cli-environment.html) for aws-sdk to work 215 | - A default profile (e.g. created using `aws configure`) 216 | - A set of any named profiles you would like to use 217 | 218 | ## Developing / Testing 219 | 220 | ### validate-features 221 | 222 | This is an included script which validates significant features of awsudo as 223 | functioning properly in a true running context. 224 | 225 | Not every feature that exists is, or should be, exercised by this tool. If a 226 | unit test can adequately validate a given behavior, that is preferred. 227 | 228 | Before running, it will check for prerequisites, but for the sake of planning 229 | they are: 230 | 231 | - Docker 232 | - A post-`aws configure` environment with 233 | - at least one profile 234 | - at least one profile requiring an MFA 235 | 236 | To execute the tool, run the following from the project root: 237 | 238 | ``` 239 | scripts/validate-features 240 | ``` 241 | 242 | it will prompt for profile names and MFA tokens as necessary. 243 | 244 | ## Contributing 245 | 246 | [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/meltwater/awsudo) 247 | 248 | Do we accept contributions? YES! (see our [policy](CONTRIBUTING.md) for details) 249 | 250 | Thank you to everyone who has been one of our [contributors](CONTRIBUTORS.md)! 251 | 252 | ## Questions/Contact? 253 | 254 | The maintainer of this repository is the [AWS sudo open source maintainers at Meltwater](mailto:awsudo.opensource@meltwater.com), please send us any questions. 255 | 256 | [v1.7.2]: https://github.com/meltwater/awsudo/releases/tag/v1.7.2 257 | [debian-docker]: https://hub.docker.com/_/debian 258 | [Docker tag ADR]: https://github.com/meltwater/awsudo/blob/master/docs/architecture/ADR_001_Latest_aws_and_nodejs_in_Docker.md 259 | [Node.js LTS]: https://nodejs.org/en/about/releases/ 260 | -------------------------------------------------------------------------------- /docs/architecture/ADR_001_Latest_aws_and_nodejs_in_Docker.md: -------------------------------------------------------------------------------- 1 | # ADR 001: Latest aws and nodejs in Docker 2 | 3 | ## Context 4 | 5 | Stated in issue [#67] 6 | 7 | > As of version 1.7.1, the Docker image includes woefully out-of-date versions of nodejs (v12/erbium) and the AWS CLI (v1.18.106). 8 | 9 | It's useful to include these: 10 | 11 | * nodejs is a runtime dependency of awsudo itself 12 | * `aws` is central to most uses of awsudo 13 | 14 | Due to its relatively short (30 month) LTS cycle, it's useful to support multiple versions of nodejs. 15 | 16 | AWS CLI v2 has been the latest version for over 2 years and maintains backward compatibility within its major version. 17 | 18 | Docker images are often the basis of other images which rely on OS features (e.g. package management tools) 19 | 20 | ## Decision 21 | 22 | * Docker images are tagged to specify 23 | * awsudo version 24 | * nodejs version (by LTS codename) 25 | * Ex: `:v1.7.2-iron` 26 | * Unspecified tag values "slide" to the latest version 27 | * Ex: these tags would be equivalent: 28 | * `:v1.7.2` 29 | * `:iron` 30 | * `:latest` 31 | * Docker images are produced for every nodejs version until their [end-of-life][nodejs releases] 32 | * The most recent `aws` version (at build time) is included 33 | * The Docker image is based on the equivalent [node image] 34 | 35 | ## Status 36 | 37 | Accepted 38 | 39 | ## Consequences 40 | 41 | * Docker images with current dependencies will be available 42 | * Sliding versions may break dependents that directly rely on the unspecific dependency 43 | 44 | [#67]: https://github.com/meltwater/awsudo/issues/67 45 | [node image]: https://hub.docker.com/_/node 46 | [nodejs releases]: https://nodejs.org/en/about/releases/ 47 | [Generate Docker images based on node]: https://github.com/meltwater/awsudo/pull/66 48 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js'; 2 | import depend from 'eslint-plugin-depend'; 3 | import jsdoc from 'eslint-plugin-jsdoc'; 4 | import globals from 'globals'; 5 | 6 | export default [ 7 | jsdoc.configs['flat/recommended'], 8 | depend.configs['flat/recommended'], 9 | // http://eslint.org/docs/rules/ 10 | { 11 | languageOptions: { 12 | ecmaVersion: 13, 13 | sourceType: 'module', 14 | globals: { 15 | ...globals.browser, 16 | ...globals.amd, 17 | ...globals.jasmine, 18 | ...globals.jest, 19 | ...globals.es2015, 20 | ...globals.node 21 | } 22 | } 23 | }, 24 | { 25 | ignores: [ 26 | '**/*.test.js', 27 | '**/*.spec.js', 28 | '**/*.config.js' 29 | ], 30 | rules: { 31 | ...js.configs.recommended.rules, 32 | 'default-case': 'error', 33 | 'id-length': [ 34 | 'error', 35 | { 36 | min: 2, 37 | exceptions: ['id'] 38 | } 39 | ], 40 | 'no-alert': 'error', 41 | 'no-duplicate-imports': 'error', 42 | 'no-implicit-coercion': 'error', 43 | 'no-implied-eval': 'error', 44 | 'no-invalid-this': 'error', 45 | 'no-labels': 'error', 46 | 'no-lone-blocks': 'error', 47 | 'no-loop-func': 'error', 48 | 'no-magic-numbers': [ 49 | 'error', 50 | { 51 | ignore: [-1, 0, 1, 2] 52 | } 53 | ], 54 | 'no-param-reassign': 'error', 55 | 'no-prototype-builtins': 0, 56 | 'no-return-assign': ['error', 'always'], 57 | 'no-script-url': 'error', 58 | 'no-self-compare': 'error', 59 | 'no-sequences': 'error', 60 | 'no-throw-literal': 'error', 61 | 'no-unmodified-loop-condition': 'error', 62 | 'no-unused-expressions': 'error', 63 | 'no-useless-call': 'error', 64 | 'no-useless-concat': 'error', 65 | 'no-useless-return': 'error', 66 | 'no-void': 'error', 67 | 'no-with': 'error', 68 | 69 | /** 70 | * Stylistic rules 71 | */ 72 | 73 | camelcase: 'error', 74 | 'comma-dangle': [ 75 | 'error', 76 | 'never' 77 | ], 78 | complexity: 'error', 79 | curly: [ 80 | 'error', 81 | 'all' 82 | ], 83 | indent: [ 84 | 'error', 85 | 4, // http://eslint.org/docs/rules/indent 86 | { 87 | SwitchCase: 1 88 | } 89 | ], 90 | 'max-depth': [ 91 | 'error', 92 | 3 // http://eslint.org/docs/rules/max-depth 93 | ], 94 | 'new-cap': 'error', 95 | 'new-parens': 'error', 96 | 'no-continue': 'error', 97 | 'no-lonely-if': 'error', 98 | 'no-multiple-empty-lines': [ 99 | 'error', 100 | { 101 | max: 1 102 | } 103 | ], 104 | 'no-nested-ternary': 'error', 105 | 'no-tabs': 'error', 106 | 'no-trailing-spaces': [ 107 | 'error', 108 | { 109 | ignoreComments: true, 110 | skipBlankLines: true 111 | } 112 | ], 113 | 'no-unneeded-ternary': 'error', 114 | 'no-unused-private-class-members': 'off', 115 | 'no-unused-vars': ['error', { 116 | 'vars': 'all', 117 | 'args': 'all', 118 | 'argsIgnorePattern': '^__', 119 | 'varsIgnorePattern': '^__', 120 | 'caughtErrorsIgnorePattern': '^__' 121 | }], 122 | 'nonblock-statement-body-position': [ 123 | 'error', 124 | 'beside' // http://eslint.org/docs/rules/nonblock-statement-body-position 125 | ], 126 | 'one-var-declaration-per-line': [ 127 | 'error', 128 | 'always' 129 | ], 130 | quotes: [ 131 | 'error', 132 | 'single' 133 | ], 134 | semi: [ 135 | 'error', 136 | 'always' 137 | ], 138 | 'vars-on-top': 'error', 139 | 140 | /** 141 | * Depend Rules 142 | */ 143 | 'depend/ban-dependencies': 'warn', 144 | 145 | /** 146 | * JSdoc Rules 147 | */ 148 | 'jsdoc/require-jsdoc': 'off', 149 | 'jsdoc/tag-lines': 'off', 150 | 151 | /** 152 | * ES6 Specific 153 | */ 154 | 155 | 'arrow-body-style': [ 156 | 'error', 157 | 'as-needed' 158 | ], 159 | 'no-confusing-arrow': 'error', 160 | 'no-useless-constructor': 'error', 161 | 'no-var': 'error', 162 | 'prefer-const': 'error', 163 | 'prefer-template': 'error' 164 | } 165 | } 166 | ]; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | throw new Error('This is not a "requirable" module. It adds the awsudo command to the path. Please see README'); -------------------------------------------------------------------------------- /jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "./src", 3 | "spec_files": [ 4 | "**/*.spec.js" 5 | ], 6 | "jsLoader": "require" 7 | } 8 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "awsudo", 3 | "version": "3.0.0-alpha.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "awsudo", 9 | "version": "3.0.0-alpha.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@aws-sdk/client-sts": "3.670.0", 13 | "@aws-sdk/shared-ini-file-loader": "3.374.0", 14 | "@smithy/shared-ini-file-loader": "3.1.8", 15 | "yargs": "17.7.2" 16 | }, 17 | "bin": { 18 | "awsudo": "src/index.js" 19 | }, 20 | "devDependencies": { 21 | "@eslint/js": "9.12.0", 22 | "eslint": "9.12.0", 23 | "eslint-plugin-depend": "0.11.0", 24 | "eslint-plugin-jsdoc": "50.4.1", 25 | "globals": "15.11.0", 26 | "jasmine": "5.4.0", 27 | "mustache": "4.2.0", 28 | "nodemon": "3.1.7" 29 | } 30 | }, 31 | "node_modules/@aws-crypto/sha256-browser": { 32 | "version": "5.2.0", 33 | "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", 34 | "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", 35 | "dependencies": { 36 | "@aws-crypto/sha256-js": "^5.2.0", 37 | "@aws-crypto/supports-web-crypto": "^5.2.0", 38 | "@aws-crypto/util": "^5.2.0", 39 | "@aws-sdk/types": "^3.222.0", 40 | "@aws-sdk/util-locate-window": "^3.0.0", 41 | "@smithy/util-utf8": "^2.0.0", 42 | "tslib": "^2.6.2" 43 | } 44 | }, 45 | "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { 46 | "version": "2.2.0", 47 | "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", 48 | "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", 49 | "dependencies": { 50 | "tslib": "^2.6.2" 51 | }, 52 | "engines": { 53 | "node": ">=14.0.0" 54 | } 55 | }, 56 | "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { 57 | "version": "2.2.0", 58 | "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", 59 | "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", 60 | "dependencies": { 61 | "@smithy/is-array-buffer": "^2.2.0", 62 | "tslib": "^2.6.2" 63 | }, 64 | "engines": { 65 | "node": ">=14.0.0" 66 | } 67 | }, 68 | "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { 69 | "version": "2.3.0", 70 | "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", 71 | "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", 72 | "dependencies": { 73 | "@smithy/util-buffer-from": "^2.2.0", 74 | "tslib": "^2.6.2" 75 | }, 76 | "engines": { 77 | "node": ">=14.0.0" 78 | } 79 | }, 80 | "node_modules/@aws-crypto/sha256-js": { 81 | "version": "5.2.0", 82 | "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", 83 | "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", 84 | "dependencies": { 85 | "@aws-crypto/util": "^5.2.0", 86 | "@aws-sdk/types": "^3.222.0", 87 | "tslib": "^2.6.2" 88 | }, 89 | "engines": { 90 | "node": ">=16.0.0" 91 | } 92 | }, 93 | "node_modules/@aws-crypto/supports-web-crypto": { 94 | "version": "5.2.0", 95 | "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", 96 | "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", 97 | "dependencies": { 98 | "tslib": "^2.6.2" 99 | } 100 | }, 101 | "node_modules/@aws-crypto/util": { 102 | "version": "5.2.0", 103 | "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", 104 | "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", 105 | "dependencies": { 106 | "@aws-sdk/types": "^3.222.0", 107 | "@smithy/util-utf8": "^2.0.0", 108 | "tslib": "^2.6.2" 109 | } 110 | }, 111 | "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { 112 | "version": "2.2.0", 113 | "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", 114 | "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", 115 | "dependencies": { 116 | "tslib": "^2.6.2" 117 | }, 118 | "engines": { 119 | "node": ">=14.0.0" 120 | } 121 | }, 122 | "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { 123 | "version": "2.2.0", 124 | "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", 125 | "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", 126 | "dependencies": { 127 | "@smithy/is-array-buffer": "^2.2.0", 128 | "tslib": "^2.6.2" 129 | }, 130 | "engines": { 131 | "node": ">=14.0.0" 132 | } 133 | }, 134 | "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { 135 | "version": "2.3.0", 136 | "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", 137 | "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", 138 | "dependencies": { 139 | "@smithy/util-buffer-from": "^2.2.0", 140 | "tslib": "^2.6.2" 141 | }, 142 | "engines": { 143 | "node": ">=14.0.0" 144 | } 145 | }, 146 | "node_modules/@aws-sdk/client-sso": { 147 | "version": "3.670.0", 148 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.670.0.tgz", 149 | "integrity": "sha512-J+oz6uSsDvk4pimMDnKJb1wsV216zTrejvMTIL4RhUD1QPIVVOpteTdUShcjZUIZnkcJZGI+cym/SFK0kuzTpg==", 150 | "dependencies": { 151 | "@aws-crypto/sha256-browser": "5.2.0", 152 | "@aws-crypto/sha256-js": "5.2.0", 153 | "@aws-sdk/core": "3.667.0", 154 | "@aws-sdk/middleware-host-header": "3.667.0", 155 | "@aws-sdk/middleware-logger": "3.667.0", 156 | "@aws-sdk/middleware-recursion-detection": "3.667.0", 157 | "@aws-sdk/middleware-user-agent": "3.669.0", 158 | "@aws-sdk/region-config-resolver": "3.667.0", 159 | "@aws-sdk/types": "3.667.0", 160 | "@aws-sdk/util-endpoints": "3.667.0", 161 | "@aws-sdk/util-user-agent-browser": "3.670.0", 162 | "@aws-sdk/util-user-agent-node": "3.669.0", 163 | "@smithy/config-resolver": "^3.0.9", 164 | "@smithy/core": "^2.4.8", 165 | "@smithy/fetch-http-handler": "^3.2.9", 166 | "@smithy/hash-node": "^3.0.7", 167 | "@smithy/invalid-dependency": "^3.0.7", 168 | "@smithy/middleware-content-length": "^3.0.9", 169 | "@smithy/middleware-endpoint": "^3.1.4", 170 | "@smithy/middleware-retry": "^3.0.23", 171 | "@smithy/middleware-serde": "^3.0.7", 172 | "@smithy/middleware-stack": "^3.0.7", 173 | "@smithy/node-config-provider": "^3.1.8", 174 | "@smithy/node-http-handler": "^3.2.4", 175 | "@smithy/protocol-http": "^4.1.4", 176 | "@smithy/smithy-client": "^3.4.0", 177 | "@smithy/types": "^3.5.0", 178 | "@smithy/url-parser": "^3.0.7", 179 | "@smithy/util-base64": "^3.0.0", 180 | "@smithy/util-body-length-browser": "^3.0.0", 181 | "@smithy/util-body-length-node": "^3.0.0", 182 | "@smithy/util-defaults-mode-browser": "^3.0.23", 183 | "@smithy/util-defaults-mode-node": "^3.0.23", 184 | "@smithy/util-endpoints": "^2.1.3", 185 | "@smithy/util-middleware": "^3.0.7", 186 | "@smithy/util-retry": "^3.0.7", 187 | "@smithy/util-utf8": "^3.0.0", 188 | "tslib": "^2.6.2" 189 | }, 190 | "engines": { 191 | "node": ">=16.0.0" 192 | } 193 | }, 194 | "node_modules/@aws-sdk/client-sso-oidc": { 195 | "version": "3.670.0", 196 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.670.0.tgz", 197 | "integrity": "sha512-4qDK2L36Q4J1lfemaHHd9ZxqKRaos3STp44qPAHf/8QyX6Uk5sXgZNVO2yWM7SIEtVKwwBh/fZAsdBkGPBfZcw==", 198 | "dependencies": { 199 | "@aws-crypto/sha256-browser": "5.2.0", 200 | "@aws-crypto/sha256-js": "5.2.0", 201 | "@aws-sdk/core": "3.667.0", 202 | "@aws-sdk/credential-provider-node": "3.670.0", 203 | "@aws-sdk/middleware-host-header": "3.667.0", 204 | "@aws-sdk/middleware-logger": "3.667.0", 205 | "@aws-sdk/middleware-recursion-detection": "3.667.0", 206 | "@aws-sdk/middleware-user-agent": "3.669.0", 207 | "@aws-sdk/region-config-resolver": "3.667.0", 208 | "@aws-sdk/types": "3.667.0", 209 | "@aws-sdk/util-endpoints": "3.667.0", 210 | "@aws-sdk/util-user-agent-browser": "3.670.0", 211 | "@aws-sdk/util-user-agent-node": "3.669.0", 212 | "@smithy/config-resolver": "^3.0.9", 213 | "@smithy/core": "^2.4.8", 214 | "@smithy/fetch-http-handler": "^3.2.9", 215 | "@smithy/hash-node": "^3.0.7", 216 | "@smithy/invalid-dependency": "^3.0.7", 217 | "@smithy/middleware-content-length": "^3.0.9", 218 | "@smithy/middleware-endpoint": "^3.1.4", 219 | "@smithy/middleware-retry": "^3.0.23", 220 | "@smithy/middleware-serde": "^3.0.7", 221 | "@smithy/middleware-stack": "^3.0.7", 222 | "@smithy/node-config-provider": "^3.1.8", 223 | "@smithy/node-http-handler": "^3.2.4", 224 | "@smithy/protocol-http": "^4.1.4", 225 | "@smithy/smithy-client": "^3.4.0", 226 | "@smithy/types": "^3.5.0", 227 | "@smithy/url-parser": "^3.0.7", 228 | "@smithy/util-base64": "^3.0.0", 229 | "@smithy/util-body-length-browser": "^3.0.0", 230 | "@smithy/util-body-length-node": "^3.0.0", 231 | "@smithy/util-defaults-mode-browser": "^3.0.23", 232 | "@smithy/util-defaults-mode-node": "^3.0.23", 233 | "@smithy/util-endpoints": "^2.1.3", 234 | "@smithy/util-middleware": "^3.0.7", 235 | "@smithy/util-retry": "^3.0.7", 236 | "@smithy/util-utf8": "^3.0.0", 237 | "tslib": "^2.6.2" 238 | }, 239 | "engines": { 240 | "node": ">=16.0.0" 241 | }, 242 | "peerDependencies": { 243 | "@aws-sdk/client-sts": "^3.670.0" 244 | } 245 | }, 246 | "node_modules/@aws-sdk/client-sts": { 247 | "version": "3.670.0", 248 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.670.0.tgz", 249 | "integrity": "sha512-bExrNo8ZVWorS3cjMZKQnA2HWqDmAzcZoSN/cPVoPFNkHwdl1lzPxvcLzmhpIr48JHgKfybBjrbluDZfIYeEog==", 250 | "dependencies": { 251 | "@aws-crypto/sha256-browser": "5.2.0", 252 | "@aws-crypto/sha256-js": "5.2.0", 253 | "@aws-sdk/client-sso-oidc": "3.670.0", 254 | "@aws-sdk/core": "3.667.0", 255 | "@aws-sdk/credential-provider-node": "3.670.0", 256 | "@aws-sdk/middleware-host-header": "3.667.0", 257 | "@aws-sdk/middleware-logger": "3.667.0", 258 | "@aws-sdk/middleware-recursion-detection": "3.667.0", 259 | "@aws-sdk/middleware-user-agent": "3.669.0", 260 | "@aws-sdk/region-config-resolver": "3.667.0", 261 | "@aws-sdk/types": "3.667.0", 262 | "@aws-sdk/util-endpoints": "3.667.0", 263 | "@aws-sdk/util-user-agent-browser": "3.670.0", 264 | "@aws-sdk/util-user-agent-node": "3.669.0", 265 | "@smithy/config-resolver": "^3.0.9", 266 | "@smithy/core": "^2.4.8", 267 | "@smithy/fetch-http-handler": "^3.2.9", 268 | "@smithy/hash-node": "^3.0.7", 269 | "@smithy/invalid-dependency": "^3.0.7", 270 | "@smithy/middleware-content-length": "^3.0.9", 271 | "@smithy/middleware-endpoint": "^3.1.4", 272 | "@smithy/middleware-retry": "^3.0.23", 273 | "@smithy/middleware-serde": "^3.0.7", 274 | "@smithy/middleware-stack": "^3.0.7", 275 | "@smithy/node-config-provider": "^3.1.8", 276 | "@smithy/node-http-handler": "^3.2.4", 277 | "@smithy/protocol-http": "^4.1.4", 278 | "@smithy/smithy-client": "^3.4.0", 279 | "@smithy/types": "^3.5.0", 280 | "@smithy/url-parser": "^3.0.7", 281 | "@smithy/util-base64": "^3.0.0", 282 | "@smithy/util-body-length-browser": "^3.0.0", 283 | "@smithy/util-body-length-node": "^3.0.0", 284 | "@smithy/util-defaults-mode-browser": "^3.0.23", 285 | "@smithy/util-defaults-mode-node": "^3.0.23", 286 | "@smithy/util-endpoints": "^2.1.3", 287 | "@smithy/util-middleware": "^3.0.7", 288 | "@smithy/util-retry": "^3.0.7", 289 | "@smithy/util-utf8": "^3.0.0", 290 | "tslib": "^2.6.2" 291 | }, 292 | "engines": { 293 | "node": ">=16.0.0" 294 | } 295 | }, 296 | "node_modules/@aws-sdk/core": { 297 | "version": "3.667.0", 298 | "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.667.0.tgz", 299 | "integrity": "sha512-pMcDVI7Tmdsc8R3sDv0Omj/4iRParGY+uJtAfF669WnZfDfaBQaix2Mq7+Mu08vdjqO9K3gicFvjk9S1VLmOKA==", 300 | "dependencies": { 301 | "@aws-sdk/types": "3.667.0", 302 | "@smithy/core": "^2.4.8", 303 | "@smithy/node-config-provider": "^3.1.8", 304 | "@smithy/property-provider": "^3.1.7", 305 | "@smithy/protocol-http": "^4.1.4", 306 | "@smithy/signature-v4": "^4.2.0", 307 | "@smithy/smithy-client": "^3.4.0", 308 | "@smithy/types": "^3.5.0", 309 | "@smithy/util-middleware": "^3.0.7", 310 | "fast-xml-parser": "4.4.1", 311 | "tslib": "^2.6.2" 312 | }, 313 | "engines": { 314 | "node": ">=16.0.0" 315 | } 316 | }, 317 | "node_modules/@aws-sdk/credential-provider-env": { 318 | "version": "3.667.0", 319 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.667.0.tgz", 320 | "integrity": "sha512-zZbrkkaPc54WXm+QAnpuv0LPNfsts0HPPd+oCECGs7IQRaFsGj187cwvPg9RMWDFZqpm64MdBDoA8OQHsqzYCw==", 321 | "dependencies": { 322 | "@aws-sdk/core": "3.667.0", 323 | "@aws-sdk/types": "3.667.0", 324 | "@smithy/property-provider": "^3.1.7", 325 | "@smithy/types": "^3.5.0", 326 | "tslib": "^2.6.2" 327 | }, 328 | "engines": { 329 | "node": ">=16.0.0" 330 | } 331 | }, 332 | "node_modules/@aws-sdk/credential-provider-http": { 333 | "version": "3.667.0", 334 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.667.0.tgz", 335 | "integrity": "sha512-sjtybFfERZWiqTY7fswBxKQLvUkiCucOWyqh3IaPo/4nE1PXRnaZCVG0+kRBPrYIxWqiVwytvZzMJy8sVZcG0A==", 336 | "dependencies": { 337 | "@aws-sdk/core": "3.667.0", 338 | "@aws-sdk/types": "3.667.0", 339 | "@smithy/fetch-http-handler": "^3.2.9", 340 | "@smithy/node-http-handler": "^3.2.4", 341 | "@smithy/property-provider": "^3.1.7", 342 | "@smithy/protocol-http": "^4.1.4", 343 | "@smithy/smithy-client": "^3.4.0", 344 | "@smithy/types": "^3.5.0", 345 | "@smithy/util-stream": "^3.1.9", 346 | "tslib": "^2.6.2" 347 | }, 348 | "engines": { 349 | "node": ">=16.0.0" 350 | } 351 | }, 352 | "node_modules/@aws-sdk/credential-provider-ini": { 353 | "version": "3.670.0", 354 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.670.0.tgz", 355 | "integrity": "sha512-TB1gacUj75leaTt2JsCTzygDSIk4ksv9uZoR7VenlgFPRktyOeT+fapwIVBeB2Qg7b9uxAY2K5XkKstDZyBEEw==", 356 | "dependencies": { 357 | "@aws-sdk/core": "3.667.0", 358 | "@aws-sdk/credential-provider-env": "3.667.0", 359 | "@aws-sdk/credential-provider-http": "3.667.0", 360 | "@aws-sdk/credential-provider-process": "3.667.0", 361 | "@aws-sdk/credential-provider-sso": "3.670.0", 362 | "@aws-sdk/credential-provider-web-identity": "3.667.0", 363 | "@aws-sdk/types": "3.667.0", 364 | "@smithy/credential-provider-imds": "^3.2.4", 365 | "@smithy/property-provider": "^3.1.7", 366 | "@smithy/shared-ini-file-loader": "^3.1.8", 367 | "@smithy/types": "^3.5.0", 368 | "tslib": "^2.6.2" 369 | }, 370 | "engines": { 371 | "node": ">=16.0.0" 372 | }, 373 | "peerDependencies": { 374 | "@aws-sdk/client-sts": "^3.670.0" 375 | } 376 | }, 377 | "node_modules/@aws-sdk/credential-provider-node": { 378 | "version": "3.670.0", 379 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.670.0.tgz", 380 | "integrity": "sha512-zwNrRYzubk4CaZ7zebeDhxsm8QtNWkbGKopZPOaZSnd5uqUGRcmx4ccVRngWUK68XDP44aEUWC8iU5Pc7btpHQ==", 381 | "dependencies": { 382 | "@aws-sdk/credential-provider-env": "3.667.0", 383 | "@aws-sdk/credential-provider-http": "3.667.0", 384 | "@aws-sdk/credential-provider-ini": "3.670.0", 385 | "@aws-sdk/credential-provider-process": "3.667.0", 386 | "@aws-sdk/credential-provider-sso": "3.670.0", 387 | "@aws-sdk/credential-provider-web-identity": "3.667.0", 388 | "@aws-sdk/types": "3.667.0", 389 | "@smithy/credential-provider-imds": "^3.2.4", 390 | "@smithy/property-provider": "^3.1.7", 391 | "@smithy/shared-ini-file-loader": "^3.1.8", 392 | "@smithy/types": "^3.5.0", 393 | "tslib": "^2.6.2" 394 | }, 395 | "engines": { 396 | "node": ">=16.0.0" 397 | } 398 | }, 399 | "node_modules/@aws-sdk/credential-provider-process": { 400 | "version": "3.667.0", 401 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.667.0.tgz", 402 | "integrity": "sha512-HZHnvop32fKgsNHkdhVaul7UzQ25sEc0j9yqA4bjhtbk0ECl42kj3f1pJ+ZU/YD9ut8lMJs/vVqiOdNThVdeBw==", 403 | "dependencies": { 404 | "@aws-sdk/core": "3.667.0", 405 | "@aws-sdk/types": "3.667.0", 406 | "@smithy/property-provider": "^3.1.7", 407 | "@smithy/shared-ini-file-loader": "^3.1.8", 408 | "@smithy/types": "^3.5.0", 409 | "tslib": "^2.6.2" 410 | }, 411 | "engines": { 412 | "node": ">=16.0.0" 413 | } 414 | }, 415 | "node_modules/@aws-sdk/credential-provider-sso": { 416 | "version": "3.670.0", 417 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.670.0.tgz", 418 | "integrity": "sha512-5PkA8BOy4q57Vhe9AESoHKZ7vjRbElNPKjXA4qC01xY+DitClRFz4O3B9sMzFp0PHlz9nDVSXXKgq0yzF/nAag==", 419 | "dependencies": { 420 | "@aws-sdk/client-sso": "3.670.0", 421 | "@aws-sdk/core": "3.667.0", 422 | "@aws-sdk/token-providers": "3.667.0", 423 | "@aws-sdk/types": "3.667.0", 424 | "@smithy/property-provider": "^3.1.7", 425 | "@smithy/shared-ini-file-loader": "^3.1.8", 426 | "@smithy/types": "^3.5.0", 427 | "tslib": "^2.6.2" 428 | }, 429 | "engines": { 430 | "node": ">=16.0.0" 431 | } 432 | }, 433 | "node_modules/@aws-sdk/credential-provider-web-identity": { 434 | "version": "3.667.0", 435 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.667.0.tgz", 436 | "integrity": "sha512-t8CFlZMD/1p/8Cli3rvRiTJpjr/8BO64gw166AHgFZYSN2h95L2l1tcW0jpsc3PprA32nLg1iQVKYt4WGM4ugw==", 437 | "dependencies": { 438 | "@aws-sdk/core": "3.667.0", 439 | "@aws-sdk/types": "3.667.0", 440 | "@smithy/property-provider": "^3.1.7", 441 | "@smithy/types": "^3.5.0", 442 | "tslib": "^2.6.2" 443 | }, 444 | "engines": { 445 | "node": ">=16.0.0" 446 | }, 447 | "peerDependencies": { 448 | "@aws-sdk/client-sts": "^3.667.0" 449 | } 450 | }, 451 | "node_modules/@aws-sdk/middleware-host-header": { 452 | "version": "3.667.0", 453 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.667.0.tgz", 454 | "integrity": "sha512-Z7fIAMQnPegs7JjAQvlOeWXwpMRfegh5eCoIP6VLJIeR6DLfYKbP35JBtt98R6DXslrN2RsbTogjbxPEDQfw1w==", 455 | "dependencies": { 456 | "@aws-sdk/types": "3.667.0", 457 | "@smithy/protocol-http": "^4.1.4", 458 | "@smithy/types": "^3.5.0", 459 | "tslib": "^2.6.2" 460 | }, 461 | "engines": { 462 | "node": ">=16.0.0" 463 | } 464 | }, 465 | "node_modules/@aws-sdk/middleware-logger": { 466 | "version": "3.667.0", 467 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.667.0.tgz", 468 | "integrity": "sha512-PtTRNpNm/5c746jRgZCNg4X9xEJIwggkGJrF0GP9AB1ANg4pc/sF2Fvn1NtqPe9wtQ2stunJprnm5WkCHN7QiA==", 469 | "dependencies": { 470 | "@aws-sdk/types": "3.667.0", 471 | "@smithy/types": "^3.5.0", 472 | "tslib": "^2.6.2" 473 | }, 474 | "engines": { 475 | "node": ">=16.0.0" 476 | } 477 | }, 478 | "node_modules/@aws-sdk/middleware-recursion-detection": { 479 | "version": "3.667.0", 480 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.667.0.tgz", 481 | "integrity": "sha512-U5glWD3ehFohzpUpopLtmqAlDurGWo2wRGPNgi4SwhWU7UDt6LS7E/UvJjqC0CUrjlzOw+my2A+Ncf+fisMhxQ==", 482 | "dependencies": { 483 | "@aws-sdk/types": "3.667.0", 484 | "@smithy/protocol-http": "^4.1.4", 485 | "@smithy/types": "^3.5.0", 486 | "tslib": "^2.6.2" 487 | }, 488 | "engines": { 489 | "node": ">=16.0.0" 490 | } 491 | }, 492 | "node_modules/@aws-sdk/middleware-user-agent": { 493 | "version": "3.669.0", 494 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.669.0.tgz", 495 | "integrity": "sha512-K8ScPi45zjJrj5Y2gRqVsvKKQCQbvQBfYGcBw9ZOx9TTavH80bOCBjWg/GFnvs4f37tqVc1wMN2oGvcTF6HveQ==", 496 | "dependencies": { 497 | "@aws-sdk/core": "3.667.0", 498 | "@aws-sdk/types": "3.667.0", 499 | "@aws-sdk/util-endpoints": "3.667.0", 500 | "@smithy/core": "^2.4.8", 501 | "@smithy/protocol-http": "^4.1.4", 502 | "@smithy/types": "^3.5.0", 503 | "tslib": "^2.6.2" 504 | }, 505 | "engines": { 506 | "node": ">=16.0.0" 507 | } 508 | }, 509 | "node_modules/@aws-sdk/region-config-resolver": { 510 | "version": "3.667.0", 511 | "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.667.0.tgz", 512 | "integrity": "sha512-iNr+JhhA902JMKHG9IwT9YdaEx6KGl6vjAL5BRNeOjfj4cZYMog6Lz/IlfOAltMtT0w88DAHDEFrBd2uO0l2eg==", 513 | "dependencies": { 514 | "@aws-sdk/types": "3.667.0", 515 | "@smithy/node-config-provider": "^3.1.8", 516 | "@smithy/types": "^3.5.0", 517 | "@smithy/util-config-provider": "^3.0.0", 518 | "@smithy/util-middleware": "^3.0.7", 519 | "tslib": "^2.6.2" 520 | }, 521 | "engines": { 522 | "node": ">=16.0.0" 523 | } 524 | }, 525 | "node_modules/@aws-sdk/shared-ini-file-loader": { 526 | "version": "3.374.0", 527 | "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.374.0.tgz", 528 | "integrity": "sha512-r3mNf+GAsnJQGh2nssPIXdOMKSn/6v1vPPWEHC2Dy0uxVdeBRxlJLVGPt4QtlwX2dT2hnIttUh/vY9yuJRP4kg==", 529 | "deprecated": "This package has moved to @smithy/shared-ini-file-loader", 530 | "dependencies": { 531 | "@smithy/shared-ini-file-loader": "^1.0.1", 532 | "tslib": "^2.5.0" 533 | }, 534 | "engines": { 535 | "node": ">=14.0.0" 536 | } 537 | }, 538 | "node_modules/@aws-sdk/shared-ini-file-loader/node_modules/@smithy/shared-ini-file-loader": { 539 | "version": "1.1.0", 540 | "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-1.1.0.tgz", 541 | "integrity": "sha512-S/v33zvCWzFyGZGlsEF0XsZtNNR281UhR7byk3nRfsgw5lGpg51rK/zjMgulM+h6NSuXaFILaYrw1I1v4kMcuA==", 542 | "dependencies": { 543 | "@smithy/types": "^1.2.0", 544 | "tslib": "^2.5.0" 545 | }, 546 | "engines": { 547 | "node": ">=14.0.0" 548 | } 549 | }, 550 | "node_modules/@aws-sdk/shared-ini-file-loader/node_modules/@smithy/types": { 551 | "version": "1.2.0", 552 | "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", 553 | "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", 554 | "dependencies": { 555 | "tslib": "^2.5.0" 556 | }, 557 | "engines": { 558 | "node": ">=14.0.0" 559 | } 560 | }, 561 | "node_modules/@aws-sdk/token-providers": { 562 | "version": "3.667.0", 563 | "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.667.0.tgz", 564 | "integrity": "sha512-ZecJlG8p6D4UTYlBHwOWX6nknVtw/OBJ3yPXTSajBjhUlj9lE2xvejI8gl4rqkyLXk7z3bki+KR4tATbMaM9yg==", 565 | "dependencies": { 566 | "@aws-sdk/types": "3.667.0", 567 | "@smithy/property-provider": "^3.1.7", 568 | "@smithy/shared-ini-file-loader": "^3.1.8", 569 | "@smithy/types": "^3.5.0", 570 | "tslib": "^2.6.2" 571 | }, 572 | "engines": { 573 | "node": ">=16.0.0" 574 | }, 575 | "peerDependencies": { 576 | "@aws-sdk/client-sso-oidc": "^3.667.0" 577 | } 578 | }, 579 | "node_modules/@aws-sdk/types": { 580 | "version": "3.667.0", 581 | "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.667.0.tgz", 582 | "integrity": "sha512-gYq0xCsqFfQaSL/yT1Gl1vIUjtsg7d7RhnUfsXaHt8xTxOKRTdH9GjbesBjXOzgOvB0W0vfssfreSNGFlOOMJg==", 583 | "dependencies": { 584 | "@smithy/types": "^3.5.0", 585 | "tslib": "^2.6.2" 586 | }, 587 | "engines": { 588 | "node": ">=16.0.0" 589 | } 590 | }, 591 | "node_modules/@aws-sdk/util-endpoints": { 592 | "version": "3.667.0", 593 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.667.0.tgz", 594 | "integrity": "sha512-X22SYDAuQJWnkF1/q17pkX3nGw5XMD9YEUbmt87vUnRq7iyJ3JOpl6UKOBeUBaL838wA5yzdbinmCITJ/VZ1QA==", 595 | "dependencies": { 596 | "@aws-sdk/types": "3.667.0", 597 | "@smithy/types": "^3.5.0", 598 | "@smithy/util-endpoints": "^2.1.3", 599 | "tslib": "^2.6.2" 600 | }, 601 | "engines": { 602 | "node": ">=16.0.0" 603 | } 604 | }, 605 | "node_modules/@aws-sdk/util-locate-window": { 606 | "version": "3.568.0", 607 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.568.0.tgz", 608 | "integrity": "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==", 609 | "dependencies": { 610 | "tslib": "^2.6.2" 611 | }, 612 | "engines": { 613 | "node": ">=16.0.0" 614 | } 615 | }, 616 | "node_modules/@aws-sdk/util-user-agent-browser": { 617 | "version": "3.670.0", 618 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.670.0.tgz", 619 | "integrity": "sha512-iRynWWazqEcCKwGMcQcywKTDLdLvqts1Yx474U64I9OKQXXwhOwhXbF5CAPSRta86lkVNAVYJa/0Bsv45pNn1A==", 620 | "dependencies": { 621 | "@aws-sdk/types": "3.667.0", 622 | "@smithy/types": "^3.5.0", 623 | "bowser": "^2.11.0", 624 | "tslib": "^2.6.2" 625 | } 626 | }, 627 | "node_modules/@aws-sdk/util-user-agent-node": { 628 | "version": "3.669.0", 629 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.669.0.tgz", 630 | "integrity": "sha512-9jxCYrgggy2xd44ZASqI7AMiRVaSiFp+06Kg8BQSU0ijKpBJlwcsqIS8pDT/n6LxuOw2eV5ipvM2C0r1iKzrGA==", 631 | "dependencies": { 632 | "@aws-sdk/middleware-user-agent": "3.669.0", 633 | "@aws-sdk/types": "3.667.0", 634 | "@smithy/node-config-provider": "^3.1.8", 635 | "@smithy/types": "^3.5.0", 636 | "tslib": "^2.6.2" 637 | }, 638 | "engines": { 639 | "node": ">=16.0.0" 640 | }, 641 | "peerDependencies": { 642 | "aws-crt": ">=1.0.0" 643 | }, 644 | "peerDependenciesMeta": { 645 | "aws-crt": { 646 | "optional": true 647 | } 648 | } 649 | }, 650 | "node_modules/@es-joy/jsdoccomment": { 651 | "version": "0.49.0", 652 | "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", 653 | "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", 654 | "dev": true, 655 | "dependencies": { 656 | "comment-parser": "1.4.1", 657 | "esquery": "^1.6.0", 658 | "jsdoc-type-pratt-parser": "~4.1.0" 659 | }, 660 | "engines": { 661 | "node": ">=16" 662 | } 663 | }, 664 | "node_modules/@eslint-community/eslint-utils": { 665 | "version": "4.4.0", 666 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 667 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 668 | "dev": true, 669 | "dependencies": { 670 | "eslint-visitor-keys": "^3.3.0" 671 | }, 672 | "engines": { 673 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 674 | }, 675 | "peerDependencies": { 676 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 677 | } 678 | }, 679 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 680 | "version": "3.4.3", 681 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 682 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 683 | "dev": true, 684 | "engines": { 685 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 686 | }, 687 | "funding": { 688 | "url": "https://opencollective.com/eslint" 689 | } 690 | }, 691 | "node_modules/@eslint-community/regexpp": { 692 | "version": "4.11.1", 693 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", 694 | "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", 695 | "dev": true, 696 | "engines": { 697 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 698 | } 699 | }, 700 | "node_modules/@eslint/config-array": { 701 | "version": "0.18.0", 702 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", 703 | "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", 704 | "dev": true, 705 | "dependencies": { 706 | "@eslint/object-schema": "^2.1.4", 707 | "debug": "^4.3.1", 708 | "minimatch": "^3.1.2" 709 | }, 710 | "engines": { 711 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 712 | } 713 | }, 714 | "node_modules/@eslint/core": { 715 | "version": "0.6.0", 716 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", 717 | "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", 718 | "dev": true, 719 | "engines": { 720 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 721 | } 722 | }, 723 | "node_modules/@eslint/eslintrc": { 724 | "version": "3.1.0", 725 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", 726 | "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", 727 | "dev": true, 728 | "dependencies": { 729 | "ajv": "^6.12.4", 730 | "debug": "^4.3.2", 731 | "espree": "^10.0.1", 732 | "globals": "^14.0.0", 733 | "ignore": "^5.2.0", 734 | "import-fresh": "^3.2.1", 735 | "js-yaml": "^4.1.0", 736 | "minimatch": "^3.1.2", 737 | "strip-json-comments": "^3.1.1" 738 | }, 739 | "engines": { 740 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 741 | }, 742 | "funding": { 743 | "url": "https://opencollective.com/eslint" 744 | } 745 | }, 746 | "node_modules/@eslint/eslintrc/node_modules/globals": { 747 | "version": "14.0.0", 748 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 749 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 750 | "dev": true, 751 | "engines": { 752 | "node": ">=18" 753 | }, 754 | "funding": { 755 | "url": "https://github.com/sponsors/sindresorhus" 756 | } 757 | }, 758 | "node_modules/@eslint/js": { 759 | "version": "9.12.0", 760 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", 761 | "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", 762 | "dev": true, 763 | "engines": { 764 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 765 | } 766 | }, 767 | "node_modules/@eslint/object-schema": { 768 | "version": "2.1.4", 769 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", 770 | "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", 771 | "dev": true, 772 | "engines": { 773 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 774 | } 775 | }, 776 | "node_modules/@eslint/plugin-kit": { 777 | "version": "0.2.0", 778 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", 779 | "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", 780 | "dev": true, 781 | "dependencies": { 782 | "levn": "^0.4.1" 783 | }, 784 | "engines": { 785 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 786 | } 787 | }, 788 | "node_modules/@humanfs/core": { 789 | "version": "0.19.0", 790 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", 791 | "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", 792 | "dev": true, 793 | "engines": { 794 | "node": ">=18.18.0" 795 | } 796 | }, 797 | "node_modules/@humanfs/node": { 798 | "version": "0.16.5", 799 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", 800 | "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", 801 | "dev": true, 802 | "dependencies": { 803 | "@humanfs/core": "^0.19.0", 804 | "@humanwhocodes/retry": "^0.3.0" 805 | }, 806 | "engines": { 807 | "node": ">=18.18.0" 808 | } 809 | }, 810 | "node_modules/@humanwhocodes/module-importer": { 811 | "version": "1.0.1", 812 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 813 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 814 | "dev": true, 815 | "engines": { 816 | "node": ">=12.22" 817 | }, 818 | "funding": { 819 | "type": "github", 820 | "url": "https://github.com/sponsors/nzakas" 821 | } 822 | }, 823 | "node_modules/@humanwhocodes/retry": { 824 | "version": "0.3.1", 825 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 826 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 827 | "dev": true, 828 | "engines": { 829 | "node": ">=18.18" 830 | }, 831 | "funding": { 832 | "type": "github", 833 | "url": "https://github.com/sponsors/nzakas" 834 | } 835 | }, 836 | "node_modules/@isaacs/cliui": { 837 | "version": "8.0.2", 838 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 839 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 840 | "dev": true, 841 | "dependencies": { 842 | "string-width": "^5.1.2", 843 | "string-width-cjs": "npm:string-width@^4.2.0", 844 | "strip-ansi": "^7.0.1", 845 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 846 | "wrap-ansi": "^8.1.0", 847 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 848 | }, 849 | "engines": { 850 | "node": ">=12" 851 | } 852 | }, 853 | "node_modules/@pkgjs/parseargs": { 854 | "version": "0.11.0", 855 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 856 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 857 | "dev": true, 858 | "optional": true, 859 | "engines": { 860 | "node": ">=14" 861 | } 862 | }, 863 | "node_modules/@pkgr/core": { 864 | "version": "0.1.1", 865 | "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", 866 | "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", 867 | "dev": true, 868 | "engines": { 869 | "node": "^12.20.0 || ^14.18.0 || >=16.0.0" 870 | }, 871 | "funding": { 872 | "url": "https://opencollective.com/unts" 873 | } 874 | }, 875 | "node_modules/@smithy/abort-controller": { 876 | "version": "3.1.5", 877 | "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.5.tgz", 878 | "integrity": "sha512-DhNPnqTqPoG8aZ5dWkFOgsuY+i0GQ3CI6hMmvCoduNsnU9gUZWZBwGfDQsTTB7NvFPkom1df7jMIJWU90kuXXg==", 879 | "dependencies": { 880 | "@smithy/types": "^3.5.0", 881 | "tslib": "^2.6.2" 882 | }, 883 | "engines": { 884 | "node": ">=16.0.0" 885 | } 886 | }, 887 | "node_modules/@smithy/config-resolver": { 888 | "version": "3.0.9", 889 | "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.9.tgz", 890 | "integrity": "sha512-5d9oBf40qC7n2xUoHmntKLdqsyTMMo/r49+eqSIjJ73eDfEtljAxEhzIQ3bkgXJtR3xiv7YzMT/3FF3ORkjWdg==", 891 | "dependencies": { 892 | "@smithy/node-config-provider": "^3.1.8", 893 | "@smithy/types": "^3.5.0", 894 | "@smithy/util-config-provider": "^3.0.0", 895 | "@smithy/util-middleware": "^3.0.7", 896 | "tslib": "^2.6.2" 897 | }, 898 | "engines": { 899 | "node": ">=16.0.0" 900 | } 901 | }, 902 | "node_modules/@smithy/core": { 903 | "version": "2.4.8", 904 | "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.4.8.tgz", 905 | "integrity": "sha512-x4qWk7p/a4dcf7Vxb2MODIf4OIcqNbK182WxRvZ/3oKPrf/6Fdic5sSElhO1UtXpWKBazWfqg0ZEK9xN1DsuHA==", 906 | "dependencies": { 907 | "@smithy/middleware-endpoint": "^3.1.4", 908 | "@smithy/middleware-retry": "^3.0.23", 909 | "@smithy/middleware-serde": "^3.0.7", 910 | "@smithy/protocol-http": "^4.1.4", 911 | "@smithy/smithy-client": "^3.4.0", 912 | "@smithy/types": "^3.5.0", 913 | "@smithy/util-body-length-browser": "^3.0.0", 914 | "@smithy/util-middleware": "^3.0.7", 915 | "@smithy/util-utf8": "^3.0.0", 916 | "tslib": "^2.6.2" 917 | }, 918 | "engines": { 919 | "node": ">=16.0.0" 920 | } 921 | }, 922 | "node_modules/@smithy/credential-provider-imds": { 923 | "version": "3.2.4", 924 | "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.4.tgz", 925 | "integrity": "sha512-S9bb0EIokfYEuar4kEbLta+ivlKCWOCFsLZuilkNy9i0uEUEHSi47IFLPaxqqCl+0ftKmcOTHayY5nQhAuq7+w==", 926 | "dependencies": { 927 | "@smithy/node-config-provider": "^3.1.8", 928 | "@smithy/property-provider": "^3.1.7", 929 | "@smithy/types": "^3.5.0", 930 | "@smithy/url-parser": "^3.0.7", 931 | "tslib": "^2.6.2" 932 | }, 933 | "engines": { 934 | "node": ">=16.0.0" 935 | } 936 | }, 937 | "node_modules/@smithy/fetch-http-handler": { 938 | "version": "3.2.9", 939 | "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.9.tgz", 940 | "integrity": "sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A==", 941 | "dependencies": { 942 | "@smithy/protocol-http": "^4.1.4", 943 | "@smithy/querystring-builder": "^3.0.7", 944 | "@smithy/types": "^3.5.0", 945 | "@smithy/util-base64": "^3.0.0", 946 | "tslib": "^2.6.2" 947 | } 948 | }, 949 | "node_modules/@smithy/hash-node": { 950 | "version": "3.0.7", 951 | "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.7.tgz", 952 | "integrity": "sha512-SAGHN+QkrwcHFjfWzs/czX94ZEjPJ0CrWJS3M43WswDXVEuP4AVy9gJ3+AF6JQHZD13bojmuf/Ap/ItDeZ+Qfw==", 953 | "dependencies": { 954 | "@smithy/types": "^3.5.0", 955 | "@smithy/util-buffer-from": "^3.0.0", 956 | "@smithy/util-utf8": "^3.0.0", 957 | "tslib": "^2.6.2" 958 | }, 959 | "engines": { 960 | "node": ">=16.0.0" 961 | } 962 | }, 963 | "node_modules/@smithy/invalid-dependency": { 964 | "version": "3.0.7", 965 | "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.7.tgz", 966 | "integrity": "sha512-Bq00GsAhHeYSuZX8Kpu4sbI9agH2BNYnqUmmbTGWOhki9NVsWn2jFr896vvoTMH8KAjNX/ErC/8t5QHuEXG+IA==", 967 | "dependencies": { 968 | "@smithy/types": "^3.5.0", 969 | "tslib": "^2.6.2" 970 | } 971 | }, 972 | "node_modules/@smithy/is-array-buffer": { 973 | "version": "3.0.0", 974 | "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", 975 | "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", 976 | "dependencies": { 977 | "tslib": "^2.6.2" 978 | }, 979 | "engines": { 980 | "node": ">=16.0.0" 981 | } 982 | }, 983 | "node_modules/@smithy/middleware-content-length": { 984 | "version": "3.0.9", 985 | "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.9.tgz", 986 | "integrity": "sha512-t97PidoGElF9hTtLCrof32wfWMqC5g2SEJNxaVH3NjlatuNGsdxXRYO/t+RPnxA15RpYiS0f+zG7FuE2DeGgjA==", 987 | "dependencies": { 988 | "@smithy/protocol-http": "^4.1.4", 989 | "@smithy/types": "^3.5.0", 990 | "tslib": "^2.6.2" 991 | }, 992 | "engines": { 993 | "node": ">=16.0.0" 994 | } 995 | }, 996 | "node_modules/@smithy/middleware-endpoint": { 997 | "version": "3.1.4", 998 | "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.1.4.tgz", 999 | "integrity": "sha512-/ChcVHekAyzUbyPRI8CzPPLj6y8QRAfJngWcLMgsWxKVzw/RzBV69mSOzJYDD3pRwushA1+5tHtPF8fjmzBnrQ==", 1000 | "dependencies": { 1001 | "@smithy/middleware-serde": "^3.0.7", 1002 | "@smithy/node-config-provider": "^3.1.8", 1003 | "@smithy/shared-ini-file-loader": "^3.1.8", 1004 | "@smithy/types": "^3.5.0", 1005 | "@smithy/url-parser": "^3.0.7", 1006 | "@smithy/util-middleware": "^3.0.7", 1007 | "tslib": "^2.6.2" 1008 | }, 1009 | "engines": { 1010 | "node": ">=16.0.0" 1011 | } 1012 | }, 1013 | "node_modules/@smithy/middleware-retry": { 1014 | "version": "3.0.23", 1015 | "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.23.tgz", 1016 | "integrity": "sha512-x9PbGXxkcXIpm6L26qRSCC+eaYcHwybRmqU8LO/WM2RRlW0g8lz6FIiKbKgGvHuoK3dLZRiQVSQJveiCzwnA5A==", 1017 | "dependencies": { 1018 | "@smithy/node-config-provider": "^3.1.8", 1019 | "@smithy/protocol-http": "^4.1.4", 1020 | "@smithy/service-error-classification": "^3.0.7", 1021 | "@smithy/smithy-client": "^3.4.0", 1022 | "@smithy/types": "^3.5.0", 1023 | "@smithy/util-middleware": "^3.0.7", 1024 | "@smithy/util-retry": "^3.0.7", 1025 | "tslib": "^2.6.2", 1026 | "uuid": "^9.0.1" 1027 | }, 1028 | "engines": { 1029 | "node": ">=16.0.0" 1030 | } 1031 | }, 1032 | "node_modules/@smithy/middleware-serde": { 1033 | "version": "3.0.7", 1034 | "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.7.tgz", 1035 | "integrity": "sha512-VytaagsQqtH2OugzVTq4qvjkLNbWehHfGcGr0JLJmlDRrNCeZoWkWsSOw1nhS/4hyUUWF/TLGGml4X/OnEep5g==", 1036 | "dependencies": { 1037 | "@smithy/types": "^3.5.0", 1038 | "tslib": "^2.6.2" 1039 | }, 1040 | "engines": { 1041 | "node": ">=16.0.0" 1042 | } 1043 | }, 1044 | "node_modules/@smithy/middleware-stack": { 1045 | "version": "3.0.7", 1046 | "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.7.tgz", 1047 | "integrity": "sha512-EyTbMCdqS1DoeQsO4gI7z2Gzq1MoRFAeS8GkFYIwbedB7Lp5zlLHJdg+56tllIIG5Hnf9ZWX48YKSHlsKvugGA==", 1048 | "dependencies": { 1049 | "@smithy/types": "^3.5.0", 1050 | "tslib": "^2.6.2" 1051 | }, 1052 | "engines": { 1053 | "node": ">=16.0.0" 1054 | } 1055 | }, 1056 | "node_modules/@smithy/node-config-provider": { 1057 | "version": "3.1.8", 1058 | "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.8.tgz", 1059 | "integrity": "sha512-E0rU0DglpeJn5ge64mk8wTGEXcQwmpUTY5Zr7IzTpDLmHKiIamINERNZYrPQjg58Ck236sEKSwRSHA4CwshU6Q==", 1060 | "dependencies": { 1061 | "@smithy/property-provider": "^3.1.7", 1062 | "@smithy/shared-ini-file-loader": "^3.1.8", 1063 | "@smithy/types": "^3.5.0", 1064 | "tslib": "^2.6.2" 1065 | }, 1066 | "engines": { 1067 | "node": ">=16.0.0" 1068 | } 1069 | }, 1070 | "node_modules/@smithy/node-http-handler": { 1071 | "version": "3.2.4", 1072 | "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.2.4.tgz", 1073 | "integrity": "sha512-49reY3+JgLMFNm7uTAKBWiKCA6XSvkNp9FqhVmusm2jpVnHORYFeFZ704LShtqWfjZW/nhX+7Iexyb6zQfXYIQ==", 1074 | "dependencies": { 1075 | "@smithy/abort-controller": "^3.1.5", 1076 | "@smithy/protocol-http": "^4.1.4", 1077 | "@smithy/querystring-builder": "^3.0.7", 1078 | "@smithy/types": "^3.5.0", 1079 | "tslib": "^2.6.2" 1080 | }, 1081 | "engines": { 1082 | "node": ">=16.0.0" 1083 | } 1084 | }, 1085 | "node_modules/@smithy/property-provider": { 1086 | "version": "3.1.7", 1087 | "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.7.tgz", 1088 | "integrity": "sha512-QfzLi1GPMisY7bAM5hOUqBdGYnY5S2JAlr201pghksrQv139f8iiiMalXtjczIP5f6owxFn3MINLNUNvUkgtPw==", 1089 | "dependencies": { 1090 | "@smithy/types": "^3.5.0", 1091 | "tslib": "^2.6.2" 1092 | }, 1093 | "engines": { 1094 | "node": ">=16.0.0" 1095 | } 1096 | }, 1097 | "node_modules/@smithy/protocol-http": { 1098 | "version": "4.1.4", 1099 | "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.4.tgz", 1100 | "integrity": "sha512-MlWK8eqj0JlpZBnWmjQLqmFp71Ug00P+m72/1xQB3YByXD4zZ+y9N4hYrR0EDmrUCZIkyATWHOXFgtavwGDTzQ==", 1101 | "dependencies": { 1102 | "@smithy/types": "^3.5.0", 1103 | "tslib": "^2.6.2" 1104 | }, 1105 | "engines": { 1106 | "node": ">=16.0.0" 1107 | } 1108 | }, 1109 | "node_modules/@smithy/querystring-builder": { 1110 | "version": "3.0.7", 1111 | "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.7.tgz", 1112 | "integrity": "sha512-65RXGZZ20rzqqxTsChdqSpbhA6tdt5IFNgG6o7e1lnPVLCe6TNWQq4rTl4N87hTDD8mV4IxJJnvyE7brbnRkQw==", 1113 | "dependencies": { 1114 | "@smithy/types": "^3.5.0", 1115 | "@smithy/util-uri-escape": "^3.0.0", 1116 | "tslib": "^2.6.2" 1117 | }, 1118 | "engines": { 1119 | "node": ">=16.0.0" 1120 | } 1121 | }, 1122 | "node_modules/@smithy/querystring-parser": { 1123 | "version": "3.0.7", 1124 | "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.7.tgz", 1125 | "integrity": "sha512-Fouw4KJVWqqUVIu1gZW8BH2HakwLz6dvdrAhXeXfeymOBrZw+hcqaWs+cS1AZPVp4nlbeIujYrKA921ZW2WMPA==", 1126 | "dependencies": { 1127 | "@smithy/types": "^3.5.0", 1128 | "tslib": "^2.6.2" 1129 | }, 1130 | "engines": { 1131 | "node": ">=16.0.0" 1132 | } 1133 | }, 1134 | "node_modules/@smithy/service-error-classification": { 1135 | "version": "3.0.7", 1136 | "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.7.tgz", 1137 | "integrity": "sha512-91PRkTfiBf9hxkIchhRKJfl1rsplRDyBnmyFca3y0Z3x/q0JJN480S83LBd8R6sBCkm2bBbqw2FHp0Mbh+ecSA==", 1138 | "dependencies": { 1139 | "@smithy/types": "^3.5.0" 1140 | }, 1141 | "engines": { 1142 | "node": ">=16.0.0" 1143 | } 1144 | }, 1145 | "node_modules/@smithy/shared-ini-file-loader": { 1146 | "version": "3.1.8", 1147 | "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.8.tgz", 1148 | "integrity": "sha512-0NHdQiSkeGl0ICQKcJQ2lCOKH23Nb0EaAa7RDRId6ZqwXkw4LJyIyZ0t3iusD4bnKYDPLGy2/5e2rfUhrt0Acw==", 1149 | "dependencies": { 1150 | "@smithy/types": "^3.5.0", 1151 | "tslib": "^2.6.2" 1152 | }, 1153 | "engines": { 1154 | "node": ">=16.0.0" 1155 | } 1156 | }, 1157 | "node_modules/@smithy/signature-v4": { 1158 | "version": "4.2.0", 1159 | "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.0.tgz", 1160 | "integrity": "sha512-LafbclHNKnsorMgUkKm7Tk7oJ7xizsZ1VwqhGKqoCIrXh4fqDDp73fK99HOEEgcsQbtemmeY/BPv0vTVYYUNEQ==", 1161 | "dependencies": { 1162 | "@smithy/is-array-buffer": "^3.0.0", 1163 | "@smithy/protocol-http": "^4.1.4", 1164 | "@smithy/types": "^3.5.0", 1165 | "@smithy/util-hex-encoding": "^3.0.0", 1166 | "@smithy/util-middleware": "^3.0.7", 1167 | "@smithy/util-uri-escape": "^3.0.0", 1168 | "@smithy/util-utf8": "^3.0.0", 1169 | "tslib": "^2.6.2" 1170 | }, 1171 | "engines": { 1172 | "node": ">=16.0.0" 1173 | } 1174 | }, 1175 | "node_modules/@smithy/smithy-client": { 1176 | "version": "3.4.0", 1177 | "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.0.tgz", 1178 | "integrity": "sha512-nOfJ1nVQsxiP6srKt43r2My0Gp5PLWCW2ASqUioxIiGmu6d32v4Nekidiv5qOmmtzIrmaD+ADX5SKHUuhReeBQ==", 1179 | "dependencies": { 1180 | "@smithy/middleware-endpoint": "^3.1.4", 1181 | "@smithy/middleware-stack": "^3.0.7", 1182 | "@smithy/protocol-http": "^4.1.4", 1183 | "@smithy/types": "^3.5.0", 1184 | "@smithy/util-stream": "^3.1.9", 1185 | "tslib": "^2.6.2" 1186 | }, 1187 | "engines": { 1188 | "node": ">=16.0.0" 1189 | } 1190 | }, 1191 | "node_modules/@smithy/types": { 1192 | "version": "3.5.0", 1193 | "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.5.0.tgz", 1194 | "integrity": "sha512-QN0twHNfe8mNJdH9unwsCK13GURU7oEAZqkBI+rsvpv1jrmserO+WnLE7jidR9W/1dxwZ0u/CB01mV2Gms/K2Q==", 1195 | "dependencies": { 1196 | "tslib": "^2.6.2" 1197 | }, 1198 | "engines": { 1199 | "node": ">=16.0.0" 1200 | } 1201 | }, 1202 | "node_modules/@smithy/url-parser": { 1203 | "version": "3.0.7", 1204 | "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.7.tgz", 1205 | "integrity": "sha512-70UbSSR8J97c1rHZOWhl+VKiZDqHWxs/iW8ZHrHp5fCCPLSBE7GcUlUvKSle3Ca+J9LLbYCj/A79BxztBvAfpA==", 1206 | "dependencies": { 1207 | "@smithy/querystring-parser": "^3.0.7", 1208 | "@smithy/types": "^3.5.0", 1209 | "tslib": "^2.6.2" 1210 | } 1211 | }, 1212 | "node_modules/@smithy/util-base64": { 1213 | "version": "3.0.0", 1214 | "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", 1215 | "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", 1216 | "dependencies": { 1217 | "@smithy/util-buffer-from": "^3.0.0", 1218 | "@smithy/util-utf8": "^3.0.0", 1219 | "tslib": "^2.6.2" 1220 | }, 1221 | "engines": { 1222 | "node": ">=16.0.0" 1223 | } 1224 | }, 1225 | "node_modules/@smithy/util-body-length-browser": { 1226 | "version": "3.0.0", 1227 | "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", 1228 | "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", 1229 | "dependencies": { 1230 | "tslib": "^2.6.2" 1231 | } 1232 | }, 1233 | "node_modules/@smithy/util-body-length-node": { 1234 | "version": "3.0.0", 1235 | "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", 1236 | "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", 1237 | "dependencies": { 1238 | "tslib": "^2.6.2" 1239 | }, 1240 | "engines": { 1241 | "node": ">=16.0.0" 1242 | } 1243 | }, 1244 | "node_modules/@smithy/util-buffer-from": { 1245 | "version": "3.0.0", 1246 | "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", 1247 | "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", 1248 | "dependencies": { 1249 | "@smithy/is-array-buffer": "^3.0.0", 1250 | "tslib": "^2.6.2" 1251 | }, 1252 | "engines": { 1253 | "node": ">=16.0.0" 1254 | } 1255 | }, 1256 | "node_modules/@smithy/util-config-provider": { 1257 | "version": "3.0.0", 1258 | "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", 1259 | "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", 1260 | "dependencies": { 1261 | "tslib": "^2.6.2" 1262 | }, 1263 | "engines": { 1264 | "node": ">=16.0.0" 1265 | } 1266 | }, 1267 | "node_modules/@smithy/util-defaults-mode-browser": { 1268 | "version": "3.0.23", 1269 | "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.23.tgz", 1270 | "integrity": "sha512-Y07qslyRtXDP/C5aWKqxTPBl4YxplEELG3xRrz2dnAQ6Lq/FgNrcKWmV561nNaZmFH+EzeGOX3ZRMbU8p1T6Nw==", 1271 | "dependencies": { 1272 | "@smithy/property-provider": "^3.1.7", 1273 | "@smithy/smithy-client": "^3.4.0", 1274 | "@smithy/types": "^3.5.0", 1275 | "bowser": "^2.11.0", 1276 | "tslib": "^2.6.2" 1277 | }, 1278 | "engines": { 1279 | "node": ">= 10.0.0" 1280 | } 1281 | }, 1282 | "node_modules/@smithy/util-defaults-mode-node": { 1283 | "version": "3.0.23", 1284 | "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.23.tgz", 1285 | "integrity": "sha512-9Y4WH7f0vnDGuHUa4lGX9e2p+sMwODibsceSV6rfkZOvMC+BY3StB2LdO1NHafpsyHJLpwAgChxQ38tFyd6vkg==", 1286 | "dependencies": { 1287 | "@smithy/config-resolver": "^3.0.9", 1288 | "@smithy/credential-provider-imds": "^3.2.4", 1289 | "@smithy/node-config-provider": "^3.1.8", 1290 | "@smithy/property-provider": "^3.1.7", 1291 | "@smithy/smithy-client": "^3.4.0", 1292 | "@smithy/types": "^3.5.0", 1293 | "tslib": "^2.6.2" 1294 | }, 1295 | "engines": { 1296 | "node": ">= 10.0.0" 1297 | } 1298 | }, 1299 | "node_modules/@smithy/util-endpoints": { 1300 | "version": "2.1.3", 1301 | "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.3.tgz", 1302 | "integrity": "sha512-34eACeKov6jZdHqS5hxBMJ4KyWKztTMulhuQ2UdOoP6vVxMLrOKUqIXAwJe/wiWMhXhydLW664B02CNpQBQ4Aw==", 1303 | "dependencies": { 1304 | "@smithy/node-config-provider": "^3.1.8", 1305 | "@smithy/types": "^3.5.0", 1306 | "tslib": "^2.6.2" 1307 | }, 1308 | "engines": { 1309 | "node": ">=16.0.0" 1310 | } 1311 | }, 1312 | "node_modules/@smithy/util-hex-encoding": { 1313 | "version": "3.0.0", 1314 | "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", 1315 | "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", 1316 | "dependencies": { 1317 | "tslib": "^2.6.2" 1318 | }, 1319 | "engines": { 1320 | "node": ">=16.0.0" 1321 | } 1322 | }, 1323 | "node_modules/@smithy/util-middleware": { 1324 | "version": "3.0.7", 1325 | "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.7.tgz", 1326 | "integrity": "sha512-OVA6fv/3o7TMJTpTgOi1H5OTwnuUa8hzRzhSFDtZyNxi6OZ70L/FHattSmhE212I7b6WSOJAAmbYnvcjTHOJCA==", 1327 | "dependencies": { 1328 | "@smithy/types": "^3.5.0", 1329 | "tslib": "^2.6.2" 1330 | }, 1331 | "engines": { 1332 | "node": ">=16.0.0" 1333 | } 1334 | }, 1335 | "node_modules/@smithy/util-retry": { 1336 | "version": "3.0.7", 1337 | "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.7.tgz", 1338 | "integrity": "sha512-nh1ZO1vTeo2YX1plFPSe/OXaHkLAHza5jpokNiiKX2M5YpNUv6RxGJZhpfmiR4jSvVHCjIDmILjrxKmP+/Ghug==", 1339 | "dependencies": { 1340 | "@smithy/service-error-classification": "^3.0.7", 1341 | "@smithy/types": "^3.5.0", 1342 | "tslib": "^2.6.2" 1343 | }, 1344 | "engines": { 1345 | "node": ">=16.0.0" 1346 | } 1347 | }, 1348 | "node_modules/@smithy/util-stream": { 1349 | "version": "3.1.9", 1350 | "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.1.9.tgz", 1351 | "integrity": "sha512-7YAR0Ub3MwTMjDfjnup4qa6W8gygZMxikBhFMPESi6ASsl/rZJhwLpF/0k9TuezScCojsM0FryGdz4LZtjKPPQ==", 1352 | "dependencies": { 1353 | "@smithy/fetch-http-handler": "^3.2.9", 1354 | "@smithy/node-http-handler": "^3.2.4", 1355 | "@smithy/types": "^3.5.0", 1356 | "@smithy/util-base64": "^3.0.0", 1357 | "@smithy/util-buffer-from": "^3.0.0", 1358 | "@smithy/util-hex-encoding": "^3.0.0", 1359 | "@smithy/util-utf8": "^3.0.0", 1360 | "tslib": "^2.6.2" 1361 | }, 1362 | "engines": { 1363 | "node": ">=16.0.0" 1364 | } 1365 | }, 1366 | "node_modules/@smithy/util-uri-escape": { 1367 | "version": "3.0.0", 1368 | "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", 1369 | "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", 1370 | "dependencies": { 1371 | "tslib": "^2.6.2" 1372 | }, 1373 | "engines": { 1374 | "node": ">=16.0.0" 1375 | } 1376 | }, 1377 | "node_modules/@smithy/util-utf8": { 1378 | "version": "3.0.0", 1379 | "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", 1380 | "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", 1381 | "dependencies": { 1382 | "@smithy/util-buffer-from": "^3.0.0", 1383 | "tslib": "^2.6.2" 1384 | }, 1385 | "engines": { 1386 | "node": ">=16.0.0" 1387 | } 1388 | }, 1389 | "node_modules/@types/estree": { 1390 | "version": "1.0.6", 1391 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 1392 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 1393 | "dev": true 1394 | }, 1395 | "node_modules/@types/json-schema": { 1396 | "version": "7.0.15", 1397 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 1398 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 1399 | "dev": true 1400 | }, 1401 | "node_modules/acorn": { 1402 | "version": "8.13.0", 1403 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", 1404 | "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", 1405 | "dev": true, 1406 | "bin": { 1407 | "acorn": "bin/acorn" 1408 | }, 1409 | "engines": { 1410 | "node": ">=0.4.0" 1411 | } 1412 | }, 1413 | "node_modules/acorn-jsx": { 1414 | "version": "5.3.2", 1415 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 1416 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 1417 | "dev": true, 1418 | "peerDependencies": { 1419 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 1420 | } 1421 | }, 1422 | "node_modules/ajv": { 1423 | "version": "6.12.6", 1424 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1425 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1426 | "dev": true, 1427 | "dependencies": { 1428 | "fast-deep-equal": "^3.1.1", 1429 | "fast-json-stable-stringify": "^2.0.0", 1430 | "json-schema-traverse": "^0.4.1", 1431 | "uri-js": "^4.2.2" 1432 | }, 1433 | "funding": { 1434 | "type": "github", 1435 | "url": "https://github.com/sponsors/epoberezkin" 1436 | } 1437 | }, 1438 | "node_modules/ansi-regex": { 1439 | "version": "6.1.0", 1440 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", 1441 | "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", 1442 | "dev": true, 1443 | "engines": { 1444 | "node": ">=12" 1445 | }, 1446 | "funding": { 1447 | "url": "https://github.com/chalk/ansi-regex?sponsor=1" 1448 | } 1449 | }, 1450 | "node_modules/ansi-styles": { 1451 | "version": "4.3.0", 1452 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1453 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1454 | "dependencies": { 1455 | "color-convert": "^2.0.1" 1456 | }, 1457 | "engines": { 1458 | "node": ">=8" 1459 | }, 1460 | "funding": { 1461 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1462 | } 1463 | }, 1464 | "node_modules/anymatch": { 1465 | "version": "3.1.3", 1466 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 1467 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 1468 | "dev": true, 1469 | "dependencies": { 1470 | "normalize-path": "^3.0.0", 1471 | "picomatch": "^2.0.4" 1472 | }, 1473 | "engines": { 1474 | "node": ">= 8" 1475 | } 1476 | }, 1477 | "node_modules/are-docs-informative": { 1478 | "version": "0.0.2", 1479 | "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", 1480 | "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", 1481 | "dev": true, 1482 | "engines": { 1483 | "node": ">=14" 1484 | } 1485 | }, 1486 | "node_modules/argparse": { 1487 | "version": "2.0.1", 1488 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1489 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1490 | "dev": true 1491 | }, 1492 | "node_modules/balanced-match": { 1493 | "version": "1.0.2", 1494 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1495 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1496 | "dev": true 1497 | }, 1498 | "node_modules/binary-extensions": { 1499 | "version": "2.3.0", 1500 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", 1501 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", 1502 | "dev": true, 1503 | "engines": { 1504 | "node": ">=8" 1505 | }, 1506 | "funding": { 1507 | "url": "https://github.com/sponsors/sindresorhus" 1508 | } 1509 | }, 1510 | "node_modules/bowser": { 1511 | "version": "2.11.0", 1512 | "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", 1513 | "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" 1514 | }, 1515 | "node_modules/brace-expansion": { 1516 | "version": "1.1.11", 1517 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1518 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1519 | "dev": true, 1520 | "dependencies": { 1521 | "balanced-match": "^1.0.0", 1522 | "concat-map": "0.0.1" 1523 | } 1524 | }, 1525 | "node_modules/braces": { 1526 | "version": "3.0.3", 1527 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 1528 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 1529 | "dev": true, 1530 | "dependencies": { 1531 | "fill-range": "^7.1.1" 1532 | }, 1533 | "engines": { 1534 | "node": ">=8" 1535 | } 1536 | }, 1537 | "node_modules/callsites": { 1538 | "version": "3.1.0", 1539 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 1540 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 1541 | "dev": true, 1542 | "engines": { 1543 | "node": ">=6" 1544 | } 1545 | }, 1546 | "node_modules/chalk": { 1547 | "version": "4.1.2", 1548 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1549 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1550 | "dev": true, 1551 | "dependencies": { 1552 | "ansi-styles": "^4.1.0", 1553 | "supports-color": "^7.1.0" 1554 | }, 1555 | "engines": { 1556 | "node": ">=10" 1557 | }, 1558 | "funding": { 1559 | "url": "https://github.com/chalk/chalk?sponsor=1" 1560 | } 1561 | }, 1562 | "node_modules/chokidar": { 1563 | "version": "3.6.0", 1564 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", 1565 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", 1566 | "dev": true, 1567 | "dependencies": { 1568 | "anymatch": "~3.1.2", 1569 | "braces": "~3.0.2", 1570 | "glob-parent": "~5.1.2", 1571 | "is-binary-path": "~2.1.0", 1572 | "is-glob": "~4.0.1", 1573 | "normalize-path": "~3.0.0", 1574 | "readdirp": "~3.6.0" 1575 | }, 1576 | "engines": { 1577 | "node": ">= 8.10.0" 1578 | }, 1579 | "funding": { 1580 | "url": "https://paulmillr.com/funding/" 1581 | }, 1582 | "optionalDependencies": { 1583 | "fsevents": "~2.3.2" 1584 | } 1585 | }, 1586 | "node_modules/chokidar/node_modules/glob-parent": { 1587 | "version": "5.1.2", 1588 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1589 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1590 | "dev": true, 1591 | "dependencies": { 1592 | "is-glob": "^4.0.1" 1593 | }, 1594 | "engines": { 1595 | "node": ">= 6" 1596 | } 1597 | }, 1598 | "node_modules/cliui": { 1599 | "version": "8.0.1", 1600 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 1601 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 1602 | "dependencies": { 1603 | "string-width": "^4.2.0", 1604 | "strip-ansi": "^6.0.1", 1605 | "wrap-ansi": "^7.0.0" 1606 | }, 1607 | "engines": { 1608 | "node": ">=12" 1609 | } 1610 | }, 1611 | "node_modules/cliui/node_modules/ansi-regex": { 1612 | "version": "5.0.1", 1613 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1614 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1615 | "engines": { 1616 | "node": ">=8" 1617 | } 1618 | }, 1619 | "node_modules/cliui/node_modules/emoji-regex": { 1620 | "version": "8.0.0", 1621 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1622 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 1623 | }, 1624 | "node_modules/cliui/node_modules/string-width": { 1625 | "version": "4.2.3", 1626 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1627 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1628 | "dependencies": { 1629 | "emoji-regex": "^8.0.0", 1630 | "is-fullwidth-code-point": "^3.0.0", 1631 | "strip-ansi": "^6.0.1" 1632 | }, 1633 | "engines": { 1634 | "node": ">=8" 1635 | } 1636 | }, 1637 | "node_modules/cliui/node_modules/strip-ansi": { 1638 | "version": "6.0.1", 1639 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1640 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1641 | "dependencies": { 1642 | "ansi-regex": "^5.0.1" 1643 | }, 1644 | "engines": { 1645 | "node": ">=8" 1646 | } 1647 | }, 1648 | "node_modules/cliui/node_modules/wrap-ansi": { 1649 | "version": "7.0.0", 1650 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1651 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1652 | "dependencies": { 1653 | "ansi-styles": "^4.0.0", 1654 | "string-width": "^4.1.0", 1655 | "strip-ansi": "^6.0.0" 1656 | }, 1657 | "engines": { 1658 | "node": ">=10" 1659 | }, 1660 | "funding": { 1661 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 1662 | } 1663 | }, 1664 | "node_modules/color-convert": { 1665 | "version": "2.0.1", 1666 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1667 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1668 | "dependencies": { 1669 | "color-name": "~1.1.4" 1670 | }, 1671 | "engines": { 1672 | "node": ">=7.0.0" 1673 | } 1674 | }, 1675 | "node_modules/color-name": { 1676 | "version": "1.1.4", 1677 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1678 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 1679 | }, 1680 | "node_modules/comment-parser": { 1681 | "version": "1.4.1", 1682 | "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", 1683 | "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", 1684 | "dev": true, 1685 | "engines": { 1686 | "node": ">= 12.0.0" 1687 | } 1688 | }, 1689 | "node_modules/concat-map": { 1690 | "version": "0.0.1", 1691 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1692 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1693 | "dev": true 1694 | }, 1695 | "node_modules/cross-spawn": { 1696 | "version": "7.0.3", 1697 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 1698 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 1699 | "dev": true, 1700 | "dependencies": { 1701 | "path-key": "^3.1.0", 1702 | "shebang-command": "^2.0.0", 1703 | "which": "^2.0.1" 1704 | }, 1705 | "engines": { 1706 | "node": ">= 8" 1707 | } 1708 | }, 1709 | "node_modules/debug": { 1710 | "version": "4.3.7", 1711 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", 1712 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", 1713 | "dev": true, 1714 | "dependencies": { 1715 | "ms": "^2.1.3" 1716 | }, 1717 | "engines": { 1718 | "node": ">=6.0" 1719 | }, 1720 | "peerDependenciesMeta": { 1721 | "supports-color": { 1722 | "optional": true 1723 | } 1724 | } 1725 | }, 1726 | "node_modules/deep-is": { 1727 | "version": "0.1.4", 1728 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 1729 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 1730 | "dev": true 1731 | }, 1732 | "node_modules/eastasianwidth": { 1733 | "version": "0.2.0", 1734 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 1735 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 1736 | "dev": true 1737 | }, 1738 | "node_modules/emoji-regex": { 1739 | "version": "9.2.2", 1740 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 1741 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 1742 | "dev": true 1743 | }, 1744 | "node_modules/es-module-lexer": { 1745 | "version": "1.5.4", 1746 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", 1747 | "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", 1748 | "dev": true 1749 | }, 1750 | "node_modules/escalade": { 1751 | "version": "3.2.0", 1752 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 1753 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 1754 | "engines": { 1755 | "node": ">=6" 1756 | } 1757 | }, 1758 | "node_modules/escape-string-regexp": { 1759 | "version": "4.0.0", 1760 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1761 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1762 | "dev": true, 1763 | "engines": { 1764 | "node": ">=10" 1765 | }, 1766 | "funding": { 1767 | "url": "https://github.com/sponsors/sindresorhus" 1768 | } 1769 | }, 1770 | "node_modules/eslint": { 1771 | "version": "9.12.0", 1772 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", 1773 | "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", 1774 | "dev": true, 1775 | "dependencies": { 1776 | "@eslint-community/eslint-utils": "^4.2.0", 1777 | "@eslint-community/regexpp": "^4.11.0", 1778 | "@eslint/config-array": "^0.18.0", 1779 | "@eslint/core": "^0.6.0", 1780 | "@eslint/eslintrc": "^3.1.0", 1781 | "@eslint/js": "9.12.0", 1782 | "@eslint/plugin-kit": "^0.2.0", 1783 | "@humanfs/node": "^0.16.5", 1784 | "@humanwhocodes/module-importer": "^1.0.1", 1785 | "@humanwhocodes/retry": "^0.3.1", 1786 | "@types/estree": "^1.0.6", 1787 | "@types/json-schema": "^7.0.15", 1788 | "ajv": "^6.12.4", 1789 | "chalk": "^4.0.0", 1790 | "cross-spawn": "^7.0.2", 1791 | "debug": "^4.3.2", 1792 | "escape-string-regexp": "^4.0.0", 1793 | "eslint-scope": "^8.1.0", 1794 | "eslint-visitor-keys": "^4.1.0", 1795 | "espree": "^10.2.0", 1796 | "esquery": "^1.5.0", 1797 | "esutils": "^2.0.2", 1798 | "fast-deep-equal": "^3.1.3", 1799 | "file-entry-cache": "^8.0.0", 1800 | "find-up": "^5.0.0", 1801 | "glob-parent": "^6.0.2", 1802 | "ignore": "^5.2.0", 1803 | "imurmurhash": "^0.1.4", 1804 | "is-glob": "^4.0.0", 1805 | "json-stable-stringify-without-jsonify": "^1.0.1", 1806 | "lodash.merge": "^4.6.2", 1807 | "minimatch": "^3.1.2", 1808 | "natural-compare": "^1.4.0", 1809 | "optionator": "^0.9.3", 1810 | "text-table": "^0.2.0" 1811 | }, 1812 | "bin": { 1813 | "eslint": "bin/eslint.js" 1814 | }, 1815 | "engines": { 1816 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1817 | }, 1818 | "funding": { 1819 | "url": "https://eslint.org/donate" 1820 | }, 1821 | "peerDependencies": { 1822 | "jiti": "*" 1823 | }, 1824 | "peerDependenciesMeta": { 1825 | "jiti": { 1826 | "optional": true 1827 | } 1828 | } 1829 | }, 1830 | "node_modules/eslint-plugin-depend": { 1831 | "version": "0.11.0", 1832 | "resolved": "https://registry.npmjs.org/eslint-plugin-depend/-/eslint-plugin-depend-0.11.0.tgz", 1833 | "integrity": "sha512-IwF06BrcdYoELuFd18sdVHhvDfF23xbr8pG/ONqrwB4gXjJ7281mEDEmACKWyvMY63afph8+2aOLbeuvr9mbdg==", 1834 | "dev": true, 1835 | "dependencies": { 1836 | "fd-package-json": "^1.2.0", 1837 | "module-replacements": "^2.1.0", 1838 | "semver": "^7.6.3" 1839 | } 1840 | }, 1841 | "node_modules/eslint-plugin-jsdoc": { 1842 | "version": "50.4.1", 1843 | "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.4.1.tgz", 1844 | "integrity": "sha512-OXIq+JJQPCLAKL473/esioFOwbXyRE5MAQ4HbZjcp3e+K3zdxt2uDpGs3FR+WezUXNStzEtTfgx15T+JFrVwBA==", 1845 | "dev": true, 1846 | "dependencies": { 1847 | "@es-joy/jsdoccomment": "~0.49.0", 1848 | "are-docs-informative": "^0.0.2", 1849 | "comment-parser": "1.4.1", 1850 | "debug": "^4.3.6", 1851 | "escape-string-regexp": "^4.0.0", 1852 | "espree": "^10.1.0", 1853 | "esquery": "^1.6.0", 1854 | "parse-imports": "^2.1.1", 1855 | "semver": "^7.6.3", 1856 | "spdx-expression-parse": "^4.0.0", 1857 | "synckit": "^0.9.1" 1858 | }, 1859 | "engines": { 1860 | "node": ">=18" 1861 | }, 1862 | "peerDependencies": { 1863 | "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" 1864 | } 1865 | }, 1866 | "node_modules/eslint-scope": { 1867 | "version": "8.1.0", 1868 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", 1869 | "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", 1870 | "dev": true, 1871 | "dependencies": { 1872 | "esrecurse": "^4.3.0", 1873 | "estraverse": "^5.2.0" 1874 | }, 1875 | "engines": { 1876 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1877 | }, 1878 | "funding": { 1879 | "url": "https://opencollective.com/eslint" 1880 | } 1881 | }, 1882 | "node_modules/eslint-visitor-keys": { 1883 | "version": "4.1.0", 1884 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", 1885 | "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", 1886 | "dev": true, 1887 | "engines": { 1888 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1889 | }, 1890 | "funding": { 1891 | "url": "https://opencollective.com/eslint" 1892 | } 1893 | }, 1894 | "node_modules/espree": { 1895 | "version": "10.2.0", 1896 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", 1897 | "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", 1898 | "dev": true, 1899 | "dependencies": { 1900 | "acorn": "^8.12.0", 1901 | "acorn-jsx": "^5.3.2", 1902 | "eslint-visitor-keys": "^4.1.0" 1903 | }, 1904 | "engines": { 1905 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1906 | }, 1907 | "funding": { 1908 | "url": "https://opencollective.com/eslint" 1909 | } 1910 | }, 1911 | "node_modules/esquery": { 1912 | "version": "1.6.0", 1913 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 1914 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 1915 | "dev": true, 1916 | "dependencies": { 1917 | "estraverse": "^5.1.0" 1918 | }, 1919 | "engines": { 1920 | "node": ">=0.10" 1921 | } 1922 | }, 1923 | "node_modules/esrecurse": { 1924 | "version": "4.3.0", 1925 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1926 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1927 | "dev": true, 1928 | "dependencies": { 1929 | "estraverse": "^5.2.0" 1930 | }, 1931 | "engines": { 1932 | "node": ">=4.0" 1933 | } 1934 | }, 1935 | "node_modules/estraverse": { 1936 | "version": "5.3.0", 1937 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1938 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1939 | "dev": true, 1940 | "engines": { 1941 | "node": ">=4.0" 1942 | } 1943 | }, 1944 | "node_modules/esutils": { 1945 | "version": "2.0.3", 1946 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1947 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1948 | "dev": true, 1949 | "engines": { 1950 | "node": ">=0.10.0" 1951 | } 1952 | }, 1953 | "node_modules/fast-deep-equal": { 1954 | "version": "3.1.3", 1955 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1956 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1957 | "dev": true 1958 | }, 1959 | "node_modules/fast-json-stable-stringify": { 1960 | "version": "2.1.0", 1961 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1962 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1963 | "dev": true 1964 | }, 1965 | "node_modules/fast-levenshtein": { 1966 | "version": "2.0.6", 1967 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1968 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1969 | "dev": true 1970 | }, 1971 | "node_modules/fast-xml-parser": { 1972 | "version": "4.4.1", 1973 | "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", 1974 | "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", 1975 | "funding": [ 1976 | { 1977 | "type": "github", 1978 | "url": "https://github.com/sponsors/NaturalIntelligence" 1979 | }, 1980 | { 1981 | "type": "paypal", 1982 | "url": "https://paypal.me/naturalintelligence" 1983 | } 1984 | ], 1985 | "dependencies": { 1986 | "strnum": "^1.0.5" 1987 | }, 1988 | "bin": { 1989 | "fxparser": "src/cli/cli.js" 1990 | } 1991 | }, 1992 | "node_modules/fd-package-json": { 1993 | "version": "1.2.0", 1994 | "resolved": "https://registry.npmjs.org/fd-package-json/-/fd-package-json-1.2.0.tgz", 1995 | "integrity": "sha512-45LSPmWf+gC5tdCQMNH4s9Sr00bIkiD9aN7dc5hqkrEw1geRYyDQS1v1oMHAW3ysfxfndqGsrDREHHjNNbKUfA==", 1996 | "dev": true, 1997 | "dependencies": { 1998 | "walk-up-path": "^3.0.1" 1999 | } 2000 | }, 2001 | "node_modules/file-entry-cache": { 2002 | "version": "8.0.0", 2003 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 2004 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 2005 | "dev": true, 2006 | "dependencies": { 2007 | "flat-cache": "^4.0.0" 2008 | }, 2009 | "engines": { 2010 | "node": ">=16.0.0" 2011 | } 2012 | }, 2013 | "node_modules/fill-range": { 2014 | "version": "7.1.1", 2015 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 2016 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 2017 | "dev": true, 2018 | "dependencies": { 2019 | "to-regex-range": "^5.0.1" 2020 | }, 2021 | "engines": { 2022 | "node": ">=8" 2023 | } 2024 | }, 2025 | "node_modules/find-up": { 2026 | "version": "5.0.0", 2027 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 2028 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 2029 | "dev": true, 2030 | "dependencies": { 2031 | "locate-path": "^6.0.0", 2032 | "path-exists": "^4.0.0" 2033 | }, 2034 | "engines": { 2035 | "node": ">=10" 2036 | }, 2037 | "funding": { 2038 | "url": "https://github.com/sponsors/sindresorhus" 2039 | } 2040 | }, 2041 | "node_modules/flat-cache": { 2042 | "version": "4.0.1", 2043 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 2044 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 2045 | "dev": true, 2046 | "dependencies": { 2047 | "flatted": "^3.2.9", 2048 | "keyv": "^4.5.4" 2049 | }, 2050 | "engines": { 2051 | "node": ">=16" 2052 | } 2053 | }, 2054 | "node_modules/flatted": { 2055 | "version": "3.3.1", 2056 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", 2057 | "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", 2058 | "dev": true 2059 | }, 2060 | "node_modules/foreground-child": { 2061 | "version": "3.3.0", 2062 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", 2063 | "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", 2064 | "dev": true, 2065 | "dependencies": { 2066 | "cross-spawn": "^7.0.0", 2067 | "signal-exit": "^4.0.1" 2068 | }, 2069 | "engines": { 2070 | "node": ">=14" 2071 | }, 2072 | "funding": { 2073 | "url": "https://github.com/sponsors/isaacs" 2074 | } 2075 | }, 2076 | "node_modules/fsevents": { 2077 | "version": "2.3.3", 2078 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 2079 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 2080 | "dev": true, 2081 | "hasInstallScript": true, 2082 | "optional": true, 2083 | "os": [ 2084 | "darwin" 2085 | ], 2086 | "engines": { 2087 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 2088 | } 2089 | }, 2090 | "node_modules/get-caller-file": { 2091 | "version": "2.0.5", 2092 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 2093 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 2094 | "engines": { 2095 | "node": "6.* || 8.* || >= 10.*" 2096 | } 2097 | }, 2098 | "node_modules/glob": { 2099 | "version": "10.4.5", 2100 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 2101 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 2102 | "dev": true, 2103 | "dependencies": { 2104 | "foreground-child": "^3.1.0", 2105 | "jackspeak": "^3.1.2", 2106 | "minimatch": "^9.0.4", 2107 | "minipass": "^7.1.2", 2108 | "package-json-from-dist": "^1.0.0", 2109 | "path-scurry": "^1.11.1" 2110 | }, 2111 | "bin": { 2112 | "glob": "dist/esm/bin.mjs" 2113 | }, 2114 | "funding": { 2115 | "url": "https://github.com/sponsors/isaacs" 2116 | } 2117 | }, 2118 | "node_modules/glob-parent": { 2119 | "version": "6.0.2", 2120 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 2121 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 2122 | "dev": true, 2123 | "dependencies": { 2124 | "is-glob": "^4.0.3" 2125 | }, 2126 | "engines": { 2127 | "node": ">=10.13.0" 2128 | } 2129 | }, 2130 | "node_modules/glob/node_modules/brace-expansion": { 2131 | "version": "2.0.1", 2132 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 2133 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 2134 | "dev": true, 2135 | "dependencies": { 2136 | "balanced-match": "^1.0.0" 2137 | } 2138 | }, 2139 | "node_modules/glob/node_modules/minimatch": { 2140 | "version": "9.0.5", 2141 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 2142 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 2143 | "dev": true, 2144 | "dependencies": { 2145 | "brace-expansion": "^2.0.1" 2146 | }, 2147 | "engines": { 2148 | "node": ">=16 || 14 >=14.17" 2149 | }, 2150 | "funding": { 2151 | "url": "https://github.com/sponsors/isaacs" 2152 | } 2153 | }, 2154 | "node_modules/globals": { 2155 | "version": "15.11.0", 2156 | "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", 2157 | "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", 2158 | "dev": true, 2159 | "engines": { 2160 | "node": ">=18" 2161 | }, 2162 | "funding": { 2163 | "url": "https://github.com/sponsors/sindresorhus" 2164 | } 2165 | }, 2166 | "node_modules/has-flag": { 2167 | "version": "4.0.0", 2168 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 2169 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2170 | "dev": true, 2171 | "engines": { 2172 | "node": ">=8" 2173 | } 2174 | }, 2175 | "node_modules/ignore": { 2176 | "version": "5.3.2", 2177 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 2178 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 2179 | "dev": true, 2180 | "engines": { 2181 | "node": ">= 4" 2182 | } 2183 | }, 2184 | "node_modules/ignore-by-default": { 2185 | "version": "1.0.1", 2186 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", 2187 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", 2188 | "dev": true 2189 | }, 2190 | "node_modules/import-fresh": { 2191 | "version": "3.3.0", 2192 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 2193 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 2194 | "dev": true, 2195 | "dependencies": { 2196 | "parent-module": "^1.0.0", 2197 | "resolve-from": "^4.0.0" 2198 | }, 2199 | "engines": { 2200 | "node": ">=6" 2201 | }, 2202 | "funding": { 2203 | "url": "https://github.com/sponsors/sindresorhus" 2204 | } 2205 | }, 2206 | "node_modules/imurmurhash": { 2207 | "version": "0.1.4", 2208 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 2209 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 2210 | "dev": true, 2211 | "engines": { 2212 | "node": ">=0.8.19" 2213 | } 2214 | }, 2215 | "node_modules/is-binary-path": { 2216 | "version": "2.1.0", 2217 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 2218 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 2219 | "dev": true, 2220 | "dependencies": { 2221 | "binary-extensions": "^2.0.0" 2222 | }, 2223 | "engines": { 2224 | "node": ">=8" 2225 | } 2226 | }, 2227 | "node_modules/is-extglob": { 2228 | "version": "2.1.1", 2229 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 2230 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 2231 | "dev": true, 2232 | "engines": { 2233 | "node": ">=0.10.0" 2234 | } 2235 | }, 2236 | "node_modules/is-fullwidth-code-point": { 2237 | "version": "3.0.0", 2238 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2239 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2240 | "engines": { 2241 | "node": ">=8" 2242 | } 2243 | }, 2244 | "node_modules/is-glob": { 2245 | "version": "4.0.3", 2246 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 2247 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 2248 | "dev": true, 2249 | "dependencies": { 2250 | "is-extglob": "^2.1.1" 2251 | }, 2252 | "engines": { 2253 | "node": ">=0.10.0" 2254 | } 2255 | }, 2256 | "node_modules/is-number": { 2257 | "version": "7.0.0", 2258 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 2259 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 2260 | "dev": true, 2261 | "engines": { 2262 | "node": ">=0.12.0" 2263 | } 2264 | }, 2265 | "node_modules/isexe": { 2266 | "version": "2.0.0", 2267 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 2268 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 2269 | "dev": true 2270 | }, 2271 | "node_modules/jackspeak": { 2272 | "version": "3.4.3", 2273 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", 2274 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", 2275 | "dev": true, 2276 | "dependencies": { 2277 | "@isaacs/cliui": "^8.0.2" 2278 | }, 2279 | "funding": { 2280 | "url": "https://github.com/sponsors/isaacs" 2281 | }, 2282 | "optionalDependencies": { 2283 | "@pkgjs/parseargs": "^0.11.0" 2284 | } 2285 | }, 2286 | "node_modules/jasmine": { 2287 | "version": "5.4.0", 2288 | "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-5.4.0.tgz", 2289 | "integrity": "sha512-E2u4ylX5tgGYvbynImU6EUBKKrSVB1L72FEPjGh4M55ov1VsxR26RA2JU91L9YSPFgcjo4mCLyKn/QXvEYGBkA==", 2290 | "dev": true, 2291 | "dependencies": { 2292 | "glob": "^10.2.2", 2293 | "jasmine-core": "~5.4.0" 2294 | }, 2295 | "bin": { 2296 | "jasmine": "bin/jasmine.js" 2297 | } 2298 | }, 2299 | "node_modules/jasmine-core": { 2300 | "version": "5.4.0", 2301 | "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.4.0.tgz", 2302 | "integrity": "sha512-T4fio3W++llLd7LGSGsioriDHgWyhoL6YTu4k37uwJLF7DzOzspz7mNxRoM3cQdLWtL/ebazQpIf/yZGJx/gzg==", 2303 | "dev": true 2304 | }, 2305 | "node_modules/js-yaml": { 2306 | "version": "4.1.0", 2307 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 2308 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 2309 | "dev": true, 2310 | "dependencies": { 2311 | "argparse": "^2.0.1" 2312 | }, 2313 | "bin": { 2314 | "js-yaml": "bin/js-yaml.js" 2315 | } 2316 | }, 2317 | "node_modules/jsdoc-type-pratt-parser": { 2318 | "version": "4.1.0", 2319 | "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", 2320 | "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", 2321 | "dev": true, 2322 | "engines": { 2323 | "node": ">=12.0.0" 2324 | } 2325 | }, 2326 | "node_modules/json-buffer": { 2327 | "version": "3.0.1", 2328 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 2329 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 2330 | "dev": true 2331 | }, 2332 | "node_modules/json-schema-traverse": { 2333 | "version": "0.4.1", 2334 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 2335 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 2336 | "dev": true 2337 | }, 2338 | "node_modules/json-stable-stringify-without-jsonify": { 2339 | "version": "1.0.1", 2340 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 2341 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 2342 | "dev": true 2343 | }, 2344 | "node_modules/keyv": { 2345 | "version": "4.5.4", 2346 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 2347 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 2348 | "dev": true, 2349 | "dependencies": { 2350 | "json-buffer": "3.0.1" 2351 | } 2352 | }, 2353 | "node_modules/levn": { 2354 | "version": "0.4.1", 2355 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 2356 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 2357 | "dev": true, 2358 | "dependencies": { 2359 | "prelude-ls": "^1.2.1", 2360 | "type-check": "~0.4.0" 2361 | }, 2362 | "engines": { 2363 | "node": ">= 0.8.0" 2364 | } 2365 | }, 2366 | "node_modules/locate-path": { 2367 | "version": "6.0.0", 2368 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 2369 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 2370 | "dev": true, 2371 | "dependencies": { 2372 | "p-locate": "^5.0.0" 2373 | }, 2374 | "engines": { 2375 | "node": ">=10" 2376 | }, 2377 | "funding": { 2378 | "url": "https://github.com/sponsors/sindresorhus" 2379 | } 2380 | }, 2381 | "node_modules/lodash.merge": { 2382 | "version": "4.6.2", 2383 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 2384 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 2385 | "dev": true 2386 | }, 2387 | "node_modules/lru-cache": { 2388 | "version": "10.4.3", 2389 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 2390 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 2391 | "dev": true 2392 | }, 2393 | "node_modules/minimatch": { 2394 | "version": "3.1.2", 2395 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 2396 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 2397 | "dev": true, 2398 | "dependencies": { 2399 | "brace-expansion": "^1.1.7" 2400 | }, 2401 | "engines": { 2402 | "node": "*" 2403 | } 2404 | }, 2405 | "node_modules/minipass": { 2406 | "version": "7.1.2", 2407 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 2408 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 2409 | "dev": true, 2410 | "engines": { 2411 | "node": ">=16 || 14 >=14.17" 2412 | } 2413 | }, 2414 | "node_modules/module-replacements": { 2415 | "version": "2.5.0", 2416 | "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-2.5.0.tgz", 2417 | "integrity": "sha512-m00JBwLSr7sur96PeAfAwNcyQk5MEm/GzZtZSRM+UjdzjNcgzPrWsWpsCpaRP+Fq+ROykt1TCr4GSR/ajcB83w==", 2418 | "dev": true 2419 | }, 2420 | "node_modules/ms": { 2421 | "version": "2.1.3", 2422 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 2423 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 2424 | "dev": true 2425 | }, 2426 | "node_modules/mustache": { 2427 | "version": "4.2.0", 2428 | "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", 2429 | "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", 2430 | "dev": true, 2431 | "bin": { 2432 | "mustache": "bin/mustache" 2433 | } 2434 | }, 2435 | "node_modules/natural-compare": { 2436 | "version": "1.4.0", 2437 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2438 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 2439 | "dev": true 2440 | }, 2441 | "node_modules/nodemon": { 2442 | "version": "3.1.7", 2443 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", 2444 | "integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==", 2445 | "dev": true, 2446 | "dependencies": { 2447 | "chokidar": "^3.5.2", 2448 | "debug": "^4", 2449 | "ignore-by-default": "^1.0.1", 2450 | "minimatch": "^3.1.2", 2451 | "pstree.remy": "^1.1.8", 2452 | "semver": "^7.5.3", 2453 | "simple-update-notifier": "^2.0.0", 2454 | "supports-color": "^5.5.0", 2455 | "touch": "^3.1.0", 2456 | "undefsafe": "^2.0.5" 2457 | }, 2458 | "bin": { 2459 | "nodemon": "bin/nodemon.js" 2460 | }, 2461 | "engines": { 2462 | "node": ">=10" 2463 | }, 2464 | "funding": { 2465 | "type": "opencollective", 2466 | "url": "https://opencollective.com/nodemon" 2467 | } 2468 | }, 2469 | "node_modules/nodemon/node_modules/has-flag": { 2470 | "version": "3.0.0", 2471 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 2472 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 2473 | "dev": true, 2474 | "engines": { 2475 | "node": ">=4" 2476 | } 2477 | }, 2478 | "node_modules/nodemon/node_modules/supports-color": { 2479 | "version": "5.5.0", 2480 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 2481 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 2482 | "dev": true, 2483 | "dependencies": { 2484 | "has-flag": "^3.0.0" 2485 | }, 2486 | "engines": { 2487 | "node": ">=4" 2488 | } 2489 | }, 2490 | "node_modules/normalize-path": { 2491 | "version": "3.0.0", 2492 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 2493 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 2494 | "dev": true, 2495 | "engines": { 2496 | "node": ">=0.10.0" 2497 | } 2498 | }, 2499 | "node_modules/optionator": { 2500 | "version": "0.9.4", 2501 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 2502 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 2503 | "dev": true, 2504 | "dependencies": { 2505 | "deep-is": "^0.1.3", 2506 | "fast-levenshtein": "^2.0.6", 2507 | "levn": "^0.4.1", 2508 | "prelude-ls": "^1.2.1", 2509 | "type-check": "^0.4.0", 2510 | "word-wrap": "^1.2.5" 2511 | }, 2512 | "engines": { 2513 | "node": ">= 0.8.0" 2514 | } 2515 | }, 2516 | "node_modules/p-limit": { 2517 | "version": "3.1.0", 2518 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 2519 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 2520 | "dev": true, 2521 | "dependencies": { 2522 | "yocto-queue": "^0.1.0" 2523 | }, 2524 | "engines": { 2525 | "node": ">=10" 2526 | }, 2527 | "funding": { 2528 | "url": "https://github.com/sponsors/sindresorhus" 2529 | } 2530 | }, 2531 | "node_modules/p-locate": { 2532 | "version": "5.0.0", 2533 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 2534 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 2535 | "dev": true, 2536 | "dependencies": { 2537 | "p-limit": "^3.0.2" 2538 | }, 2539 | "engines": { 2540 | "node": ">=10" 2541 | }, 2542 | "funding": { 2543 | "url": "https://github.com/sponsors/sindresorhus" 2544 | } 2545 | }, 2546 | "node_modules/package-json-from-dist": { 2547 | "version": "1.0.1", 2548 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", 2549 | "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", 2550 | "dev": true 2551 | }, 2552 | "node_modules/parent-module": { 2553 | "version": "1.0.1", 2554 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 2555 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 2556 | "dev": true, 2557 | "dependencies": { 2558 | "callsites": "^3.0.0" 2559 | }, 2560 | "engines": { 2561 | "node": ">=6" 2562 | } 2563 | }, 2564 | "node_modules/parse-imports": { 2565 | "version": "2.2.1", 2566 | "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", 2567 | "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", 2568 | "dev": true, 2569 | "dependencies": { 2570 | "es-module-lexer": "^1.5.3", 2571 | "slashes": "^3.0.12" 2572 | }, 2573 | "engines": { 2574 | "node": ">= 18" 2575 | } 2576 | }, 2577 | "node_modules/path-exists": { 2578 | "version": "4.0.0", 2579 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 2580 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 2581 | "dev": true, 2582 | "engines": { 2583 | "node": ">=8" 2584 | } 2585 | }, 2586 | "node_modules/path-key": { 2587 | "version": "3.1.1", 2588 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 2589 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 2590 | "dev": true, 2591 | "engines": { 2592 | "node": ">=8" 2593 | } 2594 | }, 2595 | "node_modules/path-scurry": { 2596 | "version": "1.11.1", 2597 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", 2598 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", 2599 | "dev": true, 2600 | "dependencies": { 2601 | "lru-cache": "^10.2.0", 2602 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 2603 | }, 2604 | "engines": { 2605 | "node": ">=16 || 14 >=14.18" 2606 | }, 2607 | "funding": { 2608 | "url": "https://github.com/sponsors/isaacs" 2609 | } 2610 | }, 2611 | "node_modules/picomatch": { 2612 | "version": "2.3.1", 2613 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2614 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 2615 | "dev": true, 2616 | "engines": { 2617 | "node": ">=8.6" 2618 | }, 2619 | "funding": { 2620 | "url": "https://github.com/sponsors/jonschlinkert" 2621 | } 2622 | }, 2623 | "node_modules/prelude-ls": { 2624 | "version": "1.2.1", 2625 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 2626 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 2627 | "dev": true, 2628 | "engines": { 2629 | "node": ">= 0.8.0" 2630 | } 2631 | }, 2632 | "node_modules/pstree.remy": { 2633 | "version": "1.1.8", 2634 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", 2635 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", 2636 | "dev": true 2637 | }, 2638 | "node_modules/punycode": { 2639 | "version": "2.3.1", 2640 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 2641 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 2642 | "dev": true, 2643 | "engines": { 2644 | "node": ">=6" 2645 | } 2646 | }, 2647 | "node_modules/readdirp": { 2648 | "version": "3.6.0", 2649 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 2650 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 2651 | "dev": true, 2652 | "dependencies": { 2653 | "picomatch": "^2.2.1" 2654 | }, 2655 | "engines": { 2656 | "node": ">=8.10.0" 2657 | } 2658 | }, 2659 | "node_modules/require-directory": { 2660 | "version": "2.1.1", 2661 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 2662 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 2663 | "engines": { 2664 | "node": ">=0.10.0" 2665 | } 2666 | }, 2667 | "node_modules/resolve-from": { 2668 | "version": "4.0.0", 2669 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 2670 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 2671 | "dev": true, 2672 | "engines": { 2673 | "node": ">=4" 2674 | } 2675 | }, 2676 | "node_modules/semver": { 2677 | "version": "7.6.3", 2678 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 2679 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 2680 | "dev": true, 2681 | "bin": { 2682 | "semver": "bin/semver.js" 2683 | }, 2684 | "engines": { 2685 | "node": ">=10" 2686 | } 2687 | }, 2688 | "node_modules/shebang-command": { 2689 | "version": "2.0.0", 2690 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2691 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2692 | "dev": true, 2693 | "dependencies": { 2694 | "shebang-regex": "^3.0.0" 2695 | }, 2696 | "engines": { 2697 | "node": ">=8" 2698 | } 2699 | }, 2700 | "node_modules/shebang-regex": { 2701 | "version": "3.0.0", 2702 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2703 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2704 | "dev": true, 2705 | "engines": { 2706 | "node": ">=8" 2707 | } 2708 | }, 2709 | "node_modules/signal-exit": { 2710 | "version": "4.1.0", 2711 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 2712 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 2713 | "dev": true, 2714 | "engines": { 2715 | "node": ">=14" 2716 | }, 2717 | "funding": { 2718 | "url": "https://github.com/sponsors/isaacs" 2719 | } 2720 | }, 2721 | "node_modules/simple-update-notifier": { 2722 | "version": "2.0.0", 2723 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", 2724 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", 2725 | "dev": true, 2726 | "dependencies": { 2727 | "semver": "^7.5.3" 2728 | }, 2729 | "engines": { 2730 | "node": ">=10" 2731 | } 2732 | }, 2733 | "node_modules/slashes": { 2734 | "version": "3.0.12", 2735 | "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", 2736 | "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", 2737 | "dev": true 2738 | }, 2739 | "node_modules/spdx-exceptions": { 2740 | "version": "2.5.0", 2741 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", 2742 | "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", 2743 | "dev": true 2744 | }, 2745 | "node_modules/spdx-expression-parse": { 2746 | "version": "4.0.0", 2747 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", 2748 | "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", 2749 | "dev": true, 2750 | "dependencies": { 2751 | "spdx-exceptions": "^2.1.0", 2752 | "spdx-license-ids": "^3.0.0" 2753 | } 2754 | }, 2755 | "node_modules/spdx-license-ids": { 2756 | "version": "3.0.20", 2757 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", 2758 | "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", 2759 | "dev": true 2760 | }, 2761 | "node_modules/string-width": { 2762 | "version": "5.1.2", 2763 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 2764 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 2765 | "dev": true, 2766 | "dependencies": { 2767 | "eastasianwidth": "^0.2.0", 2768 | "emoji-regex": "^9.2.2", 2769 | "strip-ansi": "^7.0.1" 2770 | }, 2771 | "engines": { 2772 | "node": ">=12" 2773 | }, 2774 | "funding": { 2775 | "url": "https://github.com/sponsors/sindresorhus" 2776 | } 2777 | }, 2778 | "node_modules/string-width-cjs": { 2779 | "name": "string-width", 2780 | "version": "4.2.3", 2781 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2782 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2783 | "dev": true, 2784 | "dependencies": { 2785 | "emoji-regex": "^8.0.0", 2786 | "is-fullwidth-code-point": "^3.0.0", 2787 | "strip-ansi": "^6.0.1" 2788 | }, 2789 | "engines": { 2790 | "node": ">=8" 2791 | } 2792 | }, 2793 | "node_modules/string-width-cjs/node_modules/ansi-regex": { 2794 | "version": "5.0.1", 2795 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2796 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2797 | "dev": true, 2798 | "engines": { 2799 | "node": ">=8" 2800 | } 2801 | }, 2802 | "node_modules/string-width-cjs/node_modules/emoji-regex": { 2803 | "version": "8.0.0", 2804 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2805 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2806 | "dev": true 2807 | }, 2808 | "node_modules/string-width-cjs/node_modules/strip-ansi": { 2809 | "version": "6.0.1", 2810 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2811 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2812 | "dev": true, 2813 | "dependencies": { 2814 | "ansi-regex": "^5.0.1" 2815 | }, 2816 | "engines": { 2817 | "node": ">=8" 2818 | } 2819 | }, 2820 | "node_modules/strip-ansi": { 2821 | "version": "7.1.0", 2822 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 2823 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 2824 | "dev": true, 2825 | "dependencies": { 2826 | "ansi-regex": "^6.0.1" 2827 | }, 2828 | "engines": { 2829 | "node": ">=12" 2830 | }, 2831 | "funding": { 2832 | "url": "https://github.com/chalk/strip-ansi?sponsor=1" 2833 | } 2834 | }, 2835 | "node_modules/strip-ansi-cjs": { 2836 | "name": "strip-ansi", 2837 | "version": "6.0.1", 2838 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2839 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2840 | "dev": true, 2841 | "dependencies": { 2842 | "ansi-regex": "^5.0.1" 2843 | }, 2844 | "engines": { 2845 | "node": ">=8" 2846 | } 2847 | }, 2848 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { 2849 | "version": "5.0.1", 2850 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2851 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2852 | "dev": true, 2853 | "engines": { 2854 | "node": ">=8" 2855 | } 2856 | }, 2857 | "node_modules/strip-json-comments": { 2858 | "version": "3.1.1", 2859 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2860 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2861 | "dev": true, 2862 | "engines": { 2863 | "node": ">=8" 2864 | }, 2865 | "funding": { 2866 | "url": "https://github.com/sponsors/sindresorhus" 2867 | } 2868 | }, 2869 | "node_modules/strnum": { 2870 | "version": "1.0.5", 2871 | "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", 2872 | "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" 2873 | }, 2874 | "node_modules/supports-color": { 2875 | "version": "7.2.0", 2876 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2877 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2878 | "dev": true, 2879 | "dependencies": { 2880 | "has-flag": "^4.0.0" 2881 | }, 2882 | "engines": { 2883 | "node": ">=8" 2884 | } 2885 | }, 2886 | "node_modules/synckit": { 2887 | "version": "0.9.2", 2888 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", 2889 | "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", 2890 | "dev": true, 2891 | "dependencies": { 2892 | "@pkgr/core": "^0.1.0", 2893 | "tslib": "^2.6.2" 2894 | }, 2895 | "engines": { 2896 | "node": "^14.18.0 || >=16.0.0" 2897 | }, 2898 | "funding": { 2899 | "url": "https://opencollective.com/unts" 2900 | } 2901 | }, 2902 | "node_modules/text-table": { 2903 | "version": "0.2.0", 2904 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2905 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 2906 | "dev": true 2907 | }, 2908 | "node_modules/to-regex-range": { 2909 | "version": "5.0.1", 2910 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2911 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2912 | "dev": true, 2913 | "dependencies": { 2914 | "is-number": "^7.0.0" 2915 | }, 2916 | "engines": { 2917 | "node": ">=8.0" 2918 | } 2919 | }, 2920 | "node_modules/touch": { 2921 | "version": "3.1.1", 2922 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", 2923 | "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", 2924 | "dev": true, 2925 | "bin": { 2926 | "nodetouch": "bin/nodetouch.js" 2927 | } 2928 | }, 2929 | "node_modules/tslib": { 2930 | "version": "2.8.0", 2931 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", 2932 | "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" 2933 | }, 2934 | "node_modules/type-check": { 2935 | "version": "0.4.0", 2936 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2937 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2938 | "dev": true, 2939 | "dependencies": { 2940 | "prelude-ls": "^1.2.1" 2941 | }, 2942 | "engines": { 2943 | "node": ">= 0.8.0" 2944 | } 2945 | }, 2946 | "node_modules/undefsafe": { 2947 | "version": "2.0.5", 2948 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", 2949 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", 2950 | "dev": true 2951 | }, 2952 | "node_modules/uri-js": { 2953 | "version": "4.4.1", 2954 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2955 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2956 | "dev": true, 2957 | "dependencies": { 2958 | "punycode": "^2.1.0" 2959 | } 2960 | }, 2961 | "node_modules/uuid": { 2962 | "version": "9.0.1", 2963 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", 2964 | "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", 2965 | "funding": [ 2966 | "https://github.com/sponsors/broofa", 2967 | "https://github.com/sponsors/ctavan" 2968 | ], 2969 | "bin": { 2970 | "uuid": "dist/bin/uuid" 2971 | } 2972 | }, 2973 | "node_modules/walk-up-path": { 2974 | "version": "3.0.1", 2975 | "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", 2976 | "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", 2977 | "dev": true 2978 | }, 2979 | "node_modules/which": { 2980 | "version": "2.0.2", 2981 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2982 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2983 | "dev": true, 2984 | "dependencies": { 2985 | "isexe": "^2.0.0" 2986 | }, 2987 | "bin": { 2988 | "node-which": "bin/node-which" 2989 | }, 2990 | "engines": { 2991 | "node": ">= 8" 2992 | } 2993 | }, 2994 | "node_modules/word-wrap": { 2995 | "version": "1.2.5", 2996 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 2997 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 2998 | "dev": true, 2999 | "engines": { 3000 | "node": ">=0.10.0" 3001 | } 3002 | }, 3003 | "node_modules/wrap-ansi": { 3004 | "version": "8.1.0", 3005 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 3006 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 3007 | "dev": true, 3008 | "dependencies": { 3009 | "ansi-styles": "^6.1.0", 3010 | "string-width": "^5.0.1", 3011 | "strip-ansi": "^7.0.1" 3012 | }, 3013 | "engines": { 3014 | "node": ">=12" 3015 | }, 3016 | "funding": { 3017 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 3018 | } 3019 | }, 3020 | "node_modules/wrap-ansi-cjs": { 3021 | "name": "wrap-ansi", 3022 | "version": "7.0.0", 3023 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 3024 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 3025 | "dev": true, 3026 | "dependencies": { 3027 | "ansi-styles": "^4.0.0", 3028 | "string-width": "^4.1.0", 3029 | "strip-ansi": "^6.0.0" 3030 | }, 3031 | "engines": { 3032 | "node": ">=10" 3033 | }, 3034 | "funding": { 3035 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 3036 | } 3037 | }, 3038 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { 3039 | "version": "5.0.1", 3040 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 3041 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 3042 | "dev": true, 3043 | "engines": { 3044 | "node": ">=8" 3045 | } 3046 | }, 3047 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { 3048 | "version": "8.0.0", 3049 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 3050 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 3051 | "dev": true 3052 | }, 3053 | "node_modules/wrap-ansi-cjs/node_modules/string-width": { 3054 | "version": "4.2.3", 3055 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 3056 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 3057 | "dev": true, 3058 | "dependencies": { 3059 | "emoji-regex": "^8.0.0", 3060 | "is-fullwidth-code-point": "^3.0.0", 3061 | "strip-ansi": "^6.0.1" 3062 | }, 3063 | "engines": { 3064 | "node": ">=8" 3065 | } 3066 | }, 3067 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { 3068 | "version": "6.0.1", 3069 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 3070 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 3071 | "dev": true, 3072 | "dependencies": { 3073 | "ansi-regex": "^5.0.1" 3074 | }, 3075 | "engines": { 3076 | "node": ">=8" 3077 | } 3078 | }, 3079 | "node_modules/wrap-ansi/node_modules/ansi-styles": { 3080 | "version": "6.2.1", 3081 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 3082 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 3083 | "dev": true, 3084 | "engines": { 3085 | "node": ">=12" 3086 | }, 3087 | "funding": { 3088 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 3089 | } 3090 | }, 3091 | "node_modules/y18n": { 3092 | "version": "5.0.8", 3093 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 3094 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 3095 | "engines": { 3096 | "node": ">=10" 3097 | } 3098 | }, 3099 | "node_modules/yargs": { 3100 | "version": "17.7.2", 3101 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 3102 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 3103 | "dependencies": { 3104 | "cliui": "^8.0.1", 3105 | "escalade": "^3.1.1", 3106 | "get-caller-file": "^2.0.5", 3107 | "require-directory": "^2.1.1", 3108 | "string-width": "^4.2.3", 3109 | "y18n": "^5.0.5", 3110 | "yargs-parser": "^21.1.1" 3111 | }, 3112 | "engines": { 3113 | "node": ">=12" 3114 | } 3115 | }, 3116 | "node_modules/yargs-parser": { 3117 | "version": "21.1.1", 3118 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 3119 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 3120 | "engines": { 3121 | "node": ">=12" 3122 | } 3123 | }, 3124 | "node_modules/yargs/node_modules/ansi-regex": { 3125 | "version": "5.0.1", 3126 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 3127 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 3128 | "engines": { 3129 | "node": ">=8" 3130 | } 3131 | }, 3132 | "node_modules/yargs/node_modules/emoji-regex": { 3133 | "version": "8.0.0", 3134 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 3135 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 3136 | }, 3137 | "node_modules/yargs/node_modules/string-width": { 3138 | "version": "4.2.3", 3139 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 3140 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 3141 | "dependencies": { 3142 | "emoji-regex": "^8.0.0", 3143 | "is-fullwidth-code-point": "^3.0.0", 3144 | "strip-ansi": "^6.0.1" 3145 | }, 3146 | "engines": { 3147 | "node": ">=8" 3148 | } 3149 | }, 3150 | "node_modules/yargs/node_modules/strip-ansi": { 3151 | "version": "6.0.1", 3152 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 3153 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 3154 | "dependencies": { 3155 | "ansi-regex": "^5.0.1" 3156 | }, 3157 | "engines": { 3158 | "node": ">=8" 3159 | } 3160 | }, 3161 | "node_modules/yocto-queue": { 3162 | "version": "0.1.0", 3163 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 3164 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 3165 | "dev": true, 3166 | "engines": { 3167 | "node": ">=10" 3168 | }, 3169 | "funding": { 3170 | "url": "https://github.com/sponsors/sindresorhus" 3171 | } 3172 | } 3173 | } 3174 | } 3175 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "awsudo", 3 | "version": "3.0.0-alpha.0", 4 | "description": "A simple utility for executing cli commands with an assumed role.", 5 | "bin": { 6 | "awsudo": "src/index.js" 7 | }, 8 | "scripts": { 9 | "deploy-docker": "scripts/deploy-docker", 10 | "postversion": "scripts/postversion", 11 | "pretest": "npm outdated -- --warn-only && npm audit && eslint src/**/*.js", 12 | "preversion": "scripts/preversion", 13 | "start": "src/index.js", 14 | "test": "JASMINE_CONFIG_PATH=jasmine.json jasmine", 15 | "test:echo-for-validate-features": "echo $*", 16 | "test:watch": "nodemon --ext js --watch src --exec npm test", 17 | "update": "npx npm-check -uE" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/meltwater/awsudo.git" 22 | }, 23 | "keywords": [ 24 | "aws", 25 | "awscli", 26 | "sudo", 27 | "sts", 28 | "assume", 29 | "assumerole", 30 | "stsassume", 31 | "stsassumerole", 32 | "role", 33 | "rolearn", 34 | "arn", 35 | "cli", 36 | "bash" 37 | ], 38 | "author": { 39 | "name": "AWS sudo open source at Meltwater", 40 | "email": "awsudo.opensource@meltwater.com" 41 | }, 42 | "license": "MIT", 43 | "bugs": { 44 | "url": "https://github.com/meltwater/awsudo/issues" 45 | }, 46 | "homepage": "https://github.com/meltwater/awsudo#readme", 47 | "dependencies": { 48 | "@aws-sdk/client-sts": "3.670.0", 49 | "@aws-sdk/shared-ini-file-loader": "3.374.0", 50 | "@smithy/shared-ini-file-loader": "3.1.8", 51 | "yargs": "17.7.2" 52 | }, 53 | "devDependencies": { 54 | "@eslint/js": "9.12.0", 55 | "eslint": "9.12.0", 56 | "eslint-plugin-depend": "0.11.0", 57 | "eslint-plugin-jsdoc": "50.4.1", 58 | "globals": "15.11.0", 59 | "jasmine": "5.4.0", 60 | "mustache": "4.2.0", 61 | "nodemon": "3.1.7" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /scripts/build-packages: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | TARBALL_NAME=$(npm pack) 5 | fpm -s npm -t deb --license MIT -n awsudo -m awsudo.opensource@meltwater.com $TARBALL_NAME 6 | fpm -s npm -t rpm --license MIT -n awsudo -m awsudo.opensource@meltwater.com $TARBALL_NAME 7 | -------------------------------------------------------------------------------- /scripts/deploy-docker: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Exit on any child process error 3 | VERSION=$(node -p "require('./package').version") 4 | 5 | printf "Awaiting publish of version %s before starting Docker deploy\n" "$VERSION" 6 | while [ "$(npm info . version)" != "$VERSION" ]; do 7 | printf "." 8 | sleep 1 9 | done 10 | printf "\n%s available!\n\n" "$VERSION" 11 | 12 | echo "Deploying: awsudo/awsudo" 13 | 14 | LATEST_NODE_LTS=iron 15 | 16 | echo "Publishing tags specific to node LTS releases..." 17 | for NODE_LTS in "hydrogen" "iron"; do 18 | docker build --build-arg node_lts="$NODE_LTS" --build-arg version="$VERSION" . \ 19 | -t awsudo/awsudo:"$NODE_LTS" \ 20 | -t awsudo/awsudo:v"${VERSION}"-"$NODE_LTS" 21 | 22 | printf "Pushing awsudo/awsudo:%s\n" ${NODE_LTS} 23 | docker push awsudo/awsudo:"${NODE_LTS}" 24 | 25 | printf "Pushing awsudo/awsudo:v%s-%s\n" "${VERSION}" ${NODE_LTS} 26 | docker push awsudo/awsudo:v"${VERSION}-${NODE_LTS}" 27 | 28 | if [ "$NODE_LTS" = "$LATEST_NODE_LTS" ]; then 29 | echo "Building sliding version tags (latest & v${VERSION})..." 30 | 31 | docker build --build-arg node_lts="$NODE_LTS" --build-arg version="$VERSION" . \ 32 | -t awsudo/awsudo:latest \ 33 | -t awsudo/awsudo:v"${VERSION}" 34 | 35 | echo "Pushing awsudo/awsudo:latest" 36 | docker push awsudo/awsudo:latest 37 | 38 | printf "Pushing awsudo/awsudo:v%s\n" "${VERSION}" 39 | docker push awsudo/awsudo:v"${VERSION}" 40 | fi 41 | done 42 | 43 | echo "All done!" 44 | -------------------------------------------------------------------------------- /scripts/postversion: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Trigger CI publish of packages by version 4 | git push --follow-tags 5 | 6 | -------------------------------------------------------------------------------- /scripts/preversion: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################ 3 | # # 4 | # preversion - verify a code base as ready to release a new version # 5 | # # 6 | # - it is based on the master branch # 7 | # - it is up-to-date with the git remote # 8 | # - it passes tests # 9 | # # 10 | ################################################################################ 11 | set -e 12 | 13 | verify_branch_is_master() { 14 | echo "[INFO] Verifying current branch is 'master'" 15 | CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)" 16 | if [ "$CURRENT_BRANCH" != "master" ]; then 17 | printf "[ERROR] Current branch: %s\n\n" "$CURRENT_BRANCH" 18 | exit 1 19 | fi 20 | } 21 | 22 | verify_up_to_date_with_origin() { 23 | echo "[INFO] Verifying release is up-to-date with origin/master" 24 | if git rev-list --left-right --count origin/master... | grep -E '[^0[:blank:]]' > /dev/null 2>&1; then 25 | echo "[ERROR] Local working copy is behind or ahead of origin. Please fetch and merge." 26 | exit 1 27 | fi 28 | } 29 | 30 | verify_local_copy_is_clean() { 31 | echo "[INFO] Verifying there aren't uncommited changes" 32 | if [ "$(git diff --cached)" != "" ] || [ "$(git diff)" != "" ]; then 33 | echo "[ERROR] Local working copy has uncommitted changes. Were these supposed to be committed?" 34 | echo "[ERROR] Please commit, stash or reset these changes." 35 | exit 1 36 | fi 37 | } 38 | 39 | verify_tests_pass() { 40 | if [ -f package.json ]; then 41 | echo "[INFO] Running tests for npm project" 42 | npm test 43 | fi 44 | } 45 | 46 | ################################################################################ 47 | # Main # 48 | ################################################################################ 49 | echo "[INFO] Verifying preparedness to release a new version" 50 | 51 | verify_local_copy_is_clean 52 | verify_branch_is_master 53 | verify_up_to_date_with_origin 54 | verify_tests_pass 55 | 56 | echo "[INFO] Ready to release a new version" 57 | -------------------------------------------------------------------------------- /scripts/validate-features: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Description: 5 | # This validates significant features of awsudo as functioning properly 6 | # in a true running context. 7 | # 8 | # Organization: 9 | # 1. Supporting functions to facilitate output, testing, and complex 10 | # operations (e.g. soliciting MFA tokens and managing their life cycle 11 | # 2. Check for prerequisites needed to run this script 12 | # 3. The test suites, ordered from the most fundamental and simplistic to 13 | # more advanced behavior 14 | # 15 | # Contributing: 16 | # Not every feature that exists should be exercised by this tool. If a 17 | # unit test can adequately validate a given behavior, that should be 18 | # preferred. 19 | # 20 | # This should be reserved for a high-level validation of the overall 21 | # ability of awsudo to run successfully. It is perfectly acceptable for 22 | # this script to shrink over time as better ways of testing functionality 23 | # emerge. 24 | 25 | ################################## 26 | # Logging Functions # 27 | ################################## 28 | 29 | # Display a message as a banner on a new line 30 | # 31 | # Usage: announce [message] 32 | # 33 | # Example: 34 | # announce "Let the tests begin" 35 | announce() { 36 | echo 37 | info "** $* **" 1>&2 38 | } 39 | 40 | # Display a message with an error label on its own line 41 | # 42 | # Usage: error [message] 43 | # 44 | # Example: 45 | # error "Let the tests begin" 46 | error() { 47 | printf "[ERROR] %s\n" "$*" 1>&2 48 | } 49 | 50 | # Display a message with an error label on its own line 51 | # 52 | # Usage: info [message] 53 | # 54 | # Example: 55 | # info "Let the tests begin" 56 | info() { 57 | printf "[INFO] %s\n" "$*" 1>&2 58 | } 59 | 60 | # Display an indicator of progress so the user is aware 61 | # of ongoing activity without overwhelming them with 62 | # status text 63 | progress() { 64 | printf "." 1>&2 65 | } 66 | 67 | ################################## 68 | # Testing Functions # 69 | ################################## 70 | 71 | # Assert that one string contains another. 72 | # Show progress on success, exit with an error on failure. 73 | # 74 | # Usage: assert_contains [phrase to display on failure] [command output] [string that output should contain] 75 | # 76 | # Example: 77 | # assert_contains "should say hello" "$(echo hello world)" "hello" 78 | assert_contains() { 79 | ASSERTION="$1" 80 | TEST="$2" 81 | CHECK="$3" 82 | 83 | if echo "$TEST" | grep "$CHECK" > /dev/null ; then 84 | progress 85 | else 86 | echo 87 | error "$ASSERTION" 88 | error "Expected \"$TEST\" to contain \"$CHECK\"" 89 | exit 1 90 | fi 91 | } 92 | 93 | # Assert that one string equals another. 94 | # Show progress on success, exit with an error on failure. 95 | # 96 | # Usage: [phrase to display on failure] [command output] [string that output should contain 97 | # 98 | # Example: 99 | # assert_is "should say hello" "$(echo hello)" "hello" 100 | assert_is() { 101 | ASSERTION="$1" 102 | TEST="$2" 103 | CHECK="$3" 104 | 105 | if [ "$TEST" == "$CHECK" ]; then 106 | progress 107 | else 108 | echo 109 | error "$ASSERTION" 110 | error "Expected \"$TEST\" to equal \"$CHECK\"" 111 | exit 1 112 | fi 113 | } 114 | 115 | # Assert that one string does not equal another. 116 | # Show progress on success, exit with an error on failure. 117 | # 118 | # Usage: [phrase to display on failure] [command output] [string that output should contain 119 | # 120 | # Example: 121 | # assert_is_not "should not say hello" "$(echo goodbye cruel world)" "hello" 122 | assert_is_not() { 123 | ASSERTION="$1" 124 | TEST="$2" 125 | CHECK="$3" 126 | 127 | if [ "$TEST" != "$CHECK" ]; then 128 | progress 129 | else 130 | error "$ASSERTION" 131 | error "Expected \"$TEST\" NOT to equal \"$CHECK\"" 132 | exit 1 133 | fi 134 | } 135 | 136 | # Report assertion as being skipped 137 | # 138 | # Usage: [phrase to display as being skipped] 139 | # 140 | # Example: 141 | # skip_assert "should not say hello" 142 | # 143 | # Aliases: 144 | # - skip_assert_is 145 | # - skip_assert_is_not 146 | # - skip_assert_contains 147 | skip_assert() { 148 | ASSERTION="$1" 149 | 150 | info "Skipping: $ASSERTION" 151 | } 152 | skip_assert_is() { skip_assert "$1"; } 153 | skip_assert_is_not() { skip_assert "$1"; } 154 | skip_assert_contains() { skip_assert "$1"; } 155 | 156 | ################################## 157 | # MFA Token Management Functions # 158 | ################################## 159 | MFA_TOKEN= 160 | LAST_MFA_EXPIRATION=0 161 | 162 | get_mfa_expiration() { 163 | NEXT_MINUTE=$(docker run ubuntu date --date 'next minute' '+%H:%M:00') 164 | 165 | NEXT_MINUTE_SECONDS=$(docker run ubuntu date -d "$NEXT_MINUTE" '+%s') 166 | PREVIOUS_HALF_MINUTE_SECONDS=$(( $NEXT_MINUTE_SECONDS - 30)) 167 | 168 | if [ "$PREVIOUS_HALF_MINUTE_SECONDS" -gt "$(date '+%s')" ]; then 169 | echo "$PREVIOUS_HALF_MINUTE_SECONDS" 170 | else 171 | echo "$NEXT_MINUTE_SECONDS" 172 | fi 173 | } 174 | 175 | read_mfa_token() { 176 | MFA_TTL=$(( $LAST_MFA_EXPIRATION - $(date '+%s') )) 177 | if [ "$MFA_TTL" -gt 0 ]; then 178 | info "Waiting $MFA_TTL seconds until previous MFA token expires..." 179 | sleep "$MFA_TTL" 180 | fi 181 | 182 | read -rp "Provide the current MFA token: " MFA_TOKEN 183 | LAST_MFA_EXPIRATION="$(get_mfa_expiration)" 184 | } 185 | 186 | ################################# 187 | # Input Validation Functions # 188 | ################################# 189 | is_invalid_profile() { 190 | PROFILE=$1 191 | 192 | [ -z "$PROFILE" ] || ! grep "$PROFILE" ~/.aws/credentials ~/.aws/config > /dev/null 193 | } 194 | 195 | ################################# 196 | # Prerequisite check # 197 | ################################# 198 | announce "Checking for prerequisites" 199 | 200 | if ! command -v docker > /dev/null; then error "The docker command is required"; exit 1; fi 201 | if [ ! -f ~/.aws/credentials ] && [ ! -f ~/.aws/config ]; then error "A ~/.aws/credentials file or ~/.aws/config file is required"; exit 1; fi 202 | if ! grep profile ~/.aws/credentials ~/.aws/config > /dev/null; then error "At least one AWS profile needs to be configured"; exit 1; fi 203 | if ! grep mfa_serial ~/.aws/credentials ~/.aws/config > /dev/null; then error "At least one profile needs to be configured with MFA"; exit 1; fi 204 | 205 | ################################# 206 | # Start Test Suite # 207 | ################################# 208 | announce "Testing unauthenticated features" 209 | assert_contains "should display help text" \ 210 | "$(src/index.js -h 2>&1)" \ 211 | "Show help" 212 | 213 | announce "Testing access without MFA authentication" 214 | 215 | while is_invalid_profile $PROFILE_NO_MFA; do 216 | read -rp "Provide a valid non-MFA profile with which to test: " PROFILE_NO_MFA 217 | done 218 | info "Extracting role ARN from profile for non-profile tests" 219 | ROLE_ARN_NO_MFA=$(src/index.js -v -p="$PROFILE_NO_MFA" true | grep "Using RoleArn" | cut -d ' ' -f3) 220 | 221 | info "Extracting AWS environment variables from credentials file for environment-only tests" 222 | PROFILE_NO_MFA_AWS_ACCESS_KEY_ID="$(grep aws_access_key_id ~/.aws/credentials | head -n1 | cut -d '=' -f2 | xargs)" 223 | PROFILE_NO_MFA_AWS_SECRET_ACCESS_KEY="$(grep aws_secret_access_key ~/.aws/credentials | head -n1 | cut -d '=' -f2 | xargs)" 224 | 225 | assert_contains "should successfully invoke aws with profile" \ 226 | "$(src/index.js -p="$PROFILE_NO_MFA" aws sts get-caller-identity)" \ 227 | "UserId" 228 | 229 | assert_contains "should successfully invoke aws with role ARN" \ 230 | "$(src/index.js "$ROLE_ARN_NO_MFA" aws sts get-caller-identity)" \ 231 | "UserId" 232 | 233 | assert_contains "should successfully invoke aws using only environment variables" \ 234 | "$(docker run -e AWS_ACCESS_KEY_ID=$PROFILE_NO_MFA_AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$PROFILE_NO_MFA_AWS_SECRET_ACCESS_KEY -v $PWD:/awsudo -w /awsudo awsudo/awsudo src/index.js $ROLE_ARN_NO_MFA aws sts get-caller-identity)" \ 235 | "UserId" 236 | 237 | announce "Testing access with MFA authentication" 238 | 239 | while is_invalid_profile $PROFILE_MFA; do 240 | read -rp "Provide a valid profile that requires MFA with which to test: " PROFILE_MFA 241 | done 242 | info "Extracting role ARN from profile for non-profile tests" 243 | read_mfa_token 244 | ROLE_ARN_MFA=$(src/index.js -p="$PROFILE_MFA" -t="$MFA_TOKEN" true | grep "Using RoleArn" | cut -d ' ' -f3) 245 | 246 | info "Proceeding to individual tests" 247 | info "Note: each test will require a new MFA token" 248 | 249 | read_mfa_token 250 | assert_contains "should successfully invoke aws with profile" \ 251 | "$(src/index.js -p="$PROFILE_MFA" -t="$MFA_TOKEN" aws sts get-caller-identity)" \ 252 | "UserId" 253 | 254 | read_mfa_token 255 | assert_contains "should successfully invoke aws with role ARN" \ 256 | "$(src/index.js $ROLE_ARN_MFA -p=$PROFILE_MFA -t=$MFA_TOKEN aws sts get-caller-identity)" \ 257 | "UserId" 258 | 259 | announce "Testing command processing" 260 | 261 | assert_is_not "should pass commands any argument flags using a profile" \ 262 | "$(src/index.js -p="$PROFILE_NO_MFA" ls -l)" \ 263 | "$(src/index.js -p="$PROFILE_NO_MFA" ls)" 264 | 265 | assert_is_not "should pass commands any argument flags using a role ARN" \ 266 | "$(src/index.js "$ROLE_ARN_NO_MFA" ls -l)" \ 267 | "$(src/index.js -p="$PROFILE_NO_MFA" ls)" 268 | 269 | assert_contains "should not truncate npm run commands passed a -- divider" \ 270 | "$(src/index.js $ROLE_ARN_NO_MFA npm run test:echo-for-validate-features -- all args present)" \ 271 | "all args present" 272 | 273 | assert_contains "should not interfere with positionals when processing options with values" \ 274 | "$(src/index.js -d 1200 $ROLE_ARN_NO_MFA npm run test:echo-for-validate-features -- success)" \ 275 | "success" 276 | 277 | announce "Tests completed successfully" 278 | -------------------------------------------------------------------------------- /src/clean-aws-credentials-cache/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | //https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_revoke-sessions.html 4 | function cleanAwsCredentialsCache({ isWindows }) { 5 | if (!isWindows && fs.existsSync('~/.aws/cli/cache')) { 6 | fs.rmdirSync('~/.aws/cli/cache', { recursive: true }); 7 | } 8 | if (isWindows && fs.existsSync('%UserProfile%\\.aws\\cli\\cache')) { 9 | fs.rmdirSync('%UserProfile%\\.aws\\cli\\cache', { recursive: true }); 10 | } 11 | } 12 | 13 | module.exports = { 14 | cleanAwsCredentialsCache 15 | }; 16 | -------------------------------------------------------------------------------- /src/clean-aws-credentials-cache/index.spec.js: -------------------------------------------------------------------------------- 1 | const { cleanAwsCredentialsCache } = require('./index'); 2 | const fs = require('fs'); 3 | 4 | describe('cleanAwsCredentialsCache', () => { 5 | beforeEach(() => { 6 | spyOn(fs, 'existsSync'); 7 | spyOn(fs, 'rmdirSync'); 8 | }); 9 | 10 | it('should be a function', () => { 11 | expect(cleanAwsCredentialsCache).toEqual(jasmine.any(Function)); 12 | }); 13 | 14 | describe('on windows', () => { 15 | beforeEach(() => { 16 | fs.existsSync.and.callFake(path => { 17 | if (path.includes('UserProfile')) { 18 | return true; 19 | } 20 | return false; 21 | }); 22 | }); 23 | 24 | it('should remove aws credentials cache folder', () => { 25 | cleanAwsCredentialsCache({ isWindows: true }); 26 | 27 | expect(fs.rmdirSync).toHaveBeenCalledWith('%UserProfile%\\.aws\\cli\\cache', jasmine.anything()); 28 | }); 29 | 30 | it('should pass option to allow folder to be emptied if it has contents', () => { 31 | fs.existsSync.and.callFake(path => { 32 | if (path.includes('UserProfile')) { 33 | return true; 34 | } 35 | return false; 36 | }); 37 | 38 | cleanAwsCredentialsCache({ isWindows: true }); 39 | 40 | expect(fs.rmdirSync).toHaveBeenCalledWith(jasmine.anything(), { recursive: true }); 41 | }); 42 | }); 43 | 44 | describe('on macOs/unix/linux', () => { 45 | beforeEach(() => { 46 | fs.existsSync.and.callFake(path => { 47 | if (path.includes('~/')) { 48 | return true; 49 | } 50 | return false; 51 | }); 52 | }); 53 | 54 | it('should remove aws credentials cache folder', () => { 55 | cleanAwsCredentialsCache({ isWindows: false }); 56 | 57 | expect(fs.rmdirSync).toHaveBeenCalledWith('~/.aws/cli/cache', jasmine.anything()); 58 | }); 59 | 60 | it('should pass option to allow folder to be emptied if it has contents', () => { 61 | cleanAwsCredentialsCache({ isWindows: false }); 62 | 63 | expect(fs.rmdirSync).toHaveBeenCalledWith(jasmine.anything(), { recursive: true }); 64 | }); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /src/get-profile-list/index.js: -------------------------------------------------------------------------------- 1 | const { loadProfilesFromConfig } = require('../load-profiles-from-config'); 2 | 3 | async function getProfileList () { 4 | try { 5 | const profiles = await loadProfilesFromConfig(); 6 | return Object.keys(profiles); 7 | } 8 | catch (__error) { 9 | return []; 10 | } 11 | } 12 | 13 | module.exports = { 14 | getProfileList 15 | }; 16 | -------------------------------------------------------------------------------- /src/get-profile-list/index.spec.js: -------------------------------------------------------------------------------- 1 | const LoadProfilesFromConfigModule = require('../load-profiles-from-config'); 2 | 3 | describe('Getting profile list', () => { 4 | let getProfileList; 5 | let loadProfilesFromConfigSpy; 6 | 7 | beforeAll(() => { 8 | loadProfilesFromConfigSpy = spyOn(LoadProfilesFromConfigModule, 'loadProfilesFromConfig'); 9 | getProfileList = require('./index').getProfileList; 10 | }); 11 | 12 | it('should get profiles from shared config with the default iniLoader', async () => { 13 | await getProfileList(); 14 | 15 | expect(loadProfilesFromConfigSpy).toHaveBeenCalled(); 16 | }); 17 | 18 | it('should return profile object\'s keys', async () => { 19 | const profiles = { 20 | ProfileOne: {}, 21 | ProfileTwo: {} 22 | }; 23 | 24 | loadProfilesFromConfigSpy.and.returnValue(Promise.resolve(profiles)); 25 | 26 | const result = await getProfileList(); 27 | 28 | expect(result).toEqual(Object.keys(profiles)); 29 | }); 30 | 31 | it('should return an empty list if no profiles are available', async () => { 32 | LoadProfilesFromConfigModule.loadProfilesFromConfig.and.throwError(); 33 | 34 | const result = await getProfileList(); 35 | 36 | expect(result).toEqual([]); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /src/get-profile-options-values/index.js: -------------------------------------------------------------------------------- 1 | const { loadProfilesFromConfig } = require('../load-profiles-from-config'); 2 | const { removeObjectEntries } = require('../remove-object-entries'); 3 | 4 | const UNDEFINED_PROFILE_OPTIONS = {}; 5 | 6 | async function getProfileOptionsValues (profile) { 7 | try { 8 | const profiles = await loadProfilesFromConfig({ profile }); 9 | 10 | const profileOptions = { 11 | duration: profiles[profile].duration_seconds, 12 | externalId: profiles[profile].external_id, 13 | sessionName: profiles[profile].role_session_name, 14 | mfaTokenArn: profiles[profile].mfa_serial 15 | }; 16 | 17 | return removeObjectEntries(profileOptions, UNDEFINED_PROFILE_OPTIONS); 18 | } 19 | catch (__error) { 20 | return {}; 21 | } 22 | } 23 | 24 | module.exports = { 25 | getProfileOptionsValues 26 | }; 27 | -------------------------------------------------------------------------------- /src/get-profile-options-values/index.spec.js: -------------------------------------------------------------------------------- 1 | const LoadProfilesFromConfigModule = require('../load-profiles-from-config'); 2 | 3 | describe('Getting profile options values', () => { 4 | let profile; 5 | let getProfileOptionsValues; 6 | 7 | beforeAll(() => { 8 | profile = 'TestProfile'; 9 | 10 | spyOn(LoadProfilesFromConfigModule, 'loadProfilesFromConfig').and.returnValue({ 11 | [profile]: {} 12 | }); 13 | 14 | getProfileOptionsValues = require('./index').getProfileOptionsValues; 15 | }); 16 | 17 | afterEach(() => { 18 | LoadProfilesFromConfigModule.loadProfilesFromConfig.and.returnValue({ 19 | [profile]: {} 20 | }); 21 | }); 22 | 23 | it('should get profile from shared config with the default iniLoader', async () => { 24 | await getProfileOptionsValues(profile); 25 | 26 | expect(LoadProfilesFromConfigModule.loadProfilesFromConfig).toHaveBeenCalledWith(jasmine.objectContaining({ 27 | profile 28 | })); 29 | }); 30 | 31 | it('should read duration from the named profile', async () => { 32 | const duration = 'LONGER!!'; 33 | 34 | LoadProfilesFromConfigModule.loadProfilesFromConfig.and.returnValue({ 35 | [profile]: { 36 | duration_seconds: duration 37 | } 38 | }); 39 | 40 | const result = await getProfileOptionsValues(profile); 41 | 42 | expect(result).toEqual({ 43 | duration 44 | }); 45 | }); 46 | 47 | it('should read externalId from the named profile', async () => { 48 | const externalId = 'Id, BUT on the outside!'; 49 | 50 | LoadProfilesFromConfigModule.loadProfilesFromConfig.and.returnValue({ 51 | [profile]: { 52 | external_id: externalId 53 | } 54 | }); 55 | 56 | const result = await getProfileOptionsValues(profile); 57 | 58 | expect(result).toEqual({ 59 | externalId 60 | }); 61 | }); 62 | 63 | it('should read sessionName from the named profile', async () => { 64 | const sessionName = 'Yoga for beginners'; 65 | 66 | LoadProfilesFromConfigModule.loadProfilesFromConfig.and.returnValue({ 67 | [profile]: { 68 | role_session_name: sessionName 69 | } 70 | }); 71 | 72 | const result = await getProfileOptionsValues(profile); 73 | 74 | expect(result).toEqual({ 75 | sessionName 76 | }); 77 | }); 78 | 79 | it('should read mfaTokenArn from the named profile', async () => { 80 | const mfaTokenArn = 'Id, BUT on the outside!'; 81 | 82 | LoadProfilesFromConfigModule.loadProfilesFromConfig.and.returnValue({ 83 | [profile]: { 84 | mfa_serial: mfaTokenArn 85 | } 86 | }); 87 | 88 | const result = await getProfileOptionsValues(profile); 89 | 90 | expect(result).toEqual({ 91 | mfaTokenArn 92 | }); 93 | }); 94 | 95 | it('should omit any missing options values from the profile', async () => { 96 | const options = await getProfileOptionsValues(profile); 97 | 98 | expect(options).toEqual({ 99 | }); 100 | }); 101 | 102 | it('should return an empty option set if no profiles are available', async () => { 103 | LoadProfilesFromConfigModule.loadProfilesFromConfig.and.throwError(); 104 | 105 | const result = await getProfileOptionsValues(); 106 | 107 | expect(result).toEqual({}); 108 | }); 109 | }); 110 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { 4 | AssumeRoleCommand, 5 | STSClient 6 | } = require('@aws-sdk/client-sts'); 7 | const { execSync } = require('child_process'); 8 | const { cleanAwsCredentialsCache } = require('./clean-aws-credentials-cache'); 9 | const { getProfileList } = require('./get-profile-list'); 10 | const { getProfileOptionsValues } = require('./get-profile-options-values'); 11 | const { isRoleArn } = require('./is-role-arn'); 12 | const { isWindows } = require('./is-windows'); 13 | const { 14 | DEFAULT_DURATION, 15 | DEFAULT_EXTERNAL_ID, 16 | DEFAULT_MFA_TOKEN, 17 | DEFAULT_MFA_TOKEN_ARN, 18 | DEFAULT_PRESERVE_CREDENTIALS_CACHE, 19 | DEFAULT_PROFILE, 20 | DEFAULT_ROLE_ARN, 21 | DEFAULT_SESSION_NAME, 22 | DEFAULT_VERBOSE_VALUE, 23 | 24 | ERROR_INCOMPLETE_MFA_OPTIONS, 25 | ERROR_INVALID_ROLE_ARN, 26 | ERROR_MISSING_COMMAND, 27 | ERROR_MISSING_ROLE_ARN_AND_PROFILE, 28 | 29 | NO_EXTERNAL_ID, 30 | NO_MFA_TOKEN, 31 | NO_MFA_TOKEN_ARN, 32 | NO_PROFILE, 33 | NO_ROLE_ARN, 34 | 35 | Options 36 | } = require('./options'); 37 | const { removeObjectEntries } = require('./remove-object-entries'); 38 | 39 | const EXIT_CODE = { 40 | SUCCESS: 0, 41 | UNKNOWN: 1, 42 | 43 | OPTIONS_UNKNOWN: 10, 44 | OPTIONS_INCOMPLETE_MFA: 11, 45 | OPTIONS_INVALID_ROLE_ARN: 12, 46 | OPTIONS_MISSING_COMMAND: 14, 47 | OPTIONS_MISSING_ROLE_ARN_AND_PROFILE: 13, 48 | 49 | ASSUME_UNKNOWN: 20 50 | }; 51 | 52 | function extractPositionalOptions (positionals) { 53 | const roleArn = isRoleArn(positionals[0]) ? positionals[0] : NO_ROLE_ARN; 54 | const command = roleArn !== NO_ROLE_ARN ? positionals.slice(1) : positionals; 55 | 56 | return { 57 | command, 58 | roleArn 59 | }; 60 | } 61 | 62 | const yargsv = require('yargs')(process.argv.slice(2)) 63 | .usage( 64 | '$0 [-d|--duration] [-p|--profile] [-n|--session-name] [-e|--external-id] [-v|--verbose] [-m|--mfa-token-arn] [-t|--mfa-token] [arn] [command..]', 65 | 'Assume an IAM role for the duration of a command', 66 | yargs => { 67 | yargs 68 | .parserConfiguration({ 69 | 'halt-at-non-option': true 70 | }) 71 | .option('d', { 72 | alias: 'duration', 73 | describe: 74 | 'The duration to assume this role in seconds. See https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html#API_AssumeRole_RequestParameters', 75 | default: DEFAULT_DURATION, 76 | type: 'number' 77 | }) 78 | .option('p', { 79 | alias: 'profile', 80 | describe: 'The profile used to assume the role. Any profile values will override default values. Any explicit options will override profile values.', 81 | default: DEFAULT_PROFILE 82 | }) 83 | .option('n', { 84 | alias: 'session-name', 85 | describe: 'The role session name to use', 86 | default: DEFAULT_SESSION_NAME, 87 | type: 'string' 88 | }) 89 | .option('e', { 90 | alias: 'external-id', 91 | describe: 'The external id string used to authenticate role assumption', 92 | default: DEFAULT_EXTERNAL_ID, 93 | type: 'string' 94 | }) 95 | .option('v', { 96 | alias: 'verbose', 97 | describe: 'Show debug information', 98 | default: DEFAULT_VERBOSE_VALUE, 99 | type: 'boolean' 100 | }) 101 | .option('t', { 102 | alias: 'mfa-token', 103 | describe: 'Current MFA token [Must also supply mfa-token-arn]', 104 | default: DEFAULT_MFA_TOKEN, 105 | type: 'string' 106 | }) 107 | .option('m', { 108 | alias: 'mfa-token-arn', 109 | describe: 'ARN for users MFA [Must also supply mfa-token]', 110 | default: DEFAULT_MFA_TOKEN_ARN, 111 | type: 'string' 112 | }) 113 | .options('preserve-credentials-cache', { 114 | describe: 'Retain the AWS credentials cache folder when command is complete; otherwise remove it', 115 | default: DEFAULT_PRESERVE_CREDENTIALS_CACHE, 116 | type: 'boolean' 117 | }) 118 | .positional('arn', { 119 | default: DEFAULT_ROLE_ARN, 120 | describe: 'ARN to assume', 121 | type: 'string' 122 | }) 123 | .positional('command', { 124 | describe: 'Command to run', 125 | type: 'array' 126 | }) 127 | .help('h'); 128 | } 129 | ).argv; 130 | 131 | let options; 132 | (async () => { 133 | const isWin32 = isWindows(); 134 | const profileList = await getProfileList(); 135 | if (yargsv.profile !== NO_PROFILE && !profileList.includes(yargsv.profile)) { 136 | console.error(`Profile ${yargsv.profile} not found in AWS configuration`); 137 | process.exit(EXIT_CODE.OPTIONS_UNKNOWN); 138 | } 139 | const specifiedOptions = removeObjectEntries(yargsv, { 140 | duration: DEFAULT_DURATION, 141 | externalId: DEFAULT_EXTERNAL_ID, 142 | mfaToken: DEFAULT_MFA_TOKEN, 143 | mfaTokenArn: DEFAULT_MFA_TOKEN_ARN, 144 | sessionName: DEFAULT_SESSION_NAME, 145 | verbose: DEFAULT_VERBOSE_VALUE 146 | }); 147 | const positionalOptions = removeObjectEntries(extractPositionalOptions(yargsv._), { roleArn: NO_ROLE_ARN }); 148 | const profileOptionsValues = yargsv.profile !== NO_PROFILE 149 | ? await getProfileOptionsValues(yargsv.profile) 150 | : {}; 151 | 152 | try { 153 | options = new Options({ 154 | ...profileOptionsValues, 155 | ...specifiedOptions, 156 | ...positionalOptions 157 | }); 158 | 159 | if (options.verbose) { 160 | console.log('options', options); 161 | } 162 | } 163 | catch (error) { 164 | let exitCode = EXIT_CODE.UNKNOWN; 165 | 166 | switch (error.errorType) { 167 | case ERROR_INCOMPLETE_MFA_OPTIONS: 168 | console.error(`To use MFA you must supply both --mfa-token-arn and --mfa-token. Missing value: ${error.errorDetail}`); 169 | exitCode = EXIT_CODE.OPTIONS_INCOMPLETE_MFA; 170 | break; 171 | case ERROR_INVALID_ROLE_ARN: 172 | console.log(`Invalid role arn provided. Provided value: ${error.errorDetail}`); 173 | exitCode = EXIT_CODE.OPTIONS_INVALID_ROLE_ARN; 174 | break; 175 | case ERROR_MISSING_COMMAND: 176 | console.log('A command to execute must be provided.'); 177 | exitCode = EXIT_CODE.OPTIONS_MISSING_ROLE_ARN_AND_PROFILE; 178 | break; 179 | case ERROR_MISSING_ROLE_ARN_AND_PROFILE: 180 | console.log('Either a role arn or a profile must be specified'); 181 | exitCode = EXIT_CODE.OPTIONS_MISSING_COMMAND; 182 | break; 183 | default: 184 | console.log('An unknown error occurred.', error.message); 185 | exitCode = EXIT_CODE.OPTIONS_UNKNOWN; 186 | break; 187 | } 188 | 189 | process.exit(exitCode); 190 | } 191 | 192 | if (options.verbose) { 193 | if (options.roleArn !== NO_ROLE_ARN) { 194 | console.log(`Using RoleArn: ${options.roleArn}`); 195 | } 196 | 197 | if (options.profile !== NO_PROFILE) { 198 | console.log(`Using Profile: ${options.profile}`); 199 | } 200 | } 201 | 202 | const assumeRoleParameters = { 203 | RoleSessionName: options.sessionName, 204 | DurationSeconds: options.duration, 205 | RoleArn: options.roleArn 206 | }; 207 | 208 | if (options.externalId !== NO_EXTERNAL_ID) { 209 | assumeRoleParameters.ExternalId = options.externalId; 210 | } 211 | 212 | const stsOptions = {}; 213 | if (options.mfaToken !== NO_MFA_TOKEN && options.mfaTokenArn !== NO_MFA_TOKEN_ARN) { 214 | assumeRoleParameters.SerialNumber = options.mfaTokenArn; 215 | assumeRoleParameters.TokenCode = options.mfaToken; 216 | stsOptions.correctClockSkew = true; 217 | } 218 | 219 | let awsEnvironmentSetCommands; 220 | try { 221 | const sts = new STSClient(stsOptions); 222 | const data = await sts 223 | .send(new AssumeRoleCommand(assumeRoleParameters)); 224 | const credentials = data.Credentials; 225 | 226 | awsEnvironmentSetCommands = [ 227 | ['AWS_ACCESS_KEY_ID', credentials.AccessKeyId], 228 | ['AWS_SECRET_ACCESS_KEY', credentials.SecretAccessKey], 229 | ['AWS_SESSION_TOKEN', credentials.SessionToken], 230 | ['AWS_EXPIRATION', credentials.Expiration.toISOString()] 231 | ] 232 | .map(arr => arr.join('=')); 233 | } catch (err) { 234 | console.log('Exception while assuming role:', err); 235 | process.exit(EXIT_CODE.ASSUME_UNKNOWN); 236 | } 237 | 238 | let command; 239 | if (isWin32) { 240 | command = awsEnvironmentSetCommands 241 | .map((arr) => `SET "${arr}"`) 242 | .concat(options.command.join(' ')) 243 | .join(' & '); 244 | } 245 | else { 246 | command = awsEnvironmentSetCommands 247 | .concat(options.command) 248 | .join(' '); 249 | } 250 | 251 | if (options.verbose) { 252 | console.log(`Running command ${command}`); 253 | } 254 | 255 | execSync(command, { stdio: 'inherit' }); 256 | 257 | if (!options.preserveCredentialsCache) { 258 | cleanAwsCredentialsCache({ isWindows: isWin32 }); 259 | } 260 | })().catch(err => { 261 | if (yargsv.verbose) { 262 | const maskedError = err.toString().replace(/(AWS_\w+?=)(\S+)/g, '$1XXXXXXXXXXXXXXXXXXXX'); 263 | console.log('Caught runtime exception:', maskedError); 264 | } 265 | 266 | process.exit(EXIT_CODE.UNKNOWN); 267 | }); 268 | -------------------------------------------------------------------------------- /src/is-role-arn/index.js: -------------------------------------------------------------------------------- 1 | function isRoleArn (roleArn) { 2 | return [ 3 | /^arn:aws:iam/, 4 | /^arn:aws-cn:iam/, 5 | /^arn:aws-us-gov:iam/ 6 | ].some(regex => regex.test(roleArn)); 7 | } 8 | 9 | module.exports = { 10 | isRoleArn 11 | }; 12 | -------------------------------------------------------------------------------- /src/is-windows/index.js: -------------------------------------------------------------------------------- 1 | function isWindows() { 2 | // Based on current values: https://nodejs.org/api/process.html#process_process_platform 3 | return process.platform === 'win32'; 4 | } 5 | 6 | module.exports = { 7 | isWindows 8 | }; 9 | -------------------------------------------------------------------------------- /src/load-profiles-from-config/index.js: -------------------------------------------------------------------------------- 1 | const { loadSharedConfigFiles } = require('@aws-sdk/shared-ini-file-loader'); 2 | 3 | async function loadProfilesFromConfig({ profile } = {}) { 4 | try { 5 | const { 6 | configFile: profiles 7 | } = await loadSharedConfigFiles({ profile }); 8 | 9 | return profiles; 10 | } 11 | catch (__error) { 12 | return {}; 13 | } 14 | } 15 | 16 | module.exports = { 17 | loadProfilesFromConfig 18 | }; -------------------------------------------------------------------------------- /src/options/index.js: -------------------------------------------------------------------------------- 1 | const { isRoleArn } = require('../is-role-arn'); 2 | 3 | const NO_EXTERNAL_ID = false; 4 | const NO_MFA_TOKEN = false; 5 | const NO_MFA_TOKEN_ARN = false; 6 | const NO_PROFILE = ''; 7 | const NO_ROLE_ARN = ''; 8 | 9 | const DEFAULT_DURATION = 900; 10 | const DEFAULT_EXTERNAL_ID = NO_EXTERNAL_ID; 11 | const DEFAULT_MFA_TOKEN = NO_MFA_TOKEN; 12 | const DEFAULT_MFA_TOKEN_ARN = NO_MFA_TOKEN_ARN; 13 | const DEFAULT_PRESERVE_CREDENTIALS_CACHE = false; 14 | const DEFAULT_PROFILE = NO_PROFILE; 15 | const DEFAULT_ROLE_ARN = NO_ROLE_ARN; 16 | const DEFAULT_SESSION_NAME = 'RoleSession'; 17 | const DEFAULT_VERBOSE_VALUE = false; 18 | 19 | const ERROR_INCOMPLETE_MFA_OPTIONS = 'ERROR_INCOMPLETE_MFA_OPTIONS'; 20 | const ERROR_INVALID_ROLE_ARN = 'ERROR_INVALID_ROLE_ARN'; 21 | const ERROR_MISSING_COMMAND = 'ERROR_MISSING_COMMAND'; 22 | const ERROR_MISSING_ROLE_ARN_AND_PROFILE = 'ERROR_MISSING_ROLE_ARN_AND_PROFILE'; 23 | 24 | class OptionsError extends Error { 25 | constructor (errorType, errorDetail = '') { 26 | super('An error occurred constructing awsudo options'); 27 | 28 | this.errorDetail = errorDetail; 29 | this.errorType = errorType; 30 | } 31 | } 32 | 33 | class Options { 34 | // eslint-disable-next-line complexity 35 | constructor ({ 36 | command, 37 | duration = DEFAULT_DURATION, 38 | externalId = DEFAULT_EXTERNAL_ID, 39 | mfaToken = DEFAULT_MFA_TOKEN, 40 | mfaTokenArn = DEFAULT_MFA_TOKEN_ARN, 41 | preserveCredentialsCache = DEFAULT_PRESERVE_CREDENTIALS_CACHE, 42 | profile = DEFAULT_PROFILE, 43 | roleArn = DEFAULT_ROLE_ARN, 44 | sessionName = DEFAULT_SESSION_NAME, 45 | verbose = DEFAULT_VERBOSE_VALUE 46 | }) { 47 | if ((mfaToken === NO_MFA_TOKEN && mfaTokenArn !== NO_MFA_TOKEN_ARN) || 48 | (mfaToken !== NO_MFA_TOKEN && mfaTokenArn === NO_MFA_TOKEN_ARN)) { 49 | const missingOption = mfaToken === NO_MFA_TOKEN ? 'mfaToken' : 'mfaTokenArn'; 50 | throw new OptionsError(ERROR_INCOMPLETE_MFA_OPTIONS, missingOption); 51 | } 52 | 53 | if (roleArn !== NO_ROLE_ARN && !isRoleArn(roleArn)) { 54 | throw new OptionsError(ERROR_INVALID_ROLE_ARN); 55 | } 56 | 57 | if (!roleArn && !profile) { 58 | throw new OptionsError(ERROR_MISSING_ROLE_ARN_AND_PROFILE); 59 | } 60 | 61 | if (!Array.isArray(command) || command.length === 0) { 62 | throw new OptionsError(ERROR_MISSING_COMMAND); 63 | } 64 | 65 | this.command = command; 66 | this.duration = duration; 67 | this.externalId = externalId; 68 | this.mfaToken = mfaToken; 69 | this.mfaTokenArn = mfaTokenArn; 70 | this.preserveCredentialsCache = preserveCredentialsCache; 71 | this.profile = profile; 72 | this.roleArn = roleArn; 73 | this.sessionName = sessionName; 74 | this.verbose = verbose; 75 | 76 | Object.freeze(this); 77 | } 78 | } 79 | 80 | module.exports = { 81 | DEFAULT_DURATION, 82 | DEFAULT_EXTERNAL_ID, 83 | DEFAULT_MFA_TOKEN, 84 | DEFAULT_MFA_TOKEN_ARN, 85 | DEFAULT_PRESERVE_CREDENTIALS_CACHE, 86 | DEFAULT_PROFILE, 87 | DEFAULT_ROLE_ARN, 88 | DEFAULT_SESSION_NAME, 89 | DEFAULT_VERBOSE_VALUE, 90 | 91 | ERROR_INCOMPLETE_MFA_OPTIONS, 92 | ERROR_INVALID_ROLE_ARN, 93 | ERROR_MISSING_COMMAND, 94 | ERROR_MISSING_ROLE_ARN_AND_PROFILE, 95 | 96 | NO_EXTERNAL_ID, 97 | NO_MFA_TOKEN, 98 | NO_MFA_TOKEN_ARN, 99 | NO_PROFILE, 100 | NO_ROLE_ARN, 101 | 102 | Options 103 | }; 104 | -------------------------------------------------------------------------------- /src/remove-object-entries/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Remove the matching entries from the object. 3 | * An entry matches if its name and value is the same. 4 | * 5 | * @param {object} baseObject - The object to base the return value on 6 | * @param {object} entries - An object of entries to remove 7 | * @returns {object} - A copy of `baseObject` stripped of properties matching `entries` 8 | */ 9 | function removeObjectEntries (baseObject, entries) { 10 | return Object.fromEntries(Object.entries(baseObject) 11 | .filter(([key, value]) => entries[key] !== value) 12 | ); 13 | } 14 | 15 | module.exports = { 16 | removeObjectEntries 17 | }; 18 | -------------------------------------------------------------------------------- /src/remove-object-entries/index.spec.js: -------------------------------------------------------------------------------- 1 | const { removeObjectEntries } = require('./index'); 2 | 3 | describe('Removing object entries', () => { 4 | it('should remove matching entries from the object', () => { 5 | const entries = { discardThisProperty: true }; 6 | 7 | const result = removeObjectEntries( 8 | { other: 'properties', ...entries }, 9 | entries 10 | ); 11 | 12 | expect(result).not.toEqual(jasmine.objectContaining(entries)); 13 | }); 14 | 15 | it('should not remove non-matching entries from the object', () => { 16 | const baseObject = { keepThisProperty: true }; 17 | 18 | const result = removeObjectEntries( 19 | baseObject, 20 | { missing: 'properties' } 21 | ); 22 | 23 | expect(result).toEqual(baseObject); 24 | }); 25 | 26 | it('should remove matching undefined values', () => { 27 | const undefinedProperty = 'divideByZero'; 28 | 29 | const result = removeObjectEntries( 30 | { [undefinedProperty]: undefined }, 31 | {} 32 | ); 33 | 34 | expect(result.hasOwnProperty(undefinedProperty)).toBeFalse(); 35 | }); 36 | 37 | it('should not remove non-matching undefined values', () => { 38 | const undefinedProperty = 'divideByZero'; 39 | 40 | const result = removeObjectEntries( 41 | { [undefinedProperty]: undefined }, 42 | { [undefinedProperty]: 'not really' } 43 | ); 44 | 45 | expect(result.hasOwnProperty(undefinedProperty)).toBeTrue(); 46 | }); 47 | }); 48 | --------------------------------------------------------------------------------