diff --git a/.dockerignore b/.dockerignore index 9cf03a44..660e02ca 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,11 +1,14 @@ node_modules **/node_modules +# Required for the async_init_with_node_modules unit test +!test/handlers/async_init_with_node_modules/node_modules + build **/build -lib -**/lib +dist +**/dist .idea **/.idea @@ -13,7 +16,5 @@ lib package-lock.json **/package-lock.json -test/integration/*.ts - .git .DS_STORE \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..d8498adf --- /dev/null +++ b/.eslintignore @@ -0,0 +1,7 @@ +node_modules +**/node_modules + +async_init_package +test-handlers + +dist/** \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 773d29e1..1f9466f0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,38 +1,31 @@ { - "parser": "@typescript-eslint/parser", "parserOptions": { - "project": ["src/tsconfig.json", "test/unit/tsconfig.json"] + "ecmaVersion": 2022 }, - "plugins": ["@typescript-eslint", "prettier"], "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "prettier" + "plugin:prettier/recommended" ], "env": { "node": true, + "mocha": true, "es6": true }, "rules": { - "@typescript-eslint/restrict-plus-operands": "error", - "@typescript-eslint/interface-name-prefix": "off", - "no-async-promise-executor": "warn", - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/indent": "off", - "@typescript-eslint/ban-types": "warn", - "no-console": "warn", - "no-shadow": "warn" - }, - "overrides": [ - { - "files":["test/**/*.ts"], - "rules": { - "no-console": "off", - "@typescript-eslint/no-explicit-any": "off", - "no-prototype-builtins": "off", - "strictBindCallApply": "off" + "strict": [ + "error", + "global" + ], + "indent": [ + "error", + 2 + ], + "camelcase": "error", + "no-console": "off", + "no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_" } - } - ] + ] + } } \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..44eb4ddb --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ +_Issue #, if available:_ + +_Description of changes:_ + +_Target (OCI, Managed Runtime, both):_ + +## Checklist +- [ ] I have run `npm install` to generate the `package-lock.json` correctly and included it in the PR. + +By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..d41c1ad1 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +version: 2 +updates: + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "npm" + directory: "/test/handlers" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" \ No newline at end of file diff --git a/.github/workflows/test-on-push-and-pr.yml b/.github/workflows/test-on-push-and-pr.yml index bd5c9be8..3a4b7150 100644 --- a/.github/workflows/test-on-push-and-pr.yml +++ b/.github/workflows/test-on-push-and-pr.yml @@ -7,14 +7,18 @@ on: branches: [ '*' ] jobs: - build: + unit-test: runs-on: ubuntu-latest - + strategy: + fail-fast: false + matrix: + node-version: [18, 20, 22] + steps: - - uses: actions/checkout@v2 - - name: Set up node - uses: actions/setup-node@v1 - with: - node-version: '12' - - name: Run 'pr' target - run: make pr + - uses: actions/checkout@v5 + - name: Build and run tests for Node.js ${{ matrix.node-version }} + run: | + docker build -f test/unit/Dockerfile.nodejs${{ matrix.node-version }}.x -t unit/nodejs.${{ matrix.node-version }}x . + docker run unit/nodejs.${{ matrix.node-version }}x + + diff --git a/.gitignore b/.gitignore index 0a19beeb..22f46116 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,6 @@ test/integration/resources/init logs *.log npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -20,9 +17,6 @@ pids *.seed *.pid.lock -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - # Coverage directory used by tools like istanbul coverage *.lcov @@ -30,93 +24,34 @@ coverage # nyc test coverage .nyc_output -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - # Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ -# TypeScript cache -*.tsbuildinfo +# Required for the async_init_with_node_modules unit test +!test/handlers/async_init_with_node_modules/node_modules # Optional npm cache directory .npm # Optional eslint cache .eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history +.eslintignore # Output of 'npm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -lib/ - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port +# Build +dist/ # Stores VSCode versions used for testing VSCode extensions .vscode-test -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* -.idea/ +deps/artifacts/ +deps/aws-lambda-cpp*/ +deps/curl*/ + +# Local codebuild +codebuild.*/ \ No newline at end of file diff --git a/.npmignore b/.npmignore index 1929246f..af2d322b 100644 --- a/.npmignore +++ b/.npmignore @@ -1,16 +1,15 @@ build .DS_Store -src +src/* +# Rapid-client.c to be used with node-gyp +!src/rapid-client.cc test # Logs logs *.log npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # IDEs .idea @@ -35,27 +34,11 @@ coverage # nyc test coverage .nyc_output -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - # Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo # Optional npm cache directory .npm @@ -63,68 +46,14 @@ web_modules/ # Optional eslint config & cache .eslintrc .eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history +.eslintignore # Output of 'npm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - # Stores VSCode versions used for testing VSCode extensions .vscode-test -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* - # git .git* diff --git a/Makefile b/Makefile index 8a3222fb..867468c1 100644 --- a/Makefile +++ b/Makefile @@ -1,61 +1,40 @@ -.PHONY: target target: $(info ${HELP_MESSAGE}) @exit 0 -.PHONY: init init: npm install -.PHONY: test test: npm run test -.PHONY: setup-codebuild-agent -setup-codebuild-agent: - docker build -t codebuild-agent - < test/integration/codebuild-local/Dockerfile.agent - -.PHONY: test-smoke -test-smoke: setup-codebuild-agent - CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_one.sh test/integration/codebuild/buildspec.os.alpine.2.yml alpine 3.12 14 - -.PHONY: test-integ -test-integ: setup-codebuild-agent - CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_all.sh test/integration/codebuild - -.PHONY: copy-files copy-files: npm run copy-files -.PHONY: install install: BUILD=$(BUILD) npm install -.PHONY: format format: npm run format # Command to run everytime you make changes to verify everything works -.PHONY: dev dev: init test # Verifications to run before sending a pull request -.PHONY: pr -pr: build dev test-smoke +pr: build dev -.PHONY: clean clean: npm run clean -.PHONY: build build: copy-files make install BUILD=1 npm run build -.PHONY: pack pack: build npm pack +.PHONY: target init test install format dev pr clean build pack copy-files + define HELP_MESSAGE Usage: $ make [TARGETS] diff --git a/README.md b/README.md index 8f1fa6ec..3c6dc8a4 100644 --- a/README.md +++ b/README.md @@ -10,16 +10,16 @@ You can include this package in your preferred base image to make that base imag ## Requirements The NodeJS Runtime Interface Client package currently supports NodeJS versions: - - 10.x - - 12.x - - 14.x + - 16.x + - 18.x + - 20.x ## Usage ### Creating a Docker Image for Lambda with the Runtime Interface Client First step is to choose the base image to be used. The supported Linux OS distributions are: - - Amazon Linux 2 + - Amazon Linux (2 and 2023) - Alpine - CentOS - Debian @@ -55,7 +55,7 @@ Example Dockerfile (to keep the image light we used a multi-stage build): # Define custom function directory ARG FUNCTION_DIR="/function" -FROM node:12-buster as build-image +FROM node:18-buster as build-image # Include global arg in this stage of the build ARG FUNCTION_DIR @@ -75,13 +75,17 @@ COPY myFunction/* ${FUNCTION_DIR} WORKDIR ${FUNCTION_DIR} +RUN npm install + # If the dependency is not in package.json uncomment the following line # RUN npm install aws-lambda-ric -RUN npm install - # Grab a fresh slim copy of the image to reduce the final size -FROM node:12-buster-slim +FROM node:18-buster-slim + +# Required for Node runtimes which use npm@8.6.0+ because +# by default npm writes logs under /home/.npm and Lambda fs is read-only +ENV NPM_CONFIG_CACHE=/tmp/.npm # Include global arg in this stage of the build ARG FUNCTION_DIR @@ -158,8 +162,13 @@ make init build ``` Then, * to run unit tests: `make test` -* to run integration tests: `make test-integ` -* to run smoke tests: `make test-smoke` + +### Raising a PR +When modifying dependencies (`package.json`), make sure to: +1. Run `npm install` to generate an updated `package-lock.json` +2. Commit both `package.json` and `package-lock.json` together + +We require package-lock.json to be checked in to ensure consistent installations across development environments. ### Troubleshooting diff --git a/RELEASE.CHANGELOG.md b/RELEASE.CHANGELOG.md new file mode 100644 index 00000000..078a3cf8 --- /dev/null +++ b/RELEASE.CHANGELOG.md @@ -0,0 +1,78 @@ +### May 21, 2025 +`3.3.0` +- Add support for multi tenancy ([#128](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/128)) + +### Aug 26, 2024 +`3.2.1` +- Update test dependencies ([#115](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/115)) +- Fix autoconf build issue ([#117](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/117)) + +### Jul 03, 2024 +`3.2.0` +- Introduce advanced logging controls ([#91](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/91)) +- Bump package-lock deps ([#98](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/98)) +- Remove Node14 from integ tests matrix since it is deprecated ([#99](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/99)) +- Bump tar from 6.1.15 to 6.2.1 ([#103](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/103)) +- Handle invalid char when sending HTTP request to Runtime API ([#100](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/100)) +- Bump braces from 3.0.2 to 3.0.3 ([#109](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/109)) +- Update codebuild_build.sh script ([#110](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/110)) +- Fix centos and ubuntu integ tests ([#111](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/111)) +- Encode request id in URI path ([#113](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/113)) +- Release aws-lambda-ric 3.2.0 ([#114](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/114)) + +### Nov 09, 2023 +`3.1.0` +- tar using --no-same-owner by @JavaScriptBach ([#46](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/46)) +- Use python3.8 in al2 integ tests ([#72](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/72)) +- Create pull request template ([#73](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/73)) +- Bump deps ([#79](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/79)) +- Remove unrecognized --disable-websockets option ([#80](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/80)) +- Update Distros and integration tests ([#82](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/82)) +- Clean up images after running integ tests ([#84](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/84)) +- Add Alpine3.17,3.18 remove 3.15 for integ tests ([#85](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/85)) +- Bump @babel/traverse from 7.22.5 to 7.23.2 ([#86](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/86)) +- Add Node20 to the test matrix ([#87](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/87)) +- Release aws-lambda-ric 3.1.0 ([#88](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/88)) + +### Jun 26, 2023 +`3.0.0` +- AWS Lambda response streaming support +- ES module support +- Migrate from TypeScript to JavaScript, Include type declaration files for TypeScript support. +- Support Amazon Linux 2023 +- Update RIE to v1.12 +- Reduce image size by deleting aws-lambda-cpp and curl dependencies after building them +- aws-lambda-ric 3.0.0 release ([#70](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/70)) +- Run integration tests against every distro on PR ([#71](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/71)) + + +### May 15, 2023 +`2.1.0` +- Allow passing HandlerFunction to run function directly ([#20](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/20)) +- Update dependencies: tar and ansi-regex ([#38](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/38)) +- Bump minimist from 1.2.5 to 1.2.6 ([#48](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/48)) +- Update Curl to 7.83.0 ([#49](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/49)) +- Update Curl to 7.84.0 ([#52](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/52)) +- update aws-lambda-cpp ([#57](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/57)) +- Bump minimatch and mocha ([#58](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/58)) +- Update dependencies and distros ([#65](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/65)) +- Revert libcurl 7.84.0 update ([#66](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/66)) +- Stage aws-lambda-ric 2.1.0 release ([#67](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/67)) + +### Sep 29, 2021 +`2.0.0` +- AWS Lambda Runtime Interface Client for NodeJS with ARM64 support + +### Jun 09, 2021 +`1.1.0` +- Update Curl version to 7.77.0 ([#23](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/23)) +- Update dependencies, remove unused dependencies, add prettier plugin to eslint ([#19](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/19)) +- Fix errors issues +- Remove trailing . from sample curl command +- Add `docker login` to fix pull rate limit issue ([#2](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/2)) +- Include GitHub action on push and pr ([#1](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/pull/1)) + +### Dec 01, 2020 +`1.0.0` +- Initial release of AWS Lambda Runtime Interface Client for NodeJS + diff --git a/THIRD-PARTY-LICENSES b/THIRD-PARTY-LICENSES index 8fe2e404..14a3456d 100644 --- a/THIRD-PARTY-LICENSES +++ b/THIRD-PARTY-LICENSES @@ -1,4 +1,4 @@ -** aws-lambda-cpp; version 0.2.6 -- https://github.com/awslabs/aws-lambda-cpp +** aws-lambda-cpp; version 0.2.8 -- https://github.com/awslabs/aws-lambda-cpp Apache License @@ -204,7 +204,7 @@ limitations under the License. ------ -** node-gyp; version 7.1.0 -- https://github.com/nodejs/node-gyp +** node-gyp; version 9.3.1 -- https://github.com/nodejs/node-gyp Copyright (c) 2012 Nathan Rajlich (The MIT License) @@ -234,7 +234,7 @@ OTHER DEALINGS IN THE SOFTWARE. ------ -** node-addon-api; version 3.0.1 -- https://github.com/nodejs/node-addon-api +** node-addon-api; version 6.1.0 -- https://github.com/nodejs/node-addon-api The MIT License (MIT) Copyright (c) 2017 Node.js API collaborators Node.js API collaborators listed at @@ -282,7 +282,7 @@ SOFTWARE. ------ -** libcurl; version 7.65.3 -- https://github.com/curl/curl +** libcurl; version 7.83.1 -- https://github.com/curl/curl Copyright (c) 1996 - 2020, Daniel Stenberg, , and many contributors, see the THANKS file. diff --git a/bin/index.js b/bin/index.js deleted file mode 100755 index c3f40b34..00000000 --- a/bin/index.js +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env node -/** Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -const lambda = require("../lib/index"); - -if(process.argv.length < 3) { - throw new Error("No handler specified"); -} - -const appRoot = process.cwd(); -const handler = process.argv[2]; - -console.log(`Executing '${handler}' in function directory '${appRoot}'`); -lambda.run(appRoot, handler); \ No newline at end of file diff --git a/bin/index.mjs b/bin/index.mjs new file mode 100755 index 00000000..5240e27f --- /dev/null +++ b/bin/index.mjs @@ -0,0 +1,14 @@ +#!/usr/bin/env node +/** Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +import { run } from "../dist/index.mjs" + +if (process.argv.length < 3) { + throw new Error("No handler specified"); +} + +const appRoot = process.cwd(); +const handler = process.argv[2]; + +console.log(`Executing '${handler}' in function directory '${appRoot}'`); +await run(appRoot, handler); \ No newline at end of file diff --git a/binding.gyp b/binding.gyp index dd36f5ce..64349f06 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,9 +1,9 @@ { 'targets': [ { - 'target_name': 'runtime-client', + 'target_name': 'rapid-client', 'sources': [ - 'lib/RuntimeClient/runtime-client.cc', + 'src/rapid-client.cc', ], 'dependencies': [ " - $) - --check_ipo_supported(RESULT has_lto OUTPUT lto_check_output) --if(has_lto) -- set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) --else() -- message(WARNING "Link-time optimization (LTO) is not supported: ${lto_check_output}") -+if (ENABLE_LTO) -+ include(CheckIPOSupported) -+ check_ipo_supported(RESULT has_lto OUTPUT lto_check_output) -+ if(has_lto) -+ set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) -+ else() -+ message(WARNING "Link-time optimization (LTO) is not supported: ${lto_check_output}") -+ endif() - endif() - - find_package(CURL REQUIRED) \ No newline at end of file diff --git a/deps/patches/aws-lambda-cpp-make-the-runtime-client-user-agent-overrideable.patch b/deps/patches/aws-lambda-cpp-make-the-runtime-client-user-agent-overrideable.patch deleted file mode 100644 index 8be35524..00000000 --- a/deps/patches/aws-lambda-cpp-make-the-runtime-client-user-agent-overrideable.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 846392515b2b0215902aaf7368651af196835f10 Mon Sep 17 00:00:00 2001 -From: Bryan Moffatt -Date: Wed, 21 Oct 2020 12:42:37 -0700 -Subject: [PATCH] make the Runtime Interface Client's user agent overrideable (#106) - -* make the Runtime Interface Client's user agent overrideable - -* remove extra empty string - -* clang-format -i src/* ---- - include/aws/lambda-runtime/runtime.h | 2 ++ - src/runtime.cpp | 20 ++++++++------------ - 2 files changed, 10 insertions(+), 12 deletions(-) - -diff --git a/include/aws/lambda-runtime/runtime.h b/include/aws/lambda-runtime/runtime.h -index 0dc292c..94e1e22 100644 ---- a/include/aws/lambda-runtime/runtime.h -+++ b/include/aws/lambda-runtime/runtime.h -@@ -137,6 +137,7 @@ public: - using next_outcome = aws::lambda_runtime::outcome; - using post_outcome = aws::lambda_runtime::outcome; - -+ runtime(std::string const& endpoint, std::string const& user_agent); - runtime(std::string const& endpoint); - ~runtime(); - -@@ -164,6 +165,7 @@ private: - invocation_response const& handler_response); - - private: -+ std::string const m_user_agent_header; - std::array const m_endpoints; - CURL* const m_curl_handle; - }; -diff --git a/src/runtime.cpp b/src/runtime.cpp -index e2ee7cd..f6131a4 100644 ---- a/src/runtime.cpp -+++ b/src/runtime.cpp -@@ -124,12 +124,6 @@ static size_t write_header(char* ptr, size_t size, size_t nmemb, void* userdata) - return size * nmemb; - } - --static std::string const& get_user_agent_header() --{ -- static std::string user_agent = std::string("User-Agent: AWS_Lambda_Cpp/") + get_version(); -- return user_agent; --} -- - static size_t read_data(char* buffer, size_t size, size_t nitems, void* userdata) - { - auto const limit = size * nitems; -@@ -163,10 +157,12 @@ static int rt_curl_debug_callback(CURL* handle, curl_infotype type, char* data, - } - #endif - --runtime::runtime(std::string const& endpoint) -- : m_endpoints{{endpoint + "/2018-06-01/runtime/init/error", -- endpoint + "/2018-06-01/runtime/invocation/next", -- endpoint + "/2018-06-01/runtime/invocation/"}}, -+runtime::runtime(std::string const& endpoint) : runtime(endpoint, "AWS_Lambda_Cpp/" + std::string(get_version())) {} -+ -+runtime::runtime(std::string const& endpoint, std::string const& user_agent) -+ : m_user_agent_header("User-Agent: " + user_agent), m_endpoints{{endpoint + "/2018-06-01/runtime/init/error", -+ endpoint + "/2018-06-01/runtime/invocation/next", -+ endpoint + "/2018-06-01/runtime/invocation/"}}, - m_curl_handle(curl_easy_init()) - { - if (!m_curl_handle) { -@@ -234,7 +230,7 @@ runtime::next_outcome runtime::get_next() - curl_easy_setopt(m_curl_handle, CURLOPT_HEADERDATA, &resp); - - curl_slist* headers = nullptr; -- headers = curl_slist_append(headers, get_user_agent_header().c_str()); -+ headers = curl_slist_append(headers, m_user_agent_header.c_str()); - curl_easy_setopt(m_curl_handle, CURLOPT_HTTPHEADER, headers); - - logging::log_debug(LOG_TAG, "Making request to %s", m_endpoints[Endpoints::NEXT].c_str()); -@@ -343,7 +343,7 @@ runtime::post_outcome runtime::do_post( - headers = curl_slist_append(headers, ("lambda-runtime-function-xray-error-cause: " + xray_response).c_str()); - headers = curl_slist_append(headers, "Expect:"); - headers = curl_slist_append(headers, "transfer-encoding:"); -- headers = curl_slist_append(headers, get_user_agent_header().c_str()); -+ headers = curl_slist_append(headers, m_user_agent_header.c_str()); - - logging::log_debug( - LOG_TAG, "calculating content length... %s", ("content-length: " + std::to_string(payload.length())).c_str()); --- -2.25.2 - diff --git a/deps/patches/aws-lambda-cpp-posting-init-errors.patch b/deps/patches/aws-lambda-cpp-posting-init-errors.patch deleted file mode 100644 index 8d202b58..00000000 --- a/deps/patches/aws-lambda-cpp-posting-init-errors.patch +++ /dev/null @@ -1,206 +0,0 @@ -diff --git a/include/aws/lambda-runtime/runtime.h b/include/aws/lambda-runtime/runtime.h -index be77d93..9597272 100644 ---- a/include/aws/lambda-runtime/runtime.h -+++ b/include/aws/lambda-runtime/runtime.h -@@ -67,28 +67,58 @@ struct invocation_request { - inline std::chrono::milliseconds get_time_remaining() const; - }; - --class invocation_response { --private: -+class runtime_response { -+protected: - /** -- * The output of the function which is sent to the lambda caller. -+ * The response payload from the runtime. - */ - std::string m_payload; - - /** - * The MIME type of the payload. -- * This is always set to 'application/json' in unsuccessful invocations. - */ - std::string m_content_type; - - /** -- * Flag to distinguish if the contents are for successful or unsuccessful invocations. -+ * The serialized XRay response header. - */ -- bool m_success; -+ std::string m_xray_response; - - /** -- * The serialized XRay response header. -+ * Instantiate an empty response. - */ -- std::string m_xray_response; -+ runtime_response() = default; -+public: -+ /* Create a runtime response with the given payload, content type and xray response. This can be used for constructing an -+ * initialization error response. For invocation success and failure response, see invocation_response. -+ */ -+ runtime_response(std::string const& payload, std::string const& content_type, std::string const& xray_response) -+ : m_payload(payload), m_content_type(content_type), m_xray_response(xray_response) -+ { -+ } -+ -+ /** -+ * Get the payload string. The string is assumed to be UTF-8 encoded. -+ */ -+ std::string const& get_payload() const { return m_payload; } -+ -+ /** -+ * Get the MIME type of the payload. -+ */ -+ std::string const& get_content_type() const { return m_content_type; } -+ -+ /** -+ * Get the XRay response string. The string is assumed to be UTF-8 encoded. -+ */ -+ std::string const& get_xray_response() const { return m_xray_response; } -+}; -+ -+class invocation_response: public runtime_response { -+private: -+ /** -+ * Flag to distinguish if the contents are for successful or unsuccessful invocations. -+ */ -+ bool m_success; - - /** - * Instantiate an empty response. Used by the static functions 'success' and 'failure' to create a populated -@@ -102,12 +132,10 @@ public: - // To support clients that need to control the entire error response body (e.g. adding a stack trace), this - // constructor should be used instead. - // Note: adding an overload to invocation_response::failure is not feasible since the parameter types are the same. -- invocation_response(std::string const& payload, std::string const& content_type, bool success, std::string const& xray_response): -- m_payload(payload), -- m_content_type(content_type), -- m_success(success), -- m_xray_response(xray_response) -- {} -+ invocation_response(std::string const& payload, std::string const& content_type, bool success, std::string const& xray_response) -+ : runtime_response(payload, content_type, xray_response), m_success(success) -+ { -+ } - - /** - * Create a successful invocation response with the given payload and content-type. -@@ -120,25 +148,10 @@ public: - */ - static invocation_response failure(std::string const& error_message, std::string const& error_type, std::string const& xray_response); - -- /** -- * Get the MIME type of the payload. -- */ -- std::string const& get_content_type() const { return m_content_type; } -- -- /** -- * Get the payload string. The string is assumed to be UTF-8 encoded. -- */ -- std::string const& get_payload() const { return m_payload; } -- - /** - * Returns true if the payload and content-type are set. Returns false if the error message and error types are set. - */ - bool is_success() const { return m_success; } -- -- /** -- * Get the XRay response string. The string isassumed to be UTF-8 encoded. -- */ -- std::string const& get_xray_response() const { return m_xray_response; } - }; - - struct no_result { -@@ -167,13 +180,19 @@ public: - */ - post_outcome post_failure(std::string const& request_id, invocation_response const& handler_response); - -+ /** -+ * Tells lambda that the runtime has failed during initialization. -+ */ -+ post_outcome post_init_error(runtime_response const& init_error_response); -+ - private: - void set_curl_next_options(); - void set_curl_post_result_options(); - post_outcome do_post( - std::string const& url, -- std::string const& request_id, -- invocation_response const& handler_response); -+ std::string const& content_type, -+ std::string const& payload, -+ std::string const& xray_response); - - private: - std::array const m_endpoints; -diff --git a/src/runtime.cpp b/src/runtime.cpp -index d895c4b..659666e 100644 ---- a/src/runtime.cpp -+++ b/src/runtime.cpp -@@ -311,37 +311,44 @@ runtime::next_outcome runtime::get_next() - runtime::post_outcome runtime::post_success(std::string const& request_id, invocation_response const& handler_response) - { - std::string const url = m_endpoints[Endpoints::RESULT] + request_id + "/response"; -- return do_post(url, request_id, handler_response); -+ return do_post(url, handler_response.get_content_type(), handler_response.get_payload(), handler_response.get_xray_response()); - } - - runtime::post_outcome runtime::post_failure(std::string const& request_id, invocation_response const& handler_response) - { - std::string const url = m_endpoints[Endpoints::RESULT] + request_id + "/error"; -- return do_post(url, request_id, handler_response); -+ return do_post(url, handler_response.get_content_type(), handler_response.get_payload(), handler_response.get_xray_response()); -+} -+ -+runtime::post_outcome runtime::post_init_error(runtime_response const& init_error_response) -+{ -+ std::string const url = m_endpoints[Endpoints::INIT]; -+ return do_post(url, init_error_response.get_content_type(), init_error_response.get_payload(), init_error_response.get_xray_response()); - } - - runtime::post_outcome runtime::do_post( - std::string const& url, -- std::string const& request_id, -- invocation_response const& handler_response) -+ std::string const& content_type, -+ std::string const& payload, -+ std::string const& xray_response) - { - set_curl_post_result_options(); - curl_easy_setopt(m_curl_handle, CURLOPT_URL, url.c_str()); - logging::log_info(LOG_TAG, "Making request to %s", url.c_str()); - - curl_slist* headers = nullptr; -- if (handler_response.get_content_type().empty()) { -+ if (content_type.empty()) { - headers = curl_slist_append(headers, "content-type: text/html"); - } - else { -- headers = curl_slist_append(headers, ("content-type: " + handler_response.get_content_type()).c_str()); -+ headers = curl_slist_append(headers, ("content-type: " + content_type).c_str()); - } - -- headers = curl_slist_append(headers, ("lambda-runtime-function-xray-error-cause: " + handler_response.get_xray_response()).c_str()); -+ headers = curl_slist_append(headers, ("lambda-runtime-function-xray-error-cause: " + xray_response).c_str()); - headers = curl_slist_append(headers, "Expect:"); - headers = curl_slist_append(headers, "transfer-encoding:"); - headers = curl_slist_append(headers, get_user_agent_header().c_str()); -- auto const& payload = handler_response.get_payload(); -+ - logging::log_debug( - LOG_TAG, "calculating content length... %s", ("content-length: " + std::to_string(payload.length())).c_str()); - headers = curl_slist_append(headers, ("content-length: " + std::to_string(payload.length())).c_str()); -@@ -358,10 +365,10 @@ runtime::post_outcome runtime::do_post( - if (curl_code != CURLE_OK) { - logging::log_debug( - LOG_TAG, -- "CURL returned error code %d - %s, for invocation %s", -+ "CURL returned error code %d - %s, when calling %s", - curl_code, - curl_easy_strerror(curl_code), -- request_id.c_str()); -+ url.c_str()); - return aws::http::response_code::REQUEST_NOT_MADE; - } - diff --git a/deps/patches/libcurl-configure-template.patch b/deps/patches/libcurl-configure-template.patch new file mode 100644 index 00000000..e26be47e --- /dev/null +++ b/deps/patches/libcurl-configure-template.patch @@ -0,0 +1,131 @@ +diff --git a/configure.ac b/configure.ac +index d24daea..64aca7f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -193,87 +193,96 @@ AS_HELP_STRING([--with-schannel],[enable Windows native SSL/TLS]), + + OPT_SECURETRANSPORT=no + AC_ARG_WITH(secure-transport,dnl +-AS_HELP_STRING([--with-secure-transport],[enable Apple OS native SSL/TLS]), ++AS_HELP_STRING([--with-secure-transport],[enable Apple OS native SSL/TLS]),[ + OPT_SECURETRANSPORT=$withval + test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }Secure-Transport" +-) ++]) + + OPT_AMISSL=no + AC_ARG_WITH(amissl,dnl +-AS_HELP_STRING([--with-amissl],[enable Amiga native SSL/TLS (AmiSSL)]), ++AS_HELP_STRING([--with-amissl],[enable Amiga native SSL/TLS (AmiSSL)]),[ + OPT_AMISSL=$withval +- test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }AmiSSL") ++ test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }AmiSSL" ++]) ++ + + OPT_OPENSSL=no + dnl Default to no CA bundle + ca="no" + AC_ARG_WITH(ssl,dnl + AS_HELP_STRING([--with-ssl=PATH],[old version of --with-openssl]) +-AS_HELP_STRING([--without-ssl], [build without any TLS library]), ++AS_HELP_STRING([--without-ssl], [build without any TLS library]),[ + OPT_SSL=$withval + OPT_OPENSSL=$withval + if test X"$withval" != Xno; then +- test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }OpenSSL") ++ test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }OpenSSL" + fi ++]) + + AC_ARG_WITH(openssl,dnl +-AS_HELP_STRING([--with-openssl=PATH],[Where to look for OpenSSL, PATH points to the SSL installation (default: /usr/local/ssl); when possible, set the PKG_CONFIG_PATH environment variable instead of using this option]), ++AS_HELP_STRING([--with-openssl=PATH],[Where to look for OpenSSL, PATH points to the SSL installation (default: /usr/local/ssl); when possible, set the PKG_CONFIG_PATH environment variable instead of using this option]),[ + OPT_OPENSSL=$withval + if test X"$withval" != Xno; then +- test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }OpenSSL") ++ test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }OpenSSL" + fi ++]) + + OPT_GNUTLS=no + AC_ARG_WITH(gnutls,dnl +-AS_HELP_STRING([--with-gnutls=PATH],[where to look for GnuTLS, PATH points to the installation root]), ++AS_HELP_STRING([--with-gnutls=PATH],[where to look for GnuTLS, PATH points to the installation root]),[ + OPT_GNUTLS=$withval + if test X"$withval" != Xno; then +- test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }GnuTLS") ++ test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }GnuTLS" + fi ++]) + + OPT_MBEDTLS=no + AC_ARG_WITH(mbedtls,dnl +-AS_HELP_STRING([--with-mbedtls=PATH],[where to look for mbedTLS, PATH points to the installation root]), ++AS_HELP_STRING([--with-mbedtls=PATH],[where to look for mbedTLS, PATH points to the installation root]),[ + OPT_MBEDTLS=$withval + if test X"$withval" != Xno; then +- test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }mbedTLS") ++ test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }mbedTLS" + fi ++]) + + OPT_WOLFSSL=no + AC_ARG_WITH(wolfssl,dnl +-AS_HELP_STRING([--with-wolfssl=PATH],[where to look for WolfSSL, PATH points to the installation root (default: system lib default)]), ++AS_HELP_STRING([--with-wolfssl=PATH],[where to look for WolfSSL, PATH points to the installation root (default: system lib default)]),[ + OPT_WOLFSSL=$withval + if test X"$withval" != Xno; then +- test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }wolfSSL") ++ test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }wolfSSL" + fi ++]) + + OPT_BEARSSL=no + AC_ARG_WITH(bearssl,dnl +-AS_HELP_STRING([--with-bearssl=PATH],[where to look for BearSSL, PATH points to the installation root]), ++AS_HELP_STRING([--with-bearssl=PATH],[where to look for BearSSL, PATH points to the installation root]),[ + OPT_BEARSSL=$withval + if test X"$withval" != Xno; then +- test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }BearSSL") ++ test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }BearSSL" + fi ++]) + + OPT_RUSTLS=no + AC_ARG_WITH(rustls,dnl +-AS_HELP_STRING([--with-rustls=PATH],[where to look for rustls, PATH points to the installation root]), ++AS_HELP_STRING([--with-rustls=PATH],[where to look for rustls, PATH points to the installation root]),[ + OPT_RUSTLS=$withval + if test X"$withval" != Xno; then +- test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }rustls") ++ test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }rustls" + fi ++]) + + OPT_NSS_AWARE=no + AC_ARG_WITH(nss-deprecated,dnl +-AS_HELP_STRING([--with-nss-deprecated],[confirm you realize NSS is going away]), ++AS_HELP_STRING([--with-nss-deprecated],[confirm you realize NSS is going away]),[ + if test X"$withval" != Xno; then + OPT_NSS_AWARE=$withval + fi +-) ++]) + + OPT_NSS=no + AC_ARG_WITH(nss,dnl +-AS_HELP_STRING([--with-nss=PATH],[where to look for NSS, PATH points to the installation root]), ++AS_HELP_STRING([--with-nss=PATH],[where to look for NSS, PATH points to the installation root]),[ + OPT_NSS=$withval + if test X"$withval" != Xno; then + +@@ -283,7 +292,7 @@ AS_HELP_STRING([--with-nss=PATH],[where to look for NSS, PATH points to the inst + + test -z "TLSCHOICE" || TLSCHOICE="${TLSCHOICE:+$TLSCHOICE, }NSS" + fi +-) ++]) + + dnl If no TLS choice has been made, check if it was explicitly disabled or + dnl error out to force the user to decide. diff --git a/deps/versions b/deps/versions index d8c5b105..b7e970c3 100644 --- a/deps/versions +++ b/deps/versions @@ -1,2 +1,2 @@ -AWS_LAMBDA_CPP_RELEASE=0.2.6 -CURL_VERSION=7.77.0 \ No newline at end of file +AWS_LAMBDA_CPP_RELEASE=0.2.8 +CURL_VERSION=7_83_1 diff --git a/package-lock.json b/package-lock.json index 6a371505..024e454c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,332 +1,306 @@ { "name": "aws-lambda-ric", - "version": "1.1.0", - "lockfileVersion": 2, + "version": "3.3.0", + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "aws-lambda-ric", - "version": "1.1.0", + "version": "3.3.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "node-addon-api": "3.2.1", - "node-gyp": "8.1.0" + "node-addon-api": "6.1.0", + "node-gyp": "9.4.0" }, "bin": { - "aws-lambda-ric": "bin/index.js" + "aws-lambda-ric": "bin/index.mjs" }, "devDependencies": { - "@types/mocha": "8.2.2", - "@types/node": "^15.12.2", - "@typescript-eslint/eslint-plugin": "4.26.1", - "@typescript-eslint/parser": "4.26.1", - "eslint": "7.28.0", - "eslint-config-prettier": "8.3.0", - "eslint-plugin-prettier": "3.4.0", - "husky": "6.0.0", - "mocha": "9.0.0", + "esbuild": "^0.25.3", + "eslint": "8.42.0", + "eslint-config-prettier": "8.8.0", + "eslint-plugin-prettier": "4.2.1", + "husky": "^8.0.3", + "lambda-runtime": "file:./src/", + "mocha": "^10.8.2", + "mock-http-server": "^1.4.5", "nyc": "^15.1.0", - "prettier": "2.3.1", + "prettier": "2.8.8", "should": "13.2.3", - "ts-mocha": "8.0.0", - "typescript": "4.3.2" + "throttle": "^1.0.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.10.4" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz", - "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==", - "dev": true + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz", + "integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/core": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz", - "integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.10", - "@babel/parser": "^7.13.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", + "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helpers": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "json5": "^2.2.2", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" - } - }, - "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.12.13" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.13.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", - "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz", + "integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.13.12", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", + "@babel/compat-data": "^7.22.5", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", + "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true - }, - "node_modules/@babel/helpers": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", - "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "@babel/types": "^7.22.5" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@babel/types": "^7.22.5" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, - "dependencies": { - "color-name": "1.1.3" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "engines": { - "node": ">=0.8.0" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "node_modules/@babel/helper-validator-option": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/helpers": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", - "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "dev": true, + "dependencies": { + "@babel/types": "^7.26.10" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -335,48 +309,38 @@ } }, "node_modules/@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.12.13" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz", - "integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.13", - "@babel/types": "^7.13.13", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.12.13" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/traverse/node_modules/globals": { @@ -389,6426 +353,3456 @@ } }, "node_modules/@babel/types": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", - "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", + "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@esbuild/android-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz", + "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@esbuild/android-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz", + "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/@esbuild/android-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz", + "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz", + "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz", + "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz", + "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz", + "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==", + "cpu": [ + "x64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@esbuild/linux-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz", + "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz", + "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", - "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz", + "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==", + "cpu": [ + "ia32" + ], "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz", + "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz", + "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 6" + "node": ">=18" } }, - "node_modules/@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz", + "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==", + "cpu": [ + "ppc64" + ], "dev": true, - "optional": true - }, - "node_modules/@types/mocha": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", - "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "15.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz", - "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==", - "dev": true + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz", - "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz", + "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==", + "cpu": [ + "riscv64" + ], "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "4.26.1", - "@typescript-eslint/scope-manager": "4.26.1", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.21", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz", - "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz", + "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==", + "cpu": [ + "s390x" + ], "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.26.1", - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/typescript-estree": "4.26.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" + "node": ">=18" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/@esbuild/linux-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz", + "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "node": ">=18" } }, - "node_modules/@typescript-eslint/parser": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz", - "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz", + "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "4.26.1", - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/typescript-estree": "4.26.1", - "debug": "^4.3.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz", - "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz", + "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=18" } }, - "node_modules/@typescript-eslint/types": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", - "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz", + "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=18" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", - "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz", + "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", - "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz", + "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.26.1", - "eslint-visitor-keys": "^2.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=18" } }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz", + "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz", + "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==", + "cpu": [ + "ia32" + ], "dev": true, - "bin": { - "acorn": "bin/acorn" - }, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=0.4.0" + "node": ">=18" } }, - "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "node_modules/@esbuild/win32-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz", + "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==", + "cpu": [ + "x64" + ], "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, "dependencies": { - "debug": "4" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">= 6.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/agentkeepalive": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz", - "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==", - "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, "engines": { - "node": ">= 8.0.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "node_modules/@eslint/eslintrc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "dev": true, "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.2", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@eslint/js": { + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", + "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, "engines": { - "node": ">=6" + "node": ">=10.10.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dependencies": { - "color-convert": "^2.0.1" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "engines": { - "node": ">= 8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dependencies": { - "default-require-extensions": "^3.0.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "dependencies": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "node_modules/cacache": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", - "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", - "dependencies": { - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cacache/node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001235", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001235.tgz", - "integrity": "sha512-zWEwIVqnzPkSAXOUlQnPW2oKoYb2aLQ4Q5ejdjBcnH63rfypaW34CxaeBn1VMya2XaEU3P/R2qHpWyj+l0BT1A==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "node_modules/default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.3.749", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz", - "integrity": "sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12" }, "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", - "dev": true - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/husky": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", - "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", - "dev": true, - "bin": { - "husky": "lib/bin.js" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=" - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "dev": true, - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/make-fetch-happen": { - "version": "8.0.14", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", - "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", - "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.0.5", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^5.0.0", - "ssri": "^8.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-fetch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz", - "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", - "dependencies": { - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "optionalDependencies": { - "encoding": "^0.1.12" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-GRGG/q9bIaUkHJB9NL+KZNjDhMBHB30zW3bZW9qOiYr+QChyLjPzswaxFWkI1q6lGlSL28EQYzAi2vKWNkPx+g==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.23", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.4", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nanoid": { - "version": "3.1.23", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", - "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" - }, - "node_modules/node-gyp": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.1.0.tgz", - "integrity": "sha512-o2elh1qt7YUp3lkMwY3/l4KF3j/A3fI/Qt4NH+CQQgPJdqGE9y7qnP84cjIWN27Q0jJkrSAhCVDg+wBVNBYdBg==", - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^8.0.14", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.0", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", - "dev": true - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", - "dev": true, - "dependencies": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" - } - }, - "node_modules/should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", - "dev": true, - "dependencies": { - "should-type": "^1.4.0" - } - }, - "node_modules/should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", - "dev": true, - "dependencies": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "node_modules/should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", - "dev": true - }, - "node_modules/should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "dev": true, - "dependencies": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "node_modules/should-util": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", - "dev": true - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", - "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", - "dependencies": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz", - "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==", - "dependencies": { - "agent-base": "6", - "debug": "4", - "socks": "^2.3.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/table": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.9.tgz", - "integrity": "sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.0.2.tgz", - "integrity": "sha512-V0HGxJd0PiDF0ecHYIesTOqfd1gJguwQUOYfMfAWnRsWQEXfc5ifbUFhD3Wjc+O+y7VAqL+g07prq9gHQ/JOZQ==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/table/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-mocha": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-8.0.0.tgz", - "integrity": "sha512-Kou1yxTlubLnD5C3unlCVO7nh0HERTezjoVhVw/M5S1SqoUec0WgllQvPk3vzPMc6by8m6xD1uR1yRf8lnVUbA==", - "dev": true, - "dependencies": { - "ts-node": "7.0.1" - }, - "bin": { - "ts-mocha": "bin/ts-mocha" - }, - "engines": { - "node": ">= 6.X.X" - }, - "optionalDependencies": { - "tsconfig-paths": "^3.5.0" - } - }, - "node_modules/ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "dependencies": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/ts-node/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dev": true, - "optional": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "optional": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", - "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.4.tgz", - "integrity": "sha512-jGWPzsUqzkow8HoAvqaPWTUPCrlPJaJ5tY8Iz7n1uCz3tTp6s3CDG0FF1NsX42WNlkRSW6Mr+CDZGnNoSsKa7g==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/compat-data": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz", - "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==", - "dev": true - }, - "@babel/core": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz", - "integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.10", - "@babel/parser": "^7.13.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", - "dev": true, - "requires": { - "@babel/types": "^7.13.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", - "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.13.12", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "dev": true, - "requires": { - "@babel/types": "^7.12.13" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "dev": true, - "requires": { - "@babel/types": "^7.13.12" + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "requires": { - "@babel/types": "^7.13.12" + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "requires": { - "@babel/types": "^7.12.13" + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "requires": { - "@babel/types": "^7.13.12" + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "requires": { - "@babel/types": "^7.12.13" + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", - "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "engines": { + "node": ">=8" } }, - "@babel/parser": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", - "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", - "dev": true - }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.12.13" - } - } + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" } }, - "@babel/traverse": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz", - "integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.13", - "@babel/types": "^7.13.13", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.12.13" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "@babel/types": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", - "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" + "engines": { + "node": ">=6.0.0" } }, - "@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "engines": { + "node": ">=6.0.0" } }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, - "@nodelib/fs.scandir": { + "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "requires": { + "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "@nodelib/fs.stat": { + "node_modules/@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", - "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true, - "optional": true - }, - "@types/mocha": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", - "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", - "dev": true - }, - "@types/node": { - "version": "15.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz", - "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz", - "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "4.26.1", - "@typescript-eslint/scope-manager": "4.26.1", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.21", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz", - "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.26.1", - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/typescript-estree": "4.26.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - } + "engines": { + "node": ">= 8" } }, - "@typescript-eslint/parser": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz", - "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.26.1", - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/typescript-estree": "4.26.1", - "debug": "^4.3.1" + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "@typescript-eslint/scope-manager": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz", - "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1" + "node_modules/@npmcli/fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "@typescript-eslint/types": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", - "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", - "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" } }, - "@typescript-eslint/visitor-keys": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", - "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.26.1", - "eslint-visitor-keys": "^2.0.0" + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" } }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "abbrev": { + "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true + "node_modules/acorn": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", + "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "requires": {} + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "agent-base": { + "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { + "dependencies": { "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" } }, - "agentkeepalive": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.4.tgz", - "integrity": "sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==", - "requires": { + "node_modules/agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", + "dependencies": { "debug": "^4.1.0", - "depd": "^1.1.2", + "depd": "^2.0.0", "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" } }, - "aggregate-error": { + "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { + "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "ajv": { + "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "requires": { + "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { + "dependencies": { "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "requires": { + "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "append-transform": { + "node_modules/append-transform": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", "dev": true, - "requires": { + "dependencies": { "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" }, - "archy": { + "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dependencies": { "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "binary-extensions": { + "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "requires": { - "fill-range": "^7.0.1" + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, - "browser-stdout": { + "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "node_modules/browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "cacache": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", - "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", - "requires": { - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", + "node_modules/cacache": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", + "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", + "minipass-pipeline": "^1.2.4", "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "dependencies": { - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - } + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.2.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.7.tgz", + "integrity": "sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2", + "path-scurry": "^1.7.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "caching-transform": { + "node_modules/caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", "dev": true, - "requires": { + "dependencies": { "hasha": "^5.0.0", "make-dir": "^3.0.0", "package-hash": "^4.0.0", "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "call-bind": { + "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "callsites": { + "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "camelcase": { + "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "caniuse-lite": { - "version": "1.0.30001235", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001235.tgz", - "integrity": "sha512-zWEwIVqnzPkSAXOUlQnPW2oKoYb2aLQ4Q5ejdjBcnH63rfypaW34CxaeBn1VMya2XaEU3P/R2qHpWyj+l0BT1A==", - "dev": true + "node_modules/caniuse-lite": { + "version": "1.0.30001503", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz", + "integrity": "sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, - "requires": { - "anymatch": "~3.1.1", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "chownr": { + "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } }, - "clean-stack": { + "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } }, - "cliui": { + "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "requires": { + "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "color-convert": { + "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { + "dependencies": { "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "console-control-strings": { + "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, - "requires": { - "safe-buffer": "~5.1.1" + "engines": { + "node": ">= 0.6" } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "decamelize": { + "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", "dev": true, - "requires": { + "dependencies": { "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "delegates": { + "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, - "requires": { - "path-type": "^4.0.0" + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" } }, - "doctrine": { + "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "requires": { + "dependencies": { "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "electron-to-chromium": { - "version": "1.3.749", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz", - "integrity": "sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.432", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.432.tgz", + "integrity": "sha512-yz3U/khQgAFT2HURJA3/F4fKIyO2r5eK09BQzBZFd6BvBSSaRuzKc2ZNBHtJcO75/EKiRYbVYJZ2RB0P4BuD2g==", "dev": true }, - "emoji-regex": { + "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "encoding": { + "node_modules/encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "optional": true, - "requires": { + "dependencies": { "iconv-lite": "^0.6.2" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "env-paths": { + "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } }, - "err-code": { + "node_modules/err-code": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" }, - "es6-error": { + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, - "escalade": { + "node_modules/esbuild": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz", + "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.3", + "@esbuild/android-arm": "0.25.3", + "@esbuild/android-arm64": "0.25.3", + "@esbuild/android-x64": "0.25.3", + "@esbuild/darwin-arm64": "0.25.3", + "@esbuild/darwin-x64": "0.25.3", + "@esbuild/freebsd-arm64": "0.25.3", + "@esbuild/freebsd-x64": "0.25.3", + "@esbuild/linux-arm": "0.25.3", + "@esbuild/linux-arm64": "0.25.3", + "@esbuild/linux-ia32": "0.25.3", + "@esbuild/linux-loong64": "0.25.3", + "@esbuild/linux-mips64el": "0.25.3", + "@esbuild/linux-ppc64": "0.25.3", + "@esbuild/linux-riscv64": "0.25.3", + "@esbuild/linux-s390x": "0.25.3", + "@esbuild/linux-x64": "0.25.3", + "@esbuild/netbsd-arm64": "0.25.3", + "@esbuild/netbsd-x64": "0.25.3", + "@esbuild/openbsd-arm64": "0.25.3", + "@esbuild/openbsd-x64": "0.25.3", + "@esbuild/sunos-x64": "0.25.3", + "@esbuild/win32-arm64": "0.25.3", + "@esbuild/win32-ia32": "0.25.3", + "@esbuild/win32-x64": "0.25.3" + } + }, + "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.42.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", + "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.42.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "node_modules/eslint-config-prettier": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", "dev": true, - "requires": {} + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } }, - "eslint-plugin-prettier": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", - "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "node_modules/eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", "dev": true, - "requires": { + "dependencies": { "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } } }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/eslint-scope": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, - "requires": { + "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "funding": { + "url": "https://opencollective.com/eslint" } }, - "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/espree": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "esprima": { + "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "requires": { + "dependencies": { "estraverse": "^5.1.0" }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "engines": { + "node": ">=0.10" } }, - "esrecurse": { + "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "requires": { + "dependencies": { "estraverse": "^5.2.0" }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "engines": { + "node": ">=4.0" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } }, - "esutils": { + "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==" }, - "fast-deep-equal": { + "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, - "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "fast-json-stable-stringify": { + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "fast-levenshtein": { + "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, - "requires": { + "dependencies": { "reusify": "^1.0.4" } }, - "file-entry-cache": { + "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "requires": { + "dependencies": { "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "requires": { + "dependencies": { "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, - "requires": { + "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "find-up": { + "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "requires": { + "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "flat": { + "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true + "dev": true, + "bin": { + "flat": "cli.js" + } }, - "flat-cache": { + "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, - "requires": { + "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "foreground-child": { + "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", "dev": true, - "requires": { + "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" } }, - "fromentries": { + "node_modules/fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" + "node_modules/fs-minipass": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.2.tgz", + "integrity": "sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g==", + "dependencies": { + "minipass": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "fsevents": { + "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "gensync": { + "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, - "get-caller-file": { + "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "get-package-type": { + "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "requires": { - "is-glob": "^4.0.1" + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" } }, - "globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, - "requires": { + "dependencies": { "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" + "engines": { + "node": ">= 0.4" }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { + "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "has-unicode": { + "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, - "hasha": { + "node_modules/hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, - "requires": { + "dependencies": { "is-stream": "^2.0.0", "type-fest": "^0.8.0" }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "he": { + "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true + "dev": true, + "bin": { + "he": "bin/he" + } }, - "html-escaper": { + "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "requires": { - "@tootallnate/once": "1", + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" + }, + "engines": { + "node": ">= 6" } }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { "agent-base": "6", "debug": "4" + }, + "engines": { + "node": ">= 6" } }, - "humanize-ms": { + "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "requires": { + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { "ms": "^2.0.0" } }, - "husky": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", - "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", - "dev": true + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } }, - "import-fresh": { + "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "requires": { + "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } }, - "indent-string": { + "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" }, - "is-binary-path": { + "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "requires": { + "dependencies": { "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-extglob": { + "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" } }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "requires": { + "dependencies": { "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-lambda": { + "node_modules/is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=" + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" }, - "is-number": { + "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.12.0" + } }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "dev": true + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-plain-obj": { + "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-typedarray": { + "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, - "is-unicode-supported": { + "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-windows": { + "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "istanbul-lib-hook": { + "node_modules/istanbul-lib-hook": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", "dev": true, - "requires": { + "dependencies": { "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "istanbul-lib-instrument": { + "node_modules/istanbul-lib-instrument": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, - "requires": { + "dependencies": { "@babel/core": "^7.7.5", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.0.0", "semver": "^6.3.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "engines": { + "node": ">=8" } }, - "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, - "requires": { + "dependencies": { "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", "p-map": "^3.0.0", "rimraf": "^3.0.0", - "uuid": "^3.3.3" + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "istanbul-lib-report": { + "node_modules/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, - "requires": { + "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" } }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, - "requires": { + "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "engines": { + "node": ">=10" } }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, - "requires": { + "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", + "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "jsesc": { + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } }, - "json-schema-traverse": { + "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "json-stable-stringify-without-jsonify": { + "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "requires": { - "minimist": "^1.2.5" + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "levn": { + "node_modules/lambda-runtime": { + "resolved": "src", + "link": true + }, + "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "requires": { + "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "locate-path": { + "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "requires": { + "dependencies": { "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.flattendeep": { + "node_modules/lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", "dev": true }, - "lodash.merge": { + "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "log-symbols": { + "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "requires": { + "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" } }, - "make-dir": { + "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "requires": { + "dependencies": { "semver": "^6.0.0" }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } }, - "make-fetch-happen": { - "version": "8.0.14", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz", - "integrity": "sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==", - "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.0.5", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", + "node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", "promise-retry": "^2.0.1", - "socks-proxy-agent": "^5.0.0", - "ssri": "^8.0.0" + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "engines": { + "node": ">= 0.6" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "requires": { - "yallist": "^4.0.0" + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" } }, - "minipass-collect": { + "node_modules/minipass-collect": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "requires": { + "dependencies": { "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" } }, - "minipass-fetch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz", - "integrity": "sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==", - "requires": { - "encoding": "^0.1.12", - "minipass": "^3.1.0", + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz", + "integrity": "sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==", + "dependencies": { + "minipass": "^5.0.0", "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "minipass-flush": { + "node_modules/minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "requires": { + "dependencies": { "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "minipass-pipeline": { + "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "requires": { + "dependencies": { "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "minipass-sized": { + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "requires": { + "dependencies": { "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "minizlib": { + "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { + "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mock-http-server": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/mock-http-server/-/mock-http-server-1.4.5.tgz", + "integrity": "sha512-7WZx7RJmMQEvTxJTOJt9U6+gLFl0JFaPHLSsAngfLaOgr3UH+ci7PW8049quyXwZGI4mh3W8oAch6w406ccyRQ==", + "dev": true, + "dependencies": { + "body-parser": "^1.18.1", + "connect": "^3.4.0", + "multiparty": "^4.1.2", + "underscore": "^1.8.3" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multiparty": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-4.2.3.tgz", + "integrity": "sha512-Ak6EUJZuhGS8hJ3c2fY6UW5MbkGUPMBEGd13djUzoY/BHqV/gTuFWtC6IuVA7A2+v3yjBS6c4or50xhzTQZImQ==", + "dev": true, + "dependencies": { + "http-errors": "~1.8.1", + "safe-buffer": "5.2.1", + "uid-safe": "2.1.5" + }, + "engines": { + "node": ">= 0.10" } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-GRGG/q9bIaUkHJB9NL+KZNjDhMBHB30zW3bZW9qOiYr+QChyLjPzswaxFWkI1q6lGlSL28EQYzAi2vKWNkPx+g==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.1", - "debug": "4.3.1", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.23", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.1.4", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "node_modules/multiparty/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nanoid": { - "version": "3.1.23", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", - "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", - "dev": true + "node_modules/multiparty/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } }, - "natural-compare": { + "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } }, - "node-gyp": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.1.0.tgz", - "integrity": "sha512-o2elh1qt7YUp3lkMwY3/l4KF3j/A3fI/Qt4NH+CQQgPJdqGE9y7qnP84cjIWN27Q0jJkrSAhCVDg+wBVNBYdBg==", - "requires": { + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, + "node_modules/node-gyp": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz", + "integrity": "sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==", + "dependencies": { "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", "glob": "^7.1.4", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^8.0.14", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", - "tar": "^6.1.0", + "tar": "^6.1.2", "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" } }, - "node-preload": { + "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", "dev": true, - "requires": { + "dependencies": { "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "node_modules/node-releases": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", + "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", "dev": true }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "requires": { - "abbrev": "1" + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "normalize-path": { + "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "nyc": { + "node_modules/nyc": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", "dev": true, - "requires": { + "dependencies": { "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", "caching-transform": "^4.0.0", @@ -6837,504 +3831,770 @@ "test-exclude": "^6.0.0", "yargs": "^15.0.2" }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, "dependencies": { - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { "wrappy": "1" } }, - "optionator": { + "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "requires": { + "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" } }, - "p-limit": { + "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "requires": { + "dependencies": { "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { + "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "requires": { + "dependencies": { "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-try": { + "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "package-hash": { + "node_modules/package-hash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.15", "hasha": "^5.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "parent-module": { + "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "requires": { + "dependencies": { "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" } }, - "path-exists": { + "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "engines": { + "node": ">=8" + } }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "node_modules/path-scurry": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", + "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", + "dependencies": { + "lru-cache": "^9.1.1", + "minipass": "^5.0.0 || ^6.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", + "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "pkg-dir": { + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "requires": { + "dependencies": { "find-up": "^4.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "prelude-ls": { + "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "prettier": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", - "dev": true + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } }, - "prettier-linter-helpers": { + "node_modules/prettier-linter-helpers": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, - "requires": { + "dependencies": { "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "process-on-spawn": { + "node_modules/process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", "dev": true, - "requires": { + "dependencies": { "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" } }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "promise-retry": { + "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "requires": { + "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" } }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "queue-microtask": { + "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "randombytes": { + "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "safe-buffer": "^5.1.0" } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "requires": { + "dependencies": { "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, - "release-zalgo": { + "node_modules/release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, - "requires": { + "dependencies": { "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" } }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "require-main-filename": { + "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "resolve-from": { + "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "retry": { + "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "engines": { + "node": ">= 4" + } }, - "reusify": { + "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, - "rimraf": { + "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "run-parallel": { + "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "requires": { + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { "queue-microtask": "^1.2.2" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "safer-buffer": { + "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true + "devOptional": true }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { + "node_modules/semver": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "dependencies": { "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, - "requires": { + "license": "BSD-3-Clause", + "dependencies": { "randombytes": "^2.1.0" } }, - "set-blocking": { + "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true }, - "shebang-command": { + "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { + "dependencies": { "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "engines": { + "node": ">=8" + } }, - "should": { + "node_modules/should": { "version": "13.2.3", "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", "dev": true, - "requires": { + "dependencies": { "should-equal": "^2.0.0", "should-format": "^3.0.3", "should-type": "^1.4.0", @@ -7342,575 +4602,690 @@ "should-util": "^1.0.0" } }, - "should-equal": { + "node_modules/should-equal": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", "dev": true, - "requires": { + "dependencies": { "should-type": "^1.4.0" } }, - "should-format": { + "node_modules/should-format": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", "dev": true, - "requires": { + "dependencies": { "should-type": "^1.3.0", "should-type-adaptors": "^1.0.1" } }, - "should-type": { + "node_modules/should-type": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", "dev": true }, - "should-type-adaptors": { + "node_modules/should-type-adaptors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", "dev": true, - "requires": { + "dependencies": { "should-type": "^1.3.0", "should-util": "^1.0.0" } }, - "should-util": { + "node_modules/should-util": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", "dev": true }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - } + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "smart-buffer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", - "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==" + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, - "socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "socks-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz", - "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==", - "requires": { - "agent-base": "6", - "debug": "4", - "socks": "^2.3.3" + "node_modules/socks": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz", + "integrity": "sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw==", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "engines": { + "node": ">=0.10.0" } }, - "spawn-wrap": { + "node_modules/spawn-wrap": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", "dev": true, - "requires": { + "dependencies": { "foreground-child": "^2.0.0", "is-windows": "^1.0.2", "make-dir": "^3.0.0", "rimraf": "^3.0.0", "signal-exit": "^3.0.2", "which": "^2.0.1" + }, + "engines": { + "node": ">=8" } }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "requires": { - "minipass": "^3.1.1" + "node_modules/ssri": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", + "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", + "dependencies": { + "minipass": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" } }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } + "node_modules/stream-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", + "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", + "dev": true, + "dependencies": { + "debug": "2" } }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "node_modules/stream-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "requires": { - "ansi-regex": "^5.0.0" + "dependencies": { + "ms": "2.0.0" } }, - "strip-bom": { + "node_modules/stream-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { - "has-flag": "^4.0.0" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "table": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.9.tgz", - "integrity": "sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "ajv": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.0.2.tgz", - "integrity": "sha512-V0HGxJd0PiDF0ecHYIesTOqfd1gJguwQUOYfMfAWnRsWQEXfc5ifbUFhD3Wjc+O+y7VAqL+g07prq9gHQ/JOZQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "requires": { + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "test-exclude": { + "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "requires": { + "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" } }, - "text-table": { + "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "node_modules/throttle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/throttle/-/throttle-1.0.3.tgz", + "integrity": "sha512-VYINSQFQeFdmhCds0tTqvQmLmdAjzGX1D6GnRQa4zlq8OpTtWSMddNyRq8Z4Snw/d6QZrWt9cM/cH8xTiGUkYA==", + "dev": true, + "dependencies": { + "readable-stream": ">= 0.3.0", + "stream-parser": ">= 0.0.2" + }, + "engines": { + "node": ">= v0.8.0" + } }, - "to-regex-range": { + "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "ts-mocha": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-8.0.0.tgz", - "integrity": "sha512-Kou1yxTlubLnD5C3unlCVO7nh0HERTezjoVhVw/M5S1SqoUec0WgllQvPk3vzPMc6by8m6xD1uR1yRf8lnVUbA==", - "dev": true, - "requires": { - "ts-node": "7.0.1", - "tsconfig-paths": "^3.5.0" - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dev": true, - "optional": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "optional": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, - "requires": { - "tslib": "^1.8.1" + "engines": { + "node": ">=0.6" } }, - "type-check": { + "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { + "dependencies": { "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-fest": { + "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } }, - "typedarray-to-buffer": { + "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, - "requires": { + "dependencies": { "is-typedarray": "^1.0.0" } }, - "typescript": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", - "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dev": true, + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "requires": { + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dependencies": { "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "requires": { + "dependencies": { "punycode": "^2.1.0" } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "workerpool": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.4.tgz", - "integrity": "sha512-jGWPzsUqzkow8HoAvqaPWTUPCrlPJaJ5tY8Iz7n1uCz3tTp6s3CDG0FF1NsX42WNlkRSW6Mr+CDZGnNoSsKa7g==", - "dev": true + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "write-file-atomic": { + "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, - "requires": { + "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, - "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "yallist": { + "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "yargs": { + "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "requires": { + "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", @@ -7919,68 +5294,72 @@ "y18n": "^5.0.5", "yargs-parser": "^20.2.2" }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - } + "engines": { + "node": ">=10" } }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "yargs-unparser": { + "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } + "engines": { + "node": ">=10" } }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "src": { "dev": true } } diff --git a/package.json b/package.json index 8ce6336f..dbf0360a 100644 --- a/package.json +++ b/package.json @@ -1,37 +1,36 @@ { "name": "aws-lambda-ric", - "version": "1.1.0", + "version": "3.3.0", "description": "AWS Lambda Runtime Interface Client for NodeJs", "homepage": "https://github.com/aws/aws-lambda-nodejs-runtime-interface-client", - "main": "lib/index.js", + "main": "dist/index.mjs", "gypfile": true, "scripts": { "archive": "npx rimraf aws-lambda-ric-*.tgz && npm install && npm run build && npm pack", - "clean": "npx rimraf {build, node_modules} && npx rimraf deps/{build_complete.txt, aws-lambda-cpp, curl}", - "copy-files": "mkdir -p lib/RuntimeClient && cp src/RuntimeClient/runtime-client.cc lib/RuntimeClient/runtime-client.cc", + "clean": "npx rimraf build node_modules package-lock.json", + "copy-files": "mkdir -p dist && cp src/types/* dist/", "update-deps": "./scripts/update_dependencies.sh", "preinstall": "./scripts/preinstall.sh", "postinstall": "./scripts/postinstall.sh", - "build": "npx rimraf lib && tsc -b src", - "build:gyp": "node-gyp rebuild", "postbuild": "npm run copy-files", + "build": "cd src && node build.js && cd ..", + "build:gyp": "node-gyp rebuild", "format": "npm run format:src && npm run format:test", - "format:src": "prettier --check \"src/**/*.ts\" --write", - "format:test": "prettier --check \"test/**/*.ts\" --write", - "lint": "eslint --ext \".ts,.js\" src", + "format:src": "prettier --check \"src/*.*js\" --write", + "format:test": "prettier --check \"test/**/*.*js\" --write", + "lint": "eslint --ext \".js\" src test", + "fix": "eslint --fix --ext \".js\" src test", "test": "npm run test:unit", - "test:unit": "ts-mocha test/unit/**/*.test.ts --reporter ./test/utils/StdoutReporter -p ./test/unit/tsconfig.json", - "test:unit:watch": "ts-mocha test/unit/**/*.test.ts --reporter ./test/utils/StdoutReporter --watch-extensions ts --watch --watch-files src, test/unit/**/*.ts -p ./test/unit/tsconfig.json", + "test:unit": "mocha --recursive ./test/unit --reporter ./test/util/StdoutReporter.test", "test:coverage": "nyc npm run test:unit", - "tsc": "tsc -b src", - "tsc:watch": "tsc -b src --watch", "refresh": "rm -rf ./node_modules ./package-lock.json && npm install", - "precommit": "npm run lint" + "precommit": "npm run lint && npm run format:test", + "prepush": "npm run lint && npm run test" }, "author": "AWS Lambda", "license": "Apache-2.0", "bin": { - "aws-lambda-ric": "bin/index.js" + "aws-lambda-ric": "bin/index.mjs" }, "husky": { "hooks": { @@ -39,8 +38,11 @@ } }, "nyc": { - "extension": [ - ".ts" + "include": [ + "src/*.*js" + ], + "exclude": [ + "src/VerboseLog.js" ], "reporter": [ "text", @@ -53,23 +55,27 @@ "statements": 75 }, "dependencies": { - "node-addon-api": "3.2.1", - "node-gyp": "8.1.0" + "node-addon-api": "6.1.0", + "node-gyp": "9.4.0" }, "devDependencies": { - "@types/mocha": "8.2.2", - "@types/node": "^15.12.2", - "@typescript-eslint/eslint-plugin": "4.26.1", - "@typescript-eslint/parser": "4.26.1", - "eslint": "7.28.0", - "eslint-config-prettier": "8.3.0", - "eslint-plugin-prettier": "3.4.0", - "husky": "6.0.0", - "mocha": "9.0.0", + "esbuild": "^0.25.3", + "eslint": "8.42.0", + "eslint-config-prettier": "8.8.0", + "eslint-plugin-prettier": "4.2.1", + "husky": "^8.0.3", + "lambda-runtime": "file:./src/", + "mocha": "^10.8.2", + "mock-http-server": "^1.4.5", "nyc": "^15.1.0", - "prettier": "2.3.1", + "prettier": "2.8.8", "should": "13.2.3", - "ts-mocha": "8.0.0", - "typescript": "4.3.2" + "throttle": "^1.0.3" + }, + "prettier": { + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true } } diff --git a/scripts/postinstall.sh b/scripts/postinstall.sh index 6c4c9b4b..98788eac 100755 --- a/scripts/postinstall.sh +++ b/scripts/postinstall.sh @@ -6,6 +6,8 @@ if [ "$(uname)" = "Darwin" ]; then echo "aws-lambda-cpp does not build on OS X. Skipping the postinstall step." else npm run build:gyp + mkdir -p dist + cp build/Release/rapid-client.node dist/ fi # If the path of this file ends in "node_modules/aws-lambda-ric/scripts" @@ -18,9 +20,11 @@ if test "${current_path#*$node_modules_path}" != "$current_path" || [ "$BUILD" ! echo "Cleaning up source dependencies to save space" deps_path="$current_path/../deps" + build_path="$current_path/../build" # Clean up source dependencies - rm -rf "$deps_path"/patches - rm -rf "$deps_path"/aws-lambda-cpp*[^gz]$ - rm -rf "$deps_path"/curl*[^gz]$ + rm -rf "$deps_path"/aws-lambda-cpp*[^gz] + rm -rf "$deps_path"/curl*[^gz] + rm -rf "$deps_path"/artifacts + rm -rf "$build_path" fi diff --git a/scripts/preinstall.sh b/scripts/preinstall.sh index ff5d6411..dabc794d 100755 --- a/scripts/preinstall.sh +++ b/scripts/preinstall.sh @@ -20,18 +20,68 @@ else . ./versions # unpack dependencies - tar xzf ./curl-$CURL_VERSION.tar.gz && \ - tar xzf ./aws-lambda-cpp-$AWS_LAMBDA_CPP_RELEASE.tar.gz + tar xzf ./curl-$CURL_VERSION.tar.gz --no-same-owner && \ + tar xzf ./aws-lambda-cpp-$AWS_LAMBDA_CPP_RELEASE.tar.gz --no-same-owner ( # Build Curl - cd curl-$CURL_VERSION && \ + cd curl-curl-$CURL_VERSION && \ ./buildconf && \ ./configure \ --prefix "$ARTIFACTS_DIR" \ + --disable-alt-svc \ + --disable-ares \ + --disable-cookies \ + --disable-crypto-auth \ + --disable-dateparse \ + --disable-dict \ + --disable-dnsshuffle \ + --disable-doh \ + --disable-file \ + --disable-ftp \ + --disable-get-easy-options \ + --disable-gopher \ + --disable-hsts \ + --disable-http-auth \ + --disable-imap \ + --disable-ipv6 \ + --disable-ldap \ + --disable-ldaps \ + --disable-libcurl-option \ + --disable-manual \ + --disable-mime \ + --disable-mqtt \ + --disable-netrc \ + --disable-ntlm-wb \ + --disable-pop3 \ + --disable-progress-meter \ + --disable-proxy \ + --disable-pthreads \ + --disable-rtsp \ --disable-shared \ + --disable-smtp \ + --disable-socketpair \ + --disable-sspi \ + --disable-telnet \ + --disable-tftp \ + --disable-threaded-resolver \ + --disable-unix-sockets \ + --disable-verbose \ + --disable-versioned-symbols \ + --with-pic \ + --without-brotli \ + --without-ca-bundle \ + --without-gssapi \ + --without-libidn2 \ + --without-libpsl \ + --without-librtmp \ + --without-libssh2 \ + --without-nghttp2 \ + --without-nghttp3 \ + --without-ngtcp2 \ --without-ssl \ - --without-zlib && \ + --without-zlib \ + --without-zstd && \ make && \ make install ) diff --git a/scripts/update_dependencies.sh b/scripts/update_dependencies.sh index 3c087af5..4f48182d 100755 --- a/scripts/update_dependencies.sh +++ b/scripts/update_dependencies.sh @@ -10,21 +10,29 @@ source versions rm -f aws-lambda-cpp-*.tar.gz && rm -f curl-*.tar.gz # Grab Curl -wget -c https://github.com/curl/curl/archive/curl-$CURL_VERSION.tar.gz +wget -c https://github.com/curl/curl/archive/refs/tags/curl-$CURL_VERSION.tar.gz -O - | tar -xz + +# Apply patches +( + cd curl-curl-$CURL_VERSION && \ + patch -p1 < ../patches/0001-curl-disable_wakeup.patch + patch -p1 < ../patches/libcurl-configure-template.patch +) + +# Pack again and remove the folder +tar -czvf curl-$CURL_VERSION.tar.gz curl-curl-$CURL_VERSION && \ + rm -rf curl-curl-$CURL_VERSION # Grab aws-lambda-cpp -wget -c https://github.com/awslabs/aws-lambda-cpp/archive/v$AWS_LAMBDA_CPP_RELEASE.tar.gz -O - | tar -xz +wget -c https://github.com/awslabs/aws-lambda-cpp/archive/refs/tags/v$AWS_LAMBDA_CPP_RELEASE.tar.gz -O - | tar -xz # Apply patches ( cd aws-lambda-cpp-$AWS_LAMBDA_CPP_RELEASE && \ patch -p1 < ../patches/aws-lambda-cpp-add-xray-response.patch && \ - patch -p1 < ../patches/aws-lambda-cpp-posting-init-errors.patch && \ - patch -p1 < ../patches/aws-lambda-cpp-make-the-runtime-client-user-agent-overrideable.patch && \ - patch -p1 < ../patches/aws-lambda-cpp-make-lto-optional.patch && \ - patch -p1 < ../patches/aws-lambda-cpp-add-content-type.patch + patch -p1 < ../patches/aws-lambda-cpp-add-tenant-id.patch ) # Pack again and remove the folder -tar -czvf aws-lambda-cpp-$AWS_LAMBDA_CPP_RELEASE.tar.gz aws-lambda-cpp-$AWS_LAMBDA_CPP_RELEASE && \ +tar -czvf aws-lambda-cpp-$AWS_LAMBDA_CPP_RELEASE.tar.gz aws-lambda-cpp-$AWS_LAMBDA_CPP_RELEASE --no-same-owner && \ rm -rf aws-lambda-cpp-$AWS_LAMBDA_CPP_RELEASE diff --git a/src/BeforeExitListener.js b/src/BeforeExitListener.js new file mode 100644 index 00000000..b553852c --- /dev/null +++ b/src/BeforeExitListener.js @@ -0,0 +1,33 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * The runtime has a single beforeExit function which is stored in the global + * object with a symbol key. + * The symbol is not exported. + * The process.beforeExit listener is setup in index.mjs along with all other + * top-level process event listeners. + */ + +'use strict'; + +// define a named symbol for the handler function +const LISTENER_SYMBOL = Symbol.for('aws.lambda.beforeExit'); +const NO_OP_LISTENER = () => {}; + +// export a setter +module.exports = { + /** + * Call the listener function with no arguments. + */ + invoke: () => global[LISTENER_SYMBOL](), + + /** + * Reset the listener to a no-op function. + */ + reset: () => (global[LISTENER_SYMBOL] = NO_OP_LISTENER), + + /** + * Set the listener to the provided function. + */ + set: (listener) => (global[LISTENER_SYMBOL] = listener), +}; diff --git a/src/CallbackContext.js b/src/CallbackContext.js new file mode 100644 index 00000000..2ee3cd3e --- /dev/null +++ b/src/CallbackContext.js @@ -0,0 +1,146 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +const BeforeExitListener = require('./BeforeExitListener.js'); +const { structuredConsole } = require('./LogPatch'); + +/** + * Build the callback function and the part of the context which exposes + * the succeed/fail/done callbacks. + * @param client {RuntimeClient} + * The RAPID client used to post results/errors. + * @param id {string} + * The invokeId for the current invocation. + * @param scheduleNext {function} + * A function which takes no params and immediately schedules the next + * iteration of the invoke loop. + */ +function _rawCallbackContext(client, id, scheduleNext) { + const postError = (err, callback) => { + structuredConsole.logError('Invoke Error', err); + client.postInvocationError(err, id, callback); + }; + + let isCompleteInvoked = false; + const complete = (result, callback) => { + if (isCompleteInvoked) { + console.error( + 'Invocation has already been reported as done. Cannot call complete more than once per invocation.', + ); + return; + } + isCompleteInvoked = true; + client.postInvocationResponse(result, id, callback); + }; + + let waitForEmptyEventLoop = true; + + const callback = function (err, result) { + BeforeExitListener.reset(); + if (err !== undefined && err !== null) { + postError(err, scheduleNext); + } else { + if (!waitForEmptyEventLoop) { + complete(result, scheduleNext); + } else { + BeforeExitListener.set(() => { + setImmediate(() => { + complete(result, scheduleNext); + }); + }); + } + } + }; + + const done = (err, result) => { + BeforeExitListener.reset(); + if (err !== undefined && err !== null) { + postError(err, scheduleNext); + } else { + complete(result, scheduleNext); + } + }; + const succeed = (result) => { + done(null, result); + }; + const fail = (err) => { + if (err === undefined || err === null) { + done('handled'); + } else { + done(err, null); + } + }; + + const callbackContext = { + get callbackWaitsForEmptyEventLoop() { + return waitForEmptyEventLoop; + }, + set callbackWaitsForEmptyEventLoop(value) { + waitForEmptyEventLoop = value; + }, + succeed: succeed, + fail: fail, + done: done, + }; + + return [ + callback, + callbackContext, + function () { + isCompleteInvoked = true; + }, + ]; +} + +/** + * Wraps the callback and context so that only the first call to any callback + * succeeds. + * @param callback {function} + * the node-style callback function that was previously generated but not + * yet wrapped. + * @param callbackContext {object} + * The previously generated callbackContext object that contains + * getter/setters for the contextWaitsForEmptyeventLoop flag and the + * succeed/fail/done functions. + * @return [callback, context] + */ +function _wrappedCallbackContext(callback, callbackContext, markCompleted) { + let finished = false; + const onlyAllowFirstCall = function (toWrap) { + return function () { + if (!finished) { + toWrap.apply(null, arguments); + finished = true; + } + }; + }; + + callbackContext.succeed = onlyAllowFirstCall(callbackContext.succeed); + callbackContext.fail = onlyAllowFirstCall(callbackContext.fail); + callbackContext.done = onlyAllowFirstCall(callbackContext.done); + + return [onlyAllowFirstCall(callback), callbackContext, markCompleted]; +} + +/** + * Construct the base-context object which includes the required flags and + * callback methods for the Node programming model. + * @param client {RAPIDClient} + * The RAPID client used to post results/errors. + * @param id {string} + * The invokeId for the current invocation. + * @param scheduleNext {function} + * A function which takes no params and immediately schedules the next + * iteration of the invoke loop. + * @return [callback, context] + * The same function and context object, but wrapped such that only the + * first call to any function will be successful. All subsequent calls are + * a no-op. + */ +module.exports.build = function (client, id, scheduleNext) { + let rawCallbackContext = _rawCallbackContext(client, id, scheduleNext); + return _wrappedCallbackContext(...rawCallbackContext); +}; diff --git a/src/Common/index.ts b/src/Common/index.ts deleted file mode 100644 index 0076330a..00000000 --- a/src/Common/index.ts +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * This module defines types, enums and interfaces common to the other modules. - */ - -import { IncomingHttpHeaders } from "http"; - -export interface InvocationResponse { - bodyJson: string; - headers: IncomingHttpHeaders; -} - -export interface NativeClient { - initializeClient: (userAgent: string) => void; - done: (id: string, bodyString: string) => void; - error: (id: string, bodyString: string, xrayString: string) => void; - next: () => Promise; -} - -export enum INVOKE_HEADER { - ClientContext = "lambda-runtime-client-context", - CognitoIdentity = "lambda-runtime-cognito-identity", - ARN = "lambda-runtime-invoked-function-arn", - AWSRequestId = "lambda-runtime-aws-request-id", - DeadlineMs = "lambda-runtime-deadline-ms", - XRayTrace = "lambda-runtime-trace-id", -} - -export interface IEnvironmentData { - functionVersion?: string; - functionName?: string; - memoryLimitInMB?: string; - logGroupName?: string; - logStreamName?: string; -} - -export interface IHeaderData { - clientContext?: string; - identity?: string; - invokedFunctionArn?: string; - awsRequestId?: string; - getRemainingTimeInMillis: () => number; -} - -export type ErrorStringOrUndefined = Error | string | undefined; - -export type ErrorStringOrUndefinedOrNull = ErrorStringOrUndefined | null; - -/** - * - */ -export interface ICallbackContext { - callbackWaitsForEmptyEventLoop: boolean; - succeed: (result: unknown) => void; - fail: (err: ErrorStringOrUndefinedOrNull) => void; - done: (err: ErrorStringOrUndefinedOrNull, result?: unknown) => void; -} - -export type CallbackFunction = ( - err: ErrorStringOrUndefinedOrNull, - result?: unknown -) => void; - -export interface IBeforeExitListener { - invoke: () => void; - reset: () => () => void; - set: (listener: () => void) => () => void; -} - -export interface IErrorCallbacks { - uncaughtException: (err: Error) => void; - unhandledRejection: (err: Error) => void; -} - -export type HandlerFunction = ( - body: unknown, - data: IEnvironmentData & IHeaderData, - callback: CallbackFunction -) => PromiseLike | unknown; diff --git a/src/Errors.js b/src/Errors.js new file mode 100644 index 00000000..c3028991 --- /dev/null +++ b/src/Errors.js @@ -0,0 +1,128 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Defines custom error types throwable by the runtime. + */ + +'use strict'; + +const util = require('util'); + +function _isError(obj) { + return ( + obj && + obj.name && + obj.message && + obj.stack && + typeof obj.name === 'string' && + typeof obj.message === 'string' && + typeof obj.stack === 'string' + ); +} + +function intoError(err) { + if (err instanceof Error) { + return err; + } else { + return new Error(err); + } +} + +module.exports.intoError = intoError; + +/** + * Attempt to convert an object into a response object. + * This method accounts for failures when serializing the error object. + */ +function toRapidResponse(error) { + try { + if (util.types.isNativeError(error) || _isError(error)) { + return { + errorType: error.name?.replaceAll('\x7F', '%7F'), + errorMessage: error.message?.replaceAll('\x7F', '%7F'), + trace: error.stack.replaceAll('\x7F', '%7F').split('\n'), + }; + } else { + return { + errorType: typeof error, + errorMessage: error.toString(), + trace: [], + }; + } + } catch (_err) { + return { + errorType: 'handled', + errorMessage: + 'callback called with Error argument, but there was a problem while retrieving one or more of its message, name, and stack', + }; + } +} + +module.exports.toRapidResponse = toRapidResponse; + +/** + * Format an error with the expected properties. + * For compatability, the error string always starts with a tab. + */ +module.exports.toFormatted = (error) => { + try { + return ( + '\t' + JSON.stringify(error, (_k, v) => _withEnumerableProperties(v)) + ); + } catch (err) { + return '\t' + JSON.stringify(toRapidResponse(error)); + } +}; + +/** + * Error name, message, code, and stack are all members of the superclass, which + * means they aren't enumerable and don't normally show up in JSON.stringify. + * This method ensures those interesting properties are available along with any + * user-provided enumerable properties. + */ +function _withEnumerableProperties(error) { + if (error instanceof Error) { + let ret = Object.assign( + { + errorType: error.name, + errorMessage: error.message, + code: error.code, + }, + error, + ); + if (typeof error.stack == 'string') { + ret.stack = error.stack.split('\n'); + } + return ret; + } else { + return error; + } +} + +const errorClasses = [ + class ImportModuleError extends Error {}, + class HandlerNotFound extends Error {}, + class MalformedHandlerName extends Error {}, + class UserCodeSyntaxError extends Error {}, + class MalformedStreamingHandler extends Error {}, + class InvalidStreamingOperation extends Error {}, + class NodeJsExit extends Error { + constructor() { + super( + 'The Lambda runtime client detected an unexpected Node.js exit code. This is most commonly caused by a Promise that was never settled. For more information, see https://nodejs.org/docs/latest/api/process.html#exit-codes', + ); + } + }, + class UnhandledPromiseRejection extends Error { + constructor(reason, promise) { + super(reason); + this.reason = reason; + this.promise = promise; + } + }, +]; + +errorClasses.forEach((e) => { + module.exports[e.name] = e; + e.prototype.name = `Runtime.${e.name}`; +}); diff --git a/src/Errors/XRayError.ts b/src/Errors/XRayError.ts deleted file mode 100644 index aa42762a..00000000 --- a/src/Errors/XRayError.ts +++ /dev/null @@ -1,115 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -import { isError } from "."; - -/** - * prepare an exception blob for sending to AWS X-Ray - * transform an Error, or Error-like, into an exception parseable by X-Ray's service. - * { - * "name": "CustomException", - * "message": "Something bad happend!", - * "stack": [ - * "exports.handler (/var/function/node_modules/event_invoke.js:3:502) - * ] - * } - * => - * { - * "working_directory": "/var/function", - * "exceptions": [ - * { - * "type": "CustomException", - * "message": "Something bad happend!", - * "stack": [ - * { - * "path": "/var/function/event_invoke.js", - * "line": 502, - * "label": "exports.throw_custom_exception" - * } - * ] - * } - * ], - * "paths": [ - * "/var/function/event_invoke.js" - * ] - * } - */ -export const toFormatted = (err: unknown): string => { - if (!isError(err)) { - return ""; - } - - try { - return JSON.stringify(new XRayFormattedCause(err)); - } catch (error) { - return ""; - } -}; - -interface XRayStackEntry { - path: string; - line: number; - label: string; -} - -interface XRayError { - type: string; - message: string; - stack: XRayStackEntry[]; -} - -class XRayFormattedCause { - working_directory: string; - exceptions: XRayError[]; - paths: string[]; - - constructor(err: Error) { - this.working_directory = process.cwd(); // eslint-disable-line - - const stack: XRayStackEntry[] = []; - if (err.stack) { - const stackLines = err.stack.split("\n"); - stackLines.shift(); - - stackLines.forEach((stackLine) => { - let line = stackLine.trim().replace(/\(|\)/g, ""); - line = line.substring(line.indexOf(" ") + 1); - - const label = - line.lastIndexOf(" ") >= 0 - ? line.slice(0, line.lastIndexOf(" ")) - : null; - - const path = - label == undefined || label == null || label.length === 0 - ? line - : line.slice(line.lastIndexOf(" ") + 1); - - const pathParts = path.split(":"); - - const entry = { - path: pathParts[0], - line: parseInt(pathParts[1]), - label: label || "anonymous", - }; - - stack.push(entry); - }); - } - - this.exceptions = [ - { - type: err.name, - message: err.message, - stack: stack, - }, - ]; - - const paths = new Set(); - stack.forEach((entry) => { - paths.add(entry.path); - }); - this.paths = Array.from(paths); - } -} diff --git a/src/Errors/index.ts b/src/Errors/index.ts deleted file mode 100644 index 8d47aeb8..00000000 --- a/src/Errors/index.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/** - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Defines custom error types throwable by the runtime. - */ - -"use strict"; - -import util from "util"; - -export function isError(obj: any): obj is Error { - return ( - obj && - obj.name && - obj.message && - obj.stack && - typeof obj.name === "string" && - typeof obj.message === "string" && - typeof obj.stack === "string" - ); -} - -interface RuntimeErrorResponse { - errorType: string; - errorMessage: string; - trace: string[]; -} - -/** - * Attempt to convert an object into a response object. - * This method accounts for failures when serializing the error object. - */ -export function toRuntimeResponse(error: unknown): RuntimeErrorResponse { - try { - if (util.types.isNativeError(error) || isError(error)) { - if (!error.stack) { - throw new Error("Error stack is missing."); - } - return { - errorType: error.name, - errorMessage: error.message, - trace: error.stack.split("\n") || [], - }; - } else { - return { - errorType: typeof error, - errorMessage: (error as any).toString(), - trace: [], - }; - } - } catch (_err) { - return { - errorType: "handled", - errorMessage: - "callback called with Error argument, but there was a problem while retrieving one or more of its message, name, and stack", - trace: [], - }; - } -} - -/** - * Format an error with the expected properties. - * For compatability, the error string always starts with a tab. - */ -export const toFormatted = (error: unknown): string => { - try { - return ( - "\t" + JSON.stringify(error, (_k, v) => _withEnumerableProperties(v)) - ); - } catch (err) { - return "\t" + JSON.stringify(toRuntimeResponse(error)); - } -}; - -/** - * Error name, message, code, and stack are all members of the superclass, which - * means they aren't enumerable and don't normally show up in JSON.stringify. - * This method ensures those interesting properties are available along with any - * user-provided enumerable properties. - */ -function _withEnumerableProperties(error: any) { - if (error instanceof Error) { - const extendedError: ExtendedError = (error); - const ret: any = Object.assign( - { - errorType: extendedError.name, - errorMessage: extendedError.message, - code: extendedError.code, - }, - extendedError - ); - if (typeof extendedError.stack == "string") { - ret.stack = extendedError.stack.split("\n"); - } - return ret; - } else { - return error; - } -} - -export class ExtendedError extends Error { - code?: number; - custom?: string; - reason?: string; - promise?: Promise; - - constructor(reason?: string) { - super(reason); // 'Error' breaks prototype chain here - Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain - } -} - -export class ImportModuleError extends ExtendedError {} -export class HandlerNotFound extends ExtendedError {} -export class MalformedHandlerName extends ExtendedError {} -export class UserCodeSyntaxError extends ExtendedError {} -export class UnhandledPromiseRejection extends ExtendedError { - constructor(reason?: string, promise?: Promise) { - super(reason); - this.reason = reason; - this.promise = promise; - } -} - -const errorClasses = [ - ImportModuleError, - HandlerNotFound, - MalformedHandlerName, - UserCodeSyntaxError, - UnhandledPromiseRejection, -]; - -errorClasses.forEach((e) => { - e.prototype.name = `Runtime.${e.name}`; -}); diff --git a/src/HttpResponseStream.js b/src/HttpResponseStream.js new file mode 100644 index 00000000..b31e04ee --- /dev/null +++ b/src/HttpResponseStream.js @@ -0,0 +1,33 @@ +/** + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * HttpResponseStream is NOT used by the runtime. + * It is only exposed in the `awslambda` variable for customers to use. + */ + +'use strict'; + +const METADATA_PRELUDE_CONTENT_TYPE = + 'application/vnd.awslambda.http-integration-response'; +const DELIMITER_LEN = 8; + +// Implements the application/vnd.awslambda.http-integration-response content type. +class HttpResponseStream { + static from(underlyingStream, prelude) { + underlyingStream.setContentType(METADATA_PRELUDE_CONTENT_TYPE); + + // JSON.stringify is required. NULL byte is not allowed in metadataPrelude. + const metadataPrelude = JSON.stringify(prelude); + + underlyingStream._onBeforeFirstWrite = (write) => { + write(metadataPrelude); + + // Write 8 null bytes after the JSON prelude. + write(new Uint8Array(DELIMITER_LEN)); + }; + + return underlyingStream; + } +} + +module.exports.HttpResponseStream = HttpResponseStream; diff --git a/src/InvokeContext.js b/src/InvokeContext.js new file mode 100644 index 00000000..376c6359 --- /dev/null +++ b/src/InvokeContext.js @@ -0,0 +1,149 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * This module defines the InvokeContext and supporting functions. The + * InvokeContext is responsible for pulling information from the invoke headers + * and for wrapping the Rapid Client object's error and response functions. + */ + +'use strict'; + +const assert = require('assert').strict; +let { setCurrentRequestId, setCurrentTenantId } = require('./LogPatch'); + +const INVOKE_HEADER = { + ClientContext: 'lambda-runtime-client-context', + CognitoIdentity: 'lambda-runtime-cognito-identity', + ARN: 'lambda-runtime-invoked-function-arn', + AWSRequestId: 'lambda-runtime-aws-request-id', + DeadlineMs: 'lambda-runtime-deadline-ms', + XRayTrace: 'lambda-runtime-trace-id', + TenantId: 'lambda-runtime-aws-tenant-id', +}; + +module.exports = class InvokeContext { + constructor(headers) { + this.headers = _enforceLowercaseKeys(headers); + } + + /** + * The invokeId for this request. + */ + get invokeId() { + let id = this.headers[INVOKE_HEADER.AWSRequestId]; + assert.ok(id, 'invocation id is missing or invalid'); + return id; + } + + /** + * The tenantId for this request. + */ + get tenantId() { + return this.headers[INVOKE_HEADER.TenantId]; + } + + /** + * Push relevant invoke data into the logging context. + */ + updateLoggingContext() { + setCurrentRequestId(this.invokeId); + setCurrentTenantId(this.tenantId); + } + + /** + * Attach all of the relavant environmental and invocation data to the + * provided object. + * This method can throw if the headers are malformed and cannot be parsed. + * @param callbackContext {Object} + * The callbackContext object returned by a call to buildCallbackContext(). + * @return {Object} + * The user context object with all required data populated from the headers + * and environment variables. + */ + attachEnvironmentData(callbackContext) { + this._forwardXRay(); + return Object.assign( + callbackContext, + this._environmentalData(), + this._headerData(), + ); + } + + /** + * All parts of the user-facing context object which are provided through + * environment variables. + */ + _environmentalData() { + return { + functionVersion: process.env['AWS_LAMBDA_FUNCTION_VERSION'], + functionName: process.env['AWS_LAMBDA_FUNCTION_NAME'], + memoryLimitInMB: process.env['AWS_LAMBDA_FUNCTION_MEMORY_SIZE'], + logGroupName: process.env['AWS_LAMBDA_LOG_GROUP_NAME'], + logStreamName: process.env['AWS_LAMBDA_LOG_STREAM_NAME'], + }; + } + + /** + * All parts of the user-facing context object which are provided through + * request headers. + */ + _headerData() { + const deadline = this.headers[INVOKE_HEADER.DeadlineMs]; + return { + clientContext: _parseJson( + this.headers[INVOKE_HEADER.ClientContext], + 'ClientContext', + ), + identity: _parseJson( + this.headers[INVOKE_HEADER.CognitoIdentity], + 'CognitoIdentity', + ), + invokedFunctionArn: this.headers[INVOKE_HEADER.ARN], + awsRequestId: this.headers[INVOKE_HEADER.AWSRequestId], + tenantId: this.headers[INVOKE_HEADER.TenantId], + getRemainingTimeInMillis: function () { + return deadline - Date.now(); + }, + }; + } + + /** + * Forward the XRay header into the environment variable. + */ + _forwardXRay() { + if (this.headers[INVOKE_HEADER.XRayTrace]) { + process.env['_X_AMZN_TRACE_ID'] = this.headers[INVOKE_HEADER.XRayTrace]; + } else { + delete process.env['_X_AMZN_TRACE_ID']; + } + } +}; + +/** + * Parse a JSON string and throw a readable error if something fails. + * @param jsonString {string} - the string to attempt to parse + * @param name {name} - the name to use when describing the string in an error + * @return object - the parsed object + * @throws if jsonString cannot be parsed + */ +function _parseJson(jsonString, name) { + if (jsonString !== undefined) { + try { + return JSON.parse(jsonString); + } catch (err) { + throw new Error(`Cannot parse ${name} as json: ${err.toString()}`); + } + } else { + return undefined; + } +} + +/** + * Construct a copy of an object such that all of its keys are lowercase. + */ +function _enforceLowercaseKeys(original) { + return Object.keys(original).reduce((enforced, originalKey) => { + enforced[originalKey.toLowerCase()] = original[originalKey]; + return enforced; + }, {}); +} diff --git a/src/LogPatch.js b/src/LogPatch.js new file mode 100644 index 00000000..50757ab4 --- /dev/null +++ b/src/LogPatch.js @@ -0,0 +1,272 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +const util = require('util'); +const fs = require('fs'); +const Errors = require('./Errors'); + +const structuredConsole = {}; + +const jsonErrorReplacer = (_, value) => { + if (value instanceof Error) { + let serializedErr = Object.assign( + { + errorType: value?.constructor?.name ?? 'UnknownError', + errorMessage: value.message, + stackTrace: + typeof value.stack === 'string' + ? value.stack.split('\n') + : value.stack, + }, + value, + ); + return serializedErr; + } + return value; +}; + +function formatJsonMessage( + requestId, + timestamp, + level, + tenantId, + ...messageParams +) { + let result = { + timestamp: timestamp, + level: level.name, + requestId: requestId, + }; + + if (tenantId != undefined && tenantId != null) { + result.tenantId = tenantId; + } + + if (messageParams.length === 1) { + result.message = messageParams[0]; + try { + return JSON.stringify(result, jsonErrorReplacer); + } catch (_) { + result.message = util.format(result.message); + return JSON.stringify(result); + } + } + + result.message = util.format(...messageParams); + for (const param of messageParams) { + if (param instanceof Error) { + result.errorType = param?.constructor?.name ?? 'UnknownError'; + result.errorMessage = param.message; + result.stackTrace = + typeof param.stack === 'string' ? param.stack.split('\n') : []; + break; + } + } + return JSON.stringify(result); +} + +/* Use a unique symbol to provide global access without risk of name clashes. */ +const REQUEST_ID_SYMBOL = Symbol.for('aws.lambda.runtime.requestId'); +let _currentRequestId = { + get: () => global[REQUEST_ID_SYMBOL], + set: (id) => (global[REQUEST_ID_SYMBOL] = id), +}; + +/* Use a unique symbol to provide global access without risk of name clashes. */ +const TENANT_ID_SYMBOL = Symbol.for('aws.lambda.runtime.tenantId'); +let _currentTenantId = { + get: () => global[TENANT_ID_SYMBOL], + set: (id) => (global[TENANT_ID_SYMBOL] = id), +}; + +/** + * Write logs to stdout. + */ +let logTextToStdout = (level, message, ...params) => { + let time = new Date().toISOString(); + let requestId = _currentRequestId.get(); + let line = `${time}\t${requestId}\t${level.name}\t${util.format( + message, + ...params, + )}`; + line = line.replace(/\n/g, '\r'); + process.stdout.write(line + '\n'); +}; + +let logJsonToStdout = (level, message, ...params) => { + let time = new Date().toISOString(); + let requestId = _currentRequestId.get(); + let tenantId = _currentTenantId.get(); + let line = formatJsonMessage( + requestId, + time, + level, + tenantId, + message, + ...params, + ); + line = line.replace(/\n/g, '\r'); + process.stdout.write(line + '\n'); +}; + +/** + * Write logs to filedescriptor. + * Implements the logging contract between runtimes and the platform. + * Each entry is framed as: + * +----------------------+------------------------+---------------------+-----------------------+ + * | Frame Type - 4 bytes | Length (len) - 4 bytes | Timestamp - 8 bytes | Message - 'len' bytes | + * +----------------------+------------------------+---------------------+-----------------------+ + * The frist 4 bytes are the frame type. For logs this is always 0xa55a0003. + * The second 4 bytes are the length of the message. + * The next 8 bytes are the UNIX timestamp of the message with microseconds precision. + * The remaining bytes ar ethe message itself. Byte order is big-endian. + */ +let logTextToFd = function (logTarget) { + let typeAndLength = Buffer.alloc(16); + return (level, message, ...params) => { + let date = new Date(); + let time = date.toISOString(); + let requestId = _currentRequestId.get(); + let enrichedMessage = `${time}\t${requestId}\t${level.name}\t${util.format( + message, + ...params, + )}\n`; + + typeAndLength.writeUInt32BE((0xa55a0003 | level.tlvMask) >>> 0, 0); + let messageBytes = Buffer.from(enrichedMessage, 'utf8'); + typeAndLength.writeInt32BE(messageBytes.length, 4); + typeAndLength.writeBigInt64BE(BigInt(date.valueOf()) * 1000n, 8); + fs.writeSync(logTarget, typeAndLength); + fs.writeSync(logTarget, messageBytes); + }; +}; + +let logJsonToFd = function (logTarget) { + let typeAndLength = Buffer.alloc(16); + return (level, message, ...params) => { + let date = new Date(); + let time = date.toISOString(); + let requestId = _currentRequestId.get(); + let tenantId = _currentTenantId.get(); + let enrichedMessage = formatJsonMessage( + requestId, + time, + level, + tenantId, + message, + ...params, + ); + + typeAndLength.writeUInt32BE((0xa55a0002 | level.tlvMask) >>> 0, 0); + let messageBytes = Buffer.from(enrichedMessage, 'utf8'); + typeAndLength.writeInt32BE(messageBytes.length, 4); + typeAndLength.writeBigInt64BE(BigInt(date.valueOf()) * 1000n, 8); + fs.writeSync(logTarget, typeAndLength); + fs.writeSync(logTarget, messageBytes); + }; +}; + +/** + * Replace console functions with a log function. + * @param {Function(level, String)} log + * Apply log filters, based on `AWS_LAMBDA_LOG_LEVEL` env var + */ +function _patchConsoleWith(log) { + const NopLog = (_message, ..._params) => {}; + const levels = Object.freeze({ + TRACE: { name: 'TRACE', priority: 1, tlvMask: 0b00100 }, + DEBUG: { name: 'DEBUG', priority: 2, tlvMask: 0b01000 }, + INFO: { name: 'INFO', priority: 3, tlvMask: 0b01100 }, + WARN: { name: 'WARN', priority: 4, tlvMask: 0b10000 }, + ERROR: { name: 'ERROR', priority: 5, tlvMask: 0b10100 }, + FATAL: { name: 'FATAL', priority: 6, tlvMask: 0b11000 }, + }); + let awsLambdaLogLevel = + levels[process.env['AWS_LAMBDA_LOG_LEVEL']?.toUpperCase()] ?? levels.TRACE; + + if (levels.TRACE.priority >= awsLambdaLogLevel.priority) { + console.trace = (msg, ...params) => { + log(levels.TRACE, msg, ...params); + }; + } else { + console.trace = NopLog; + } + if (levels.DEBUG.priority >= awsLambdaLogLevel.priority) { + console.debug = (msg, ...params) => { + log(levels.DEBUG, msg, ...params); + }; + } else { + console.debug = NopLog; + } + if (levels.INFO.priority >= awsLambdaLogLevel.priority) { + console.info = (msg, ...params) => { + log(levels.INFO, msg, ...params); + }; + } else { + console.info = NopLog; + } + console.log = console.info; + if (levels.WARN.priority >= awsLambdaLogLevel.priority) { + console.warn = (msg, ...params) => { + log(levels.WARN, msg, ...params); + }; + } else { + console.warn = NopLog; + } + if (levels.ERROR.priority >= awsLambdaLogLevel.priority) { + console.error = (msg, ...params) => { + log(levels.ERROR, msg, ...params); + }; + } else { + console.error = NopLog; + } + console.fatal = (msg, ...params) => { + log(levels.FATAL, msg, ...params); + }; +} + +let _patchConsole = () => { + const JsonName = 'JSON', + TextName = 'TEXT'; + let awsLambdaLogFormat = + process.env['AWS_LAMBDA_LOG_FORMAT']?.toUpperCase() === JsonName + ? JsonName + : TextName; + let jsonErrorLogger = (_, err) => { + console.error(Errors.intoError(err)); + }, + textErrorLogger = (msg, err) => { + console.error(msg, Errors.toFormatted(Errors.intoError(err))); + }; + + /** + Resolve log format here, instead of inside log function. + This avoids conditional statements in the log function hot path. + **/ + let logger; + if ( + process.env['_LAMBDA_TELEMETRY_LOG_FD'] != null && + process.env['_LAMBDA_TELEMETRY_LOG_FD'] != undefined + ) { + let logFd = parseInt(process.env['_LAMBDA_TELEMETRY_LOG_FD']); + delete process.env['_LAMBDA_TELEMETRY_LOG_FD']; + logger = + awsLambdaLogFormat === JsonName ? logJsonToFd(logFd) : logTextToFd(logFd); + } else { + logger = + awsLambdaLogFormat === JsonName ? logJsonToStdout : logTextToStdout; + } + _patchConsoleWith(logger); + structuredConsole.logError = + awsLambdaLogFormat === JsonName ? jsonErrorLogger : textErrorLogger; +}; + +module.exports = { + setCurrentRequestId: _currentRequestId.set, + setCurrentTenantId: _currentTenantId.set, + patchConsole: _patchConsole, + structuredConsole: structuredConsole, +}; diff --git a/src/NativeModuleLoader.js b/src/NativeModuleLoader.js new file mode 100644 index 00000000..66776fe1 --- /dev/null +++ b/src/NativeModuleLoader.js @@ -0,0 +1,7 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +exports.load = () => require('./rapid-client.node'); diff --git a/src/RAPIDClient.js b/src/RAPIDClient.js new file mode 100644 index 00000000..cf027879 --- /dev/null +++ b/src/RAPIDClient.js @@ -0,0 +1,213 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * This module defines the RAPID client which is responsible for all HTTP + * interactions with the RAPID layer. + */ + +'use strict'; + +const Errors = require('./Errors'); +const XRayError = require('./XRayError'); +const ERROR_TYPE_HEADER = 'Lambda-Runtime-Function-Error-Type'; +const { createResponseStream } = require('./ResponseStream'); + +/** + * Objects of this class are responsible for all interactions with the RAPID + * API. + */ +module.exports = class RAPIDClient { + constructor(hostnamePort, httpClient, nativeClient) { + this.http = httpClient || require('http'); + this.nativeClient = + nativeClient || require('./NativeModuleLoader.js').load(); + this.useAlternativeClient = + process.env['AWS_LAMBDA_NODEJS_USE_ALTERNATIVE_CLIENT_1'] === 'true'; + + let [hostname, port] = hostnamePort.split(':'); + this.hostname = hostname; + this.port = parseInt(port, 10); + this.agent = new this.http.Agent({ + keepAlive: true, + maxSockets: 1, + }); + } + + /** + * Complete and invocation with the provided response. + * @param {Object} response + * An arbitrary object to convert to JSON and send back as as response. + * @param {String} id + * The invocation ID. + * @param {Function} callback + * The callback to run after the POST response ends + */ + postInvocationResponse(response, id, callback) { + let bodyString = _trySerializeResponse(response); + this.nativeClient.done(encodeURIComponent(id), bodyString); + callback(); + } + + /** + * Stream the invocation response. + * @param {String} id + * The invocation ID. + * @param {Function} callback + * The callback to run after the POST response ends + * @return {object} + * A response stream and a Promise that resolves when the stream is done. + */ + getStreamForInvocationResponse(id, callback, options) { + const ret = createResponseStream({ + httpOptions: { + agent: this.agent, + http: this.http, + hostname: this.hostname, + method: 'POST', + port: this.port, + path: + '/2018-06-01/runtime/invocation/' + + encodeURIComponent(id) + + '/response', + highWaterMark: options?.highWaterMark, + }, + }); + + return { + request: ret.request, + responseDone: ret.responseDone.then((_) => { + if (callback) { + callback(); + } + }), + }; + } + + /** + * Post an initialization error to the RAPID API. + * @param {Error} error + * @param {Function} callback + * The callback to run after the POST response ends + */ + postInitError(error, callback) { + let response = Errors.toRapidResponse(error); + this._post( + `/2018-06-01/runtime/init/error`, + response, + { [ERROR_TYPE_HEADER]: response.errorType }, + callback, + ); + } + + /** + * Post an invocation error to the RAPID API + * @param {Error} error + * @param {String} id + * The invocation ID for the in-progress invocation. + * @param {Function} callback + * The callback to run after the POST response ends + */ + postInvocationError(error, id, callback) { + let response = Errors.toRapidResponse(error); + let bodyString = _trySerializeResponse(response); + let xrayString = XRayError.formatted(error); + this.nativeClient.error(encodeURIComponent(id), bodyString, xrayString); + callback(); + } + + /** + * Get the next invocation. + * @return {PromiseLike.} + * A promise which resolves to an invocation object that contains the body + * as json and the header array. e.g. {bodyJson, headers} + */ + async nextInvocation() { + if (this.useAlternativeClient) { + const options = { + hostname: this.hostname, + port: this.port, + path: '/2018-06-01/runtime/invocation/next', + method: 'GET', + agent: this.agent, + }; + return new Promise((resolve, reject) => { + let request = this.http.request(options, (response) => { + let data = ''; + response + .setEncoding('utf-8') + .on('data', (chunk) => { + data += chunk; + }) + .on('end', () => { + resolve({ + bodyJson: data, + headers: response.headers, + }); + }); + }); + request + .on('error', (e) => { + reject(e); + }) + .end(); + }); + } + + return this.nativeClient.next(); + } + + /** + * HTTP Post to a path. + * @param {String} path + * @param {Object} body + * The body is serialized into JSON before posting. + * @param {Object} headers + * The http headers + * @param (function()} callback + * The callback to run after the POST response ends + */ + _post(path, body, headers, callback) { + let bodyString = _trySerializeResponse(body); + const options = { + hostname: this.hostname, + port: this.port, + path: path, + method: 'POST', + headers: Object.assign( + { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.from(bodyString).length, + }, + headers || {}, + ), + agent: this.agent, + }; + let request = this.http.request(options, (response) => { + response + .on('end', () => { + callback(); + }) + .on('error', (e) => { + throw e; + }) + .on('data', () => {}); + }); + request + .on('error', (e) => { + throw e; + }) + .end(bodyString, 'utf-8'); + } +}; + +/** + * Attempt to serialize an object as json. Capture the failure if it occurs and + * throw one that's known to be serializable. + */ +function _trySerializeResponse(body) { + try { + return JSON.stringify(body === undefined ? null : body); + } catch (err) { + throw new Error('Unable to stringify response body'); + } +} diff --git a/src/ResponseStream.js b/src/ResponseStream.js new file mode 100644 index 00000000..b1c09ddf --- /dev/null +++ b/src/ResponseStream.js @@ -0,0 +1,288 @@ +/** + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +const { InvalidStreamingOperation, toRapidResponse } = require('./Errors.js'); +const { verbose, vvverbose } = require('./VerboseLog.js').logger('STREAM'); +const net = require('net'); + +const STATUS_READY = 'ready'; // request created, no data sent yet, can send more data. +const STATUS_WRITE_CALLED = 'write_called'; // .write called and request created. + +const HEADER_RESPONSE_MODE = 'Lambda-Runtime-Function-Response-Mode'; +const VALUE_STREAMING = 'streaming'; +const TRAILER_NAME_ERROR_TYPE = 'Lambda-Runtime-Function-Error-Type'; +const TRAILER_NAME_ERROR_BODY = 'Lambda-Runtime-Function-Error-Body'; + +const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + +const failProps = new WeakMap(); + +function addFailWeakProp(req, fn) { + failProps.set(req, fn); +} + +function tryCallFail(req, err, callback) { + const fail = failProps.get(req); + if (typeof fail === 'function') { + fail(err, callback); + return true; + } + return false; +} + +function writableStreamOnly(inner) { + const fns = [ + // stream.Writable + 'cork', + 'destroy', + 'end', + 'uncork', + 'write', + + // EventEmitter + 'addListener', + 'emit', + 'eventNames', + 'getMaxListeners', + 'listenerCount', + 'listeners', + 'off', + 'on', + 'once', + 'prependListener', + 'prependOnceListener', + 'rawListeners', + 'removeAllListeners', + 'removeListener', + 'setMaxListeners', + + // AWS + 'setContentType', + ]; + + const propsReadWrite = ['destroyed', 'writable', '_onBeforeFirstWrite']; + + const propsReadOnly = [ + 'writableFinished', + 'writableObjectMode', + 'writableBuffer', + 'writableEnded', + 'writableNeedDrain', + 'writableHighWaterMark', + 'writableCorked', + 'writableLength', + ]; + + const stream = Object.fromEntries( + fns.map((fn) => { + return [fn, inner[fn].bind(inner)]; + }), + ); + + Object.defineProperties( + stream, + Object.fromEntries( + propsReadWrite.map((prop) => [ + prop, + { + get() { + return inner[prop]; + }, + set(value) { + inner[prop] = value; + }, + }, + ]), + ), + ); + + Object.defineProperties( + stream, + Object.fromEntries( + propsReadOnly.map((prop) => [ + prop, + { + get() { + return inner[prop]; + }, + }, + ]), + ), + ); + + return stream; +} + +// Wraps a "transport" that can accept data in chunks. Transport can +// be an HTTP/1.1 connection with chunking. +// WARN There is NO chunk fidelity, i.e. no guarantee that HTTP chunks +// will map to Stream write invocations 1-1. +function createResponseStream(options) { + let status = STATUS_READY; + let req = undefined; + + const headers = { + [HEADER_RESPONSE_MODE]: VALUE_STREAMING, + Trailer: [TRAILER_NAME_ERROR_TYPE, TRAILER_NAME_ERROR_BODY], + 'Content-Type': options.contentType + ? options.contentType + : DEFAULT_CONTENT_TYPE, + }; + + let responseDoneResolve; + let responseDoneReject; + let responseDonePromise = new Promise((resolve, reject) => { + responseDoneResolve = resolve; + responseDoneReject = reject; + }); + + let headersDoneResolve; + let headersDoneReject; + let headersDonePromise = new Promise((resolve, reject) => { + headersDoneResolve = resolve; + headersDoneReject = reject; + }); + + const agent = options.httpOptions.agent; + agent.createConnection = (opts, connectionListener) => { + return net.createConnection( + { + ...opts, + highWaterMark: options?.httpOptions?.highWaterMark, + }, + connectionListener, + ); + }; + + req = options.httpOptions.http.request( + { + http: options.httpOptions.http, + contentType: options.httpOptions.contentType, + method: options.httpOptions.method, + hostname: options.httpOptions.hostname, + port: options.httpOptions.port, + path: options.httpOptions.path, + headers, + agent: agent, + }, + (res) => { + headersDoneResolve({ + statusCode: res.statusCode, + statusMessage: res.statusMessage, + headers: res.headers, + }); + + let buf = undefined; + + res.on('data', (chunk) => { + buf = typeof buf === 'undefined' ? chunk : Buffer.concat([buf, chunk]); + }); + + res.on('aborted', (err) => { + if (responseDoneReject) { + responseDoneReject(err); + } + req.destroy(err); + }); + + res.on('end', () => { + vvverbose('rapid response', buf ? buf.toString() : 'buf undefined'); + + responseDoneResolve(buf); + }); + }, + ); + + req.on('error', (err) => { + if (headersDoneReject) { + headersDoneReject(err); + } + + if (responseDoneReject) { + responseDoneReject(err); + } + + req.destroy(err); + }); + + const origEnd = req.end.bind(req); + req.end = function (cb) { + origEnd(cb); + }; + + req.setContentType = function (contentType) { + if (status !== STATUS_READY) { + throw new InvalidStreamingOperation('Cannot set content-type, too late.'); + } + req.setHeader('Content-Type', contentType); + }; + + const origWrite = req.write.bind(req); + req.write = function (chunk, encoding, callback) { + vvverbose( + 'ResponseStream::write', + chunk.length, + 'callback:', + typeof callback, + ); + + if ( + typeof chunk !== 'string' && + !Buffer.isBuffer(chunk) && + chunk?.constructor !== Uint8Array + ) { + chunk = JSON.stringify(chunk); + } + + if ( + status === STATUS_READY && + typeof this._onBeforeFirstWrite === 'function' + ) { + this._onBeforeFirstWrite((ch) => origWrite(ch)); + } + + // First write shall open the connection. + const ret = origWrite(chunk, encoding, callback); + + vvverbose('ResponseStream::origWrite', ret); + vvverbose('ResponseStream::write outputData len', this.outputData.length); + vvverbose('ResponseStream::write outputSize', this.outputSize); + + if (status === STATUS_READY) { + status = STATUS_WRITE_CALLED; + } + + return ret; + }; + + const request = writableStreamOnly(req); + + // This will close the stream after sending the error. + addFailWeakProp(request, function (err, callback) { + verbose('ResponseStream::fail err:', err); + + const error = toRapidResponse(err); + + // Send error as trailers. + req.addTrailers({ + [TRAILER_NAME_ERROR_TYPE]: error.errorType, + [TRAILER_NAME_ERROR_BODY]: Buffer.from(JSON.stringify(error)).toString( + 'base64', + ), + }); + + req.end(callback); + }); + + return { + request, + headersDone: headersDonePromise, // Not required to be awaited. + responseDone: responseDonePromise, + }; +} + +module.exports.createResponseStream = createResponseStream; +module.exports.tryCallFail = tryCallFail; diff --git a/src/Runtime.js b/src/Runtime.js new file mode 100644 index 00000000..77d6eaac --- /dev/null +++ b/src/Runtime.js @@ -0,0 +1,216 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * This module defines the top-level Runtime class which controls the + * bootstrap's execution flow. + */ + +'use strict'; + +const InvokeContext = require('./InvokeContext.js'); +const CallbackContext = require('./CallbackContext.js'); +const StreamingContext = require('./StreamingContext.js'); +const BeforeExitListener = require('./BeforeExitListener.js'); +const { STREAM_RESPONSE } = require('./UserFunction.js'); +const { NodeJsExit } = require('./Errors.js'); +const { verbose, vverbose } = require('./VerboseLog.js').logger('RAPID'); +const { structuredConsole } = require('./LogPatch'); + +module.exports = class Runtime { + constructor(client, handler, handlerMetadata, errorCallbacks) { + this.client = client; + this.handler = handler; + this.handlerMetadata = handlerMetadata; + this.errorCallbacks = errorCallbacks; + this.handleOnce = + handlerMetadata.streaming === STREAM_RESPONSE + ? this.handleOnceStreaming + : this.handleOnceNonStreaming; + } + + /** + * Schedule the next loop iteration to start at the beginning of the next time + * around the event loop. + */ + scheduleIteration() { + let that = this; + setImmediate(() => { + that.handleOnce().then( + // Success is a no-op at this level. There are 2 cases: + // 1 - The user used one of the callback functions which already + // schedules the next iteration. + // 2 - The next iteration is not scheduled because the + // waitForEmptyEventLoop was set. In this case the beforeExit + // handler will automatically start the next iteration. + () => {}, + + // Errors should not reach this level in typical execution. If they do + // it's a sign of an issue in the Client or a bug in the runtime. So + // dump it to the console and attempt to report it as a Runtime error. + (err) => { + console.log(`Unexpected Top Level Error: ${err.toString()}`); + this.errorCallbacks.uncaughtException(err); + }, + ); + }); + } + + /** + * Wait for the next invocation, process it, and schedule the next iteration. + */ + async handleOnceNonStreaming() { + let { bodyJson, headers } = await this.client.nextInvocation(); + let invokeContext = new InvokeContext(headers); + invokeContext.updateLoggingContext(); + + let [callback, callbackContext, markCompleted] = CallbackContext.build( + this.client, + invokeContext.invokeId, + this.scheduleIteration.bind(this), + ); + + try { + this._setErrorCallbacks(invokeContext.invokeId); + this._setDefaultExitListener(invokeContext.invokeId, markCompleted, this.handlerMetadata.isAsync); + + let result = this.handler( + JSON.parse(bodyJson), + invokeContext.attachEnvironmentData(callbackContext), + callback, + ); + + if (_isPromise(result)) { + result + .then(callbackContext.succeed, callbackContext.fail) + .catch(callbackContext.fail); + } + } catch (err) { + callback(err); + } + } + + /** + * Wait for the next invocation, process it, and schedule the next iteration. + */ + async handleOnceStreaming() { + let { bodyJson, headers } = await this.client.nextInvocation(); + + let invokeContext = new InvokeContext(headers); + invokeContext.updateLoggingContext(); + + let streamingContext = StreamingContext.build( + this.client, + invokeContext.invokeId, + this.scheduleIteration.bind(this), + this.handlerMetadata?.highWaterMark + ? { highWaterMark: this.handlerMetadata.highWaterMark } + : undefined, + ); + + const { + responseStream, + rapidResponse, + scheduleNext, + fail: ctxFail, + } = streamingContext.createStream(); + delete streamingContext.createStream; + + try { + this._setErrorCallbacks(invokeContext.invokeId); + this._setStreamingExitListener(invokeContext.invokeId, responseStream); + + const ctx = invokeContext.attachEnvironmentData(streamingContext); + + verbose('Runtime::handleOnceStreaming', 'invoking handler'); + const event = JSON.parse(bodyJson); + const handlerResult = this.handler(event, responseStream, ctx); + verbose('Runtime::handleOnceStreaming', 'handler returned'); + + if (!_isPromise(handlerResult)) { + verbose('Runtime got non-promise response'); + ctxFail('Streaming does not support non-async handlers.', scheduleNext); + + return; + } + + const result = await handlerResult; + if (typeof result !== 'undefined') { + console.warn('Streaming handlers ignore return values.'); + } + verbose('Runtime::handleOnceStreaming result is awaited.'); + + // await for the rapid response if present. + if (rapidResponse) { + const res = await rapidResponse; + vverbose('RAPID response', res); + } + + if (!responseStream.writableFinished) { + ctxFail('Response stream is not finished.', scheduleNext); + return; + } + + // Handler returned and response has ended. + scheduleNext(); + } catch (err) { + verbose('Runtime::handleOnceStreaming::finally stream destroyed'); + ctxFail(err, scheduleNext); + } + } + + /** + * Replace the error handler callbacks. + * @param {String} invokeId + */ + _setErrorCallbacks(invokeId) { + this.errorCallbacks.uncaughtException = (error) => { + this.client.postInvocationError(error, invokeId, () => { + process.exit(129); + }); + }; + this.errorCallbacks.unhandledRejection = (error) => { + this.client.postInvocationError(error, invokeId, () => { + process.exit(128); + }); + }; + } + + /** + * Setup the 'beforeExit' listener that is used if the callback is never + * called and the handler is not async. + * CallbackContext replaces the listener if a callback is invoked. + */ + _setDefaultExitListener(invokeId, markCompleted, isAsync) { + BeforeExitListener.set(() => { + markCompleted(); + // if the handle signature is async, we do want to fail the invocation + if (isAsync) { + const nodeJsExitError = new NodeJsExit(); + structuredConsole.logError('Invoke Error', nodeJsExitError); + this.client.postInvocationError(nodeJsExitError, invokeId, () => + this.scheduleIteration(), + ); + // if the handler signature is sync, or use callback, we do want to send a successful invocation with a null payload if the customer forgot to call the callback + } else { + this.client.postInvocationResponse(null, invokeId, () => + this.scheduleIteration(), + ); + } + }); + } + + /** + * Setup the 'beforeExit' listener that is used if the callback is never + * called and the handler is not async. + * CallbackContext replaces the listener if a callback is invoked. + */ + _setStreamingExitListener(_invokeId) { + BeforeExitListener.set(() => { + this.scheduleIteration(); + }); + } +}; + +function _isPromise(obj) { + return obj && obj.then && typeof obj.then === 'function'; +} diff --git a/src/Runtime/BeforeExitListener.ts b/src/Runtime/BeforeExitListener.ts deleted file mode 100644 index 74dbc210..00000000 --- a/src/Runtime/BeforeExitListener.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -import { IBeforeExitListener } from "../Common"; - -/** - * The runtime has a single beforeExit function which is stored in the global - * object with a symbol key. - * The symbol is not exported. - * The process.beforeExit listener is setup in index.js along with all other - * top-level process event listeners. - */ - -// define a named symbol for the handler function -const LISTENER_SYMBOL = Symbol.for("aws.lambda.beforeExit"); - -const NO_OP_LISTENER = () => { - /* NoOp */ -}; - -// export a setter -class BeforeExitListener implements IBeforeExitListener { - constructor() { - this.reset(); - } - - /** - * Call the listener function with no arguments. - */ - invoke = (): void => (global as any)[LISTENER_SYMBOL](); - - /** - * Reset the listener to a no-op function. - */ - reset = (): (() => void) => - ((global as any)[LISTENER_SYMBOL] = NO_OP_LISTENER); - - /** - * Set the listener to the provided function. - */ - set = (listener: () => void): (() => void) => - ((global as any)[LISTENER_SYMBOL] = listener); -} - -const beforeExitListener = new BeforeExitListener(); - -export default beforeExitListener; diff --git a/src/Runtime/CallbackContext.ts b/src/Runtime/CallbackContext.ts deleted file mode 100644 index eb85f8de..00000000 --- a/src/Runtime/CallbackContext.ts +++ /dev/null @@ -1,164 +0,0 @@ -/* eslint-disable no-console */ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -import BeforeExitListener from "./BeforeExitListener"; -import { - ErrorStringOrUndefinedOrNull, - ICallbackContext, - ErrorStringOrUndefined, - CallbackFunction, -} from "../Common"; -import * as Errors from "../Errors"; -import { IRuntimeClient } from "../RuntimeClient"; - -/** - * Construct the base-context object which includes the required flags and - * callback methods for the Node programming model. - * - * @param client {Client} - * The Runtime client used to post results/errors. - * @param id {string} - * The invokeId for the current invocation. - * @param scheduleNext {function} - * A function which takes no params and immediately schedules the next - * iteration of the invoke loop. - * @returns [callback, context] - * The same function and context object, but wrapped such that only the - * first call to any function will be successful. All subsequent calls are - * a no-op. - */ -export const build = function ( - client: IRuntimeClient, - id: string, - scheduleNext: () => void -): [CallbackFunction, ICallbackContext] { - const [callback, context] = _rawCallbackContext(client, id, scheduleNext); - return _wrappedCallbackContext(callback, context); -}; - -function _homogeneousError(err: ErrorStringOrUndefined) { - if (err instanceof Error) { - return err; - } else { - return new Error(err); - } -} - -/** - * Build the callback function and the part of the context which exposes - * the succeed/fail/done callbacks. - * @param client {Client} - * The Runtime client used to post results/errors. - * @param id {string} - * The invokeId for the current invocation. - * @param scheduleNext {function} - * A function which takes no params and immediately schedules the next - * iteration of the invoke loop. - */ -function _rawCallbackContext( - client: IRuntimeClient, - id: string, - scheduleNext: () => void -): [CallbackFunction, ICallbackContext] { - const postError = (err: ErrorStringOrUndefined, callback: () => void) => { - const homogeneousError = _homogeneousError(err); - console.error("Invoke Error", Errors.toFormatted(homogeneousError)); - client.postInvocationError(err, id, callback); - }; - - const complete = (result: unknown, callback: () => void) => { - client.postInvocationResponse(result, id, callback); - }; - - let waitForEmptyEventLoop = true; - - const callback = ( - err: ErrorStringOrUndefinedOrNull, - result: unknown - ): void => { - BeforeExitListener.reset(); - if (err !== undefined && err !== null) { - postError(err, scheduleNext); - } else { - complete(result, () => { - if (!waitForEmptyEventLoop) { - scheduleNext(); - } else { - BeforeExitListener.set(scheduleNext); - } - }); - } - }; - - const done = (err: ErrorStringOrUndefinedOrNull, result?: unknown) => { - BeforeExitListener.reset(); - if (err !== undefined && err !== null) { - postError(err, scheduleNext); - } else { - complete(result, scheduleNext); - } - }; - - const succeed = (result: unknown) => { - done(null, result); - }; - - const fail = (err: ErrorStringOrUndefinedOrNull) => { - if (err === undefined || err === null) { - done("handled"); - } else { - done(err); - } - }; - - const callbackContext = { - get callbackWaitsForEmptyEventLoop(): boolean { - return waitForEmptyEventLoop; - }, - set callbackWaitsForEmptyEventLoop(value: boolean) { - waitForEmptyEventLoop = value; - }, - succeed, - fail, - done, - }; - - return [callback, callbackContext]; -} - -/** - * Wraps the callback and context so that only the first call to any callback - * succeeds. - * @param callback {function} - * the node-style callback function that was previously generated but not - * yet wrapped. - * @param callbackContext {object} - * The previously generated callbackContext object that contains - * getter/setters for the contextWaitsForEmptyeventLoop flag and the - * succeed/fail/done functions. - * @return [callback, context] - */ -function _wrappedCallbackContext( - callback: CallbackFunction, - callbackContext: ICallbackContext -): [CallbackFunction, ICallbackContext] { - let finished = false; - // eslint-disable-next-line @typescript-eslint/ban-types - const onlyAllowFirstCall = function (toWrap: Function) { - return function (...args: unknown[]) { - if (!finished) { - // eslint-disable-next-line prefer-spread - toWrap.apply(null, args); - finished = true; - } - }; - }; - - callbackContext.succeed = onlyAllowFirstCall(callbackContext.succeed); - callbackContext.fail = onlyAllowFirstCall(callbackContext.fail); - callbackContext.done = onlyAllowFirstCall(callbackContext.done); - - return [onlyAllowFirstCall(callback), callbackContext]; -} diff --git a/src/Runtime/InvokeContext.ts b/src/Runtime/InvokeContext.ts deleted file mode 100644 index cbcc3c6f..00000000 --- a/src/Runtime/InvokeContext.ts +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * This module defines the InvokeContext and supporting functions. The - * InvokeContext is responsible for pulling information from the invoke headers - * and for wrapping the Runtime Client object's error and response functions. - */ - -"use strict"; - -import { strict as assert } from "assert"; -import { IncomingHttpHeaders } from "http"; -import { - ICallbackContext, - IHeaderData, - IEnvironmentData, - INVOKE_HEADER, -} from "../Common"; -import LogPatch from "../utils/LogPatch"; - -const setCurrentRequestId = LogPatch.setCurrentRequestId; - -export default class InvokeContext { - headers: IncomingHttpHeaders; - - constructor(headers: IncomingHttpHeaders) { - this.headers = _enforceLowercaseKeys(headers); - } - - private getHeaderValue(key: string): string | undefined { - const headerVal = this.headers[key]; - - switch (typeof headerVal) { - case "undefined": - return undefined; - case "string": - return headerVal; - default: - if (headerVal.length == 0) { - return undefined; - } - - return headerVal[0]; - } - } - - /** - * The invokeId for this request. - */ - get invokeId(): string { - const id = this.getHeaderValue(INVOKE_HEADER.AWSRequestId); - assert.ok(id, "invocation id is missing or invalid"); - return id; - } - - /** - * The header data for this request. - */ - get headerData(): IHeaderData { - return this._headerData(); - } - - /** - * Push relevant invoke data into the logging context. - */ - updateLoggingContext(): void { - setCurrentRequestId(this.invokeId); - } - - /** - * Attach all of the relavant environmental and invocation data to the - * provided object. - * This method can throw if the headers are malformed and cannot be parsed. - * @param callbackContext {Object} - * The callbackContext object returned by a call to buildCallbackContext(). - * @return {Object} - * The user context object with all required data populated from the headers - * and environment variables. - */ - attachEnvironmentData( - callbackContext: ICallbackContext - ): ICallbackContext & IEnvironmentData & IHeaderData { - this._forwardXRay(); - return Object.assign( - callbackContext, - this._environmentalData(), - this._headerData() - ); - } - - /** - * All parts of the user-facing context object which are provided through - * environment variables. - */ - private _environmentalData(): IEnvironmentData { - return { - functionVersion: process.env["AWS_LAMBDA_FUNCTION_VERSION"], - functionName: process.env["AWS_LAMBDA_FUNCTION_NAME"], - memoryLimitInMB: process.env["AWS_LAMBDA_FUNCTION_MEMORY_SIZE"], - logGroupName: process.env["AWS_LAMBDA_LOG_GROUP_NAME"], - logStreamName: process.env["AWS_LAMBDA_LOG_STREAM_NAME"], - }; - } - - /** - * All parts of the user-facing context object which are provided through - * request headers. - */ - private _headerData(): IHeaderData { - const deadline = parseInt( - this.getHeaderValue(INVOKE_HEADER.DeadlineMs) || "" - ); - return { - clientContext: _parseJson( - this.getHeaderValue(INVOKE_HEADER.ClientContext), - "ClientContext" - ), - identity: _parseJson( - this.getHeaderValue(INVOKE_HEADER.CognitoIdentity), - "CognitoIdentity" - ), - invokedFunctionArn: this.getHeaderValue(INVOKE_HEADER.ARN), - awsRequestId: this.getHeaderValue(INVOKE_HEADER.AWSRequestId), - getRemainingTimeInMillis: function () { - return deadline - Date.now(); - }, - }; - } - - /** - * Forward the XRay header into the environment variable. - */ - private _forwardXRay(): void { - if (this.getHeaderValue(INVOKE_HEADER.XRayTrace)) { - process.env["_X_AMZN_TRACE_ID"] = this.getHeaderValue( - INVOKE_HEADER.XRayTrace - ); - } else { - delete process.env["_X_AMZN_TRACE_ID"]; - } - } -} - -/** - * Parse a JSON string and throw a readable error if something fails. - * @param jsonString {string} - the string to attempt to parse - * @param name {string} - the name to use when describing the string in an error - * @return object - the parsed object - * @throws if jsonString cannot be parsed - */ -function _parseJson(jsonString?: string, name?: string): string | undefined { - if (jsonString !== undefined) { - try { - return JSON.parse(jsonString); - } catch (err) { - throw new Error(`Cannot parse ${name} as json: ${err.toString()}`); - } - } else { - return undefined; - } -} - -/** - * Construct a copy of an object such that all of its keys are lowercase. - */ -function _enforceLowercaseKeys( - original: IncomingHttpHeaders -): IncomingHttpHeaders { - return Object.keys(original).reduce((enforced, originalKey) => { - enforced[originalKey.toLowerCase()] = original[originalKey]; - return enforced; - }, {} as IncomingHttpHeaders); -} diff --git a/src/Runtime/Runtime.ts b/src/Runtime/Runtime.ts deleted file mode 100644 index 2abbcc12..00000000 --- a/src/Runtime/Runtime.ts +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * This module defines the top-level Runtime class which controls the - * bootstrap's execution flow. - */ - -"use strict"; - -import BeforeExitListener from "./BeforeExitListener"; -import { HandlerFunction, IErrorCallbacks } from "../Common"; -import * as CallbackContext from "./CallbackContext"; -import InvokeContext from "./InvokeContext"; -import { IRuntimeClient } from "../RuntimeClient"; - -export default class Runtime { - client: IRuntimeClient; - errorCallbacks: IErrorCallbacks; - handler: HandlerFunction; - - constructor( - client: IRuntimeClient, - handler: HandlerFunction, - errorCallbacks: IErrorCallbacks - ) { - this.client = client; - this.handler = handler; - this.errorCallbacks = errorCallbacks; - } - - /** - * Schedule the next loop iteration to start at the beginning of the next time - * around the event loop. - */ - scheduleIteration(): void { - setImmediate(() => { - this.handleOnce().then( - // Success is a no-op at this level. There are 2 cases: - // 1 - The user used one of the callback functions which already - // schedules the next iteration. - // 2 - The next iteration is not scheduled because the - // waitForEmptyEventLoop was set. In this case the beforeExit - // handler will automatically start the next iteration. - // eslint-disable-next-line @typescript-eslint/no-empty-function - () => {}, - - // Errors should not reach this level in typical execution. If they do - // it's a sign of an issue in the Client or a bug in the runtime. So - // dump it to the console and attempt to report it as a Runtime error. - (err) => { - // eslint-disable-next-line no-console - console.log(`Unexpected Top Level Error: ${err.toString()}`); - this.errorCallbacks.uncaughtException(err); - } - ); - }); - } - - /** - * Wait for the next invocation, process it, and schedule the next iteration. - */ - async handleOnce(): Promise { - const { bodyJson, headers } = await this.client.nextInvocation(); - const invokeContext = new InvokeContext(headers); - invokeContext.updateLoggingContext(); - - const [callback, callbackContext] = CallbackContext.build( - this.client, - invokeContext.invokeId, - this.scheduleIteration.bind(this) - ); - - try { - this._setErrorCallbacks(invokeContext.invokeId); - this._setDefaultExitListener(invokeContext.invokeId); - - const result = this.handler( - JSON.parse(bodyJson), - invokeContext.attachEnvironmentData(callbackContext), - callback - ); - - if (_isPromise(result)) { - result - .then(callbackContext.succeed, callbackContext.fail) - .catch(callbackContext.fail); - } - } catch (err) { - callback(err); - } - } - - /** - * Replace the error handler callbacks. - * @param {String} invokeId - */ - private _setErrorCallbacks(invokeId: string): void { - this.errorCallbacks.uncaughtException = (error: Error): void => { - this.client.postInvocationError(error, invokeId, () => { - process.exit(129); - }); - }; - this.errorCallbacks.unhandledRejection = (error: Error): void => { - this.client.postInvocationError(error, invokeId, () => { - process.exit(128); - }); - }; - } - - /** - * Setup the 'beforeExit' listener that is used if the callback is never - * called and the handler is not async. - * CallbackContext replaces the listener if a callback is invoked. - */ - private _setDefaultExitListener(invokeId: string): void { - BeforeExitListener.set(() => { - this.client.postInvocationResponse(null, invokeId, () => - this.scheduleIteration() - ); - }); - } -} - -function _isPromise(obj: Promise | unknown): obj is Promise { - return obj instanceof Promise; -} diff --git a/src/Runtime/index.ts b/src/Runtime/index.ts deleted file mode 100644 index e83a528d..00000000 --- a/src/Runtime/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - */ -import Runtime from "./Runtime"; - -export default Runtime; diff --git a/src/RuntimeClient/RuntimeClient.ts b/src/RuntimeClient/RuntimeClient.ts deleted file mode 100644 index bf71bc62..00000000 --- a/src/RuntimeClient/RuntimeClient.ts +++ /dev/null @@ -1,247 +0,0 @@ -/** - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * This module defines the Runtime client which is responsible for all HTTP - * interactions with the Runtime layer. - */ - -"use strict"; - -import { - Agent, - RequestOptions, - IncomingMessage, - ClientRequest, - OutgoingHttpHeaders, -} from "http"; -import { URL } from "url"; - -import { InvocationResponse, NativeClient } from "../Common"; -import * as Errors from "../Errors"; -import * as XRayError from "../Errors/XRayError"; - -const ERROR_TYPE_HEADER = "Lambda-Runtime-Function-Error-Type"; - -interface HttpModule { - Agent: typeof Agent; - request( - options: RequestOptions | string | URL, - callback?: (res: IncomingMessage) => void - ): ClientRequest; -} - -export interface IRuntimeClient { - nextInvocation: () => Promise; - - postInvocationError: ( - error: unknown, - id: string, - callback: () => void - ) => void; - - postInvocationResponse: ( - response: unknown, - id: string, - callback: () => void - ) => void; -} - -function userAgent(): string { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const version = require("../../package.json").version; - - return `aws-lambda-nodejs/${process.version}-${version}`; -} - -/** - * Objects of this class are responsible for all interactions with the Runtime - * API. - */ -export default class RuntimeClient implements IRuntimeClient { - agent: Agent; - http: HttpModule; - nativeClient: NativeClient; - userAgent: string; - useAlternativeClient: boolean; - - hostname: string; - port: number; - - constructor( - hostnamePort: string, - httpClient?: HttpModule, - nativeClient?: NativeClient - ) { - this.http = httpClient || require("http"); - this.nativeClient = - nativeClient || require("../../build/Release/runtime-client.node"); - this.userAgent = userAgent(); - this.nativeClient.initializeClient(this.userAgent); - this.useAlternativeClient = - process.env["AWS_LAMBDA_NODEJS_USE_ALTERNATIVE_CLIENT_1"] === "true"; - - const [hostname, port] = hostnamePort.split(":"); - this.hostname = hostname; - this.port = parseInt(port, 10); - this.agent = new this.http.Agent({ - keepAlive: true, - maxSockets: 1, - }); - } - - /** - * Complete and invocation with the provided response. - * @param {Object} response - * An arbitrary object to convert to JSON and send back as as response. - * @param {String} id - * The invocation ID. - * @param {function()} callback - * The callback to run after the POST response ends - */ - postInvocationResponse( - response: unknown, - id: string, - callback: () => void - ): void { - const bodyString = _trySerializeResponse(response); - this.nativeClient.done(id, bodyString); - callback(); - } - - /** - * Post an initialization error to the Runtime API. - * @param {Error} error - * @param {function()} callback - * The callback to run after the POST response ends - */ - postInitError(error: unknown, callback: () => void): void { - const response = Errors.toRuntimeResponse(error); - this._post( - `/2018-06-01/runtime/init/error`, - response, - { [ERROR_TYPE_HEADER]: response.errorType }, - callback - ); - } - - /** - * Post an invocation error to the Runtime API - * @param {Error} error - * @param {String} id - * The invocation ID for the in-progress invocation. - * @param {function()} callback - * The callback to run after the POST response ends - */ - postInvocationError(error: unknown, id: string, callback: () => void): void { - const response = Errors.toRuntimeResponse(error); - const bodyString = _trySerializeResponse(response); - const xrayString = XRayError.toFormatted(error); - this.nativeClient.error(id, bodyString, xrayString); - callback(); - } - - /** - * Get the next invocation. - * @return {PromiseLike.} - * A promise which resolves to an invocation object that contains the body - * as json and the header array. e.g. {bodyJson, headers} - */ - async nextInvocation(): Promise { - if (this.useAlternativeClient) { - const options = { - hostname: this.hostname, - port: this.port, - path: "/2018-06-01/runtime/invocation/next", - method: "GET", - agent: this.agent, - headers: { - "User-Agent": this.userAgent, - }, - }; - return new Promise((resolve, reject) => { - const request = this.http.request(options, (response) => { - let data = ""; - response - .setEncoding("utf-8") - .on("data", (chunk) => { - data += chunk; - }) - .on("end", () => { - resolve({ - bodyJson: data, - headers: response.headers, - }); - }); - }); - request - .on("error", (e) => { - reject(e); - }) - .end(); - }); - } - - return this.nativeClient.next(); - } - - /** - * HTTP Post to a path. - * @param {String} path - * @param {Object} body - * The body is serialized into JSON before posting. - * @param {Object} headers - * The http headers - * @param {function()} callback - * The callback to run after the POST response ends - */ - _post( - path: string, - body: unknown, - headers: OutgoingHttpHeaders, - callback: () => void - ): void { - const bodyString = _trySerializeResponse(body); - const options: RequestOptions = { - hostname: this.hostname, - port: this.port, - path: path, - method: "POST", - headers: Object.assign( - { - "Content-Type": "application/json", - "Content-Length": Buffer.from(bodyString).length, - }, - headers || {} - ), - agent: this.agent, - }; - const request = this.http.request(options, (response) => { - response - .on("end", () => { - callback(); - }) - .on("error", (e) => { - throw e; - }) - // eslint-disable-next-line @typescript-eslint/no-empty-function - .on("data", () => {}); - }); - request - .on("error", (e) => { - throw e; - }) - .end(bodyString, "utf-8"); - } -} - -/** - * Attempt to serialize an object as json. Capture the failure if it occurs and - * throw one that's known to be serializable. - */ -function _trySerializeResponse(body: unknown): string { - try { - return JSON.stringify(body === undefined ? null : body); - } catch (err) { - throw new Error("Unable to stringify response body"); - } -} diff --git a/src/RuntimeClient/index.ts b/src/RuntimeClient/index.ts deleted file mode 100644 index 7cd048e4..00000000 --- a/src/RuntimeClient/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - */ -import RuntimeClient from "./RuntimeClient"; - -export default RuntimeClient; -export { IRuntimeClient } from "./RuntimeClient"; diff --git a/src/RuntimeClient/runtime-client.cc b/src/RuntimeClient/runtime-client.cc deleted file mode 100644 index d6edffa5..00000000 --- a/src/RuntimeClient/runtime-client.cc +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2019-present Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -#include -#include "aws/lambda-runtime/runtime.h" -#include "aws/lambda-runtime/version.h" -#include "napi.h" - -#include - -static aws::lambda_runtime::runtime *CLIENT; - -Napi::Value InitializeClient(const Napi::CallbackInfo & info) -{ - Napi::Env env = info.Env(); - if (info.Length() < 1) { - Napi::TypeError::New(env, "Wrong number of arguments, expected 1").ThrowAsJavaScriptException(); - return env.Null(); - } - if (!info[0].IsString()) { - Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - if (CLIENT != nullptr) { - Napi::TypeError::New(env, "Client already initialized").ThrowAsJavaScriptException(); - return env.Null(); - } - auto userAgent = info[0].As().Utf8Value(); - CLIENT = new aws::lambda_runtime::runtime(getenv("AWS_LAMBDA_RUNTIME_API"), userAgent); - return env.Null(); -} - -Napi::Value Next(const Napi::CallbackInfo & info) -{ - Napi::Env env = info.Env(); - if (CLIENT == nullptr) { - Napi::TypeError::New(env, "Client not initialized").ThrowAsJavaScriptException(); - return env.Null(); - } - auto outcome = CLIENT->get_next(); - if (!outcome.is_success()) { - Napi::TypeError::New(env, "Failed to get next!").ThrowAsJavaScriptException(); - return env.Null(); - } - - // TODO: See if json parsing works on V8:Buffer objects, which might be a way to reduce copying large payloads - auto response = outcome.get_result(); - auto response_data = Napi::String::New(env, response.payload.c_str()); - - // TODO: The current javascript code (InvokeContext.js) to handle the header values itself. - // These type conversions might be replaced by returning the final context object. - auto headers = Napi::Object::New(env); - headers.Set( - Napi::String::New(env, "lambda-runtime-deadline-ms"), - Napi::Number::New(env, - std::chrono::duration_cast( - response.deadline.time_since_epoch() - ).count() - )); - headers.Set( - Napi::String::New(env, "lambda-runtime-aws-request-id"), - Napi::String::New(env, response.request_id.c_str())); - headers.Set( - Napi::String::New(env, "lambda-runtime-trace-id"), - Napi::String::New(env, response.xray_trace_id.c_str())); - headers.Set( - Napi::String::New(env, "lambda-runtime-invoked-function-arn"), - Napi::String::New(env, response.function_arn.c_str())); - if (response.client_context != "") { - headers.Set( - Napi::String::New(env, "lambda-runtime-client-context"), - Napi::String::New(env, response.client_context.c_str())); - } - if (response.cognito_identity != "") { - headers.Set( - Napi::String::New(env, "lambda-runtime-cognito-identity"), - Napi::String::New(env, response.cognito_identity.c_str())); - } - - auto ret = Napi::Object::New(env); - ret.Set(Napi::String::New(env, "bodyJson"), response_data); - ret.Set(Napi::String::New(env, "headers"), headers); - - return ret; -} - -Napi::Value Done(const Napi::CallbackInfo & info) -{ - Napi::Env env = info.Env(); - if (CLIENT == nullptr) { - Napi::TypeError::New(env, "Client not initialized").ThrowAsJavaScriptException(); - return env.Null(); - } - if (info.Length() < 2) { - Napi::TypeError::New(env, "Wrong number of arguments, expected 2").ThrowAsJavaScriptException(); - return env.Null(); - } - if (!info[0].IsString() || !info[1].IsString()) { - Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - auto requestId = info[0].As(); - auto responseString = info[1].As(); - auto response = aws::lambda_runtime::invocation_response::success(responseString.Utf8Value(), "application/json"); - auto outcome = CLIENT->post_success(requestId.Utf8Value(), response); - return env.Null(); -} - -Napi::Value Error(const Napi::CallbackInfo & info) -{ - Napi::Env env = info.Env(); - if (CLIENT == nullptr) { - Napi::TypeError::New(env, "Client not initialized").ThrowAsJavaScriptException(); - return env.Null(); - } - if (info.Length() < 3) { - Napi::TypeError::New(env, "Wrong number of arguments, expected 3").ThrowAsJavaScriptException(); - return env.Null(); - } - if (!info[0].IsString() || !info[1].IsString() || !info[2].IsString()) { - Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - auto requestId = info[0].As(); - auto responseString = info[1].As(); - auto xrayResponse = info[2].As(); - auto response = aws::lambda_runtime::invocation_response(responseString.Utf8Value(), "application/json", false, xrayResponse.Utf8Value()); - auto outcome = CLIENT->post_failure(requestId.Utf8Value(), response); - return env.Null(); -} - -Napi::Object Init(Napi::Env env, Napi::Object exports) -{ - exports.Set(Napi::String::New(env, "initializeClient"), Napi::Function::New(env, InitializeClient)); - exports.Set(Napi::String::New(env, "next"), Napi::Function::New(env, Next)); - exports.Set(Napi::String::New(env, "done"), Napi::Function::New(env, Done)); - exports.Set(Napi::String::New(env, "error"), Napi::Function::New(env, Error)); - return exports; -} - -NODE_API_MODULE(addon, Init); diff --git a/src/StreamingContext.js b/src/StreamingContext.js new file mode 100644 index 00000000..921998b6 --- /dev/null +++ b/src/StreamingContext.js @@ -0,0 +1,83 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +const BeforeExitListener = require('./BeforeExitListener.js'); +const { InvalidStreamingOperation } = require('./Errors'); +const { verbose, vverbose } = require('./VerboseLog.js').logger('STREAM'); +const { tryCallFail } = require('./ResponseStream'); +const { structuredConsole } = require('./LogPatch'); + +/** + * Construct the base-context object which includes the required flags and + * callback methods for the Node programming model. + * @param client {RAPIDClient} + * The RAPID client used to post results/errors. + * @param id {string} + * The invokeId for the current invocation. + * @param scheduleNext {function} + * A function which takes no params and immediately schedules the next + * iteration of the invoke loop. + * @param options {object} + * An object with optional properties for streaming. + * @return {context} + * Context object that has the createStream function. + */ +module.exports.build = function (client, id, scheduleNext, options) { + let waitForEmptyEventLoop = true; + + const scheduleNextNow = () => { + verbose('StreamingContext::scheduleNextNow entered'); + if (!waitForEmptyEventLoop) { + scheduleNext(); + } else { + BeforeExitListener.set(() => { + setImmediate(() => { + scheduleNext(); + }); + }); + } + }; + + let isStreamCreated = false; + const streamingContext = { + get callbackWaitsForEmptyEventLoop() { + return waitForEmptyEventLoop; + }, + set callbackWaitsForEmptyEventLoop(value) { + waitForEmptyEventLoop = value; + }, + createStream: (callback) => { + if (isStreamCreated) { + throw new InvalidStreamingOperation( + 'Cannot create stream for the same StreamingContext more than once.', + ); + } + + const { request: responseStream, responseDone: rapidResponse } = + client.getStreamForInvocationResponse(id, callback, options); + + isStreamCreated = true; + vverbose('StreamingContext::createStream stream created'); + + return { + fail: (err, callback) => { + structuredConsole.logError('Invoke Error', err); + + tryCallFail(responseStream, err, callback); + }, + responseStream, + rapidResponse, + scheduleNext: () => { + verbose('StreamingContext::createStream scheduleNext'); + BeforeExitListener.reset(); + scheduleNextNow(); + }, + }; + }, + }; + + return streamingContext; +}; diff --git a/src/UserFunction.js b/src/UserFunction.js new file mode 100644 index 00000000..a6e16313 --- /dev/null +++ b/src/UserFunction.js @@ -0,0 +1,336 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * This module defines the functions for loading the user's code as specified + * in a handler string. + */ + +'use strict'; + +const path = require('path'); +const fs = require('fs'); +const { + HandlerNotFound, + MalformedHandlerName, + ImportModuleError, + UserCodeSyntaxError, +} = require('./Errors.js'); +const { verbose } = require('./VerboseLog.js').logger('LOADER'); +const { HttpResponseStream } = require('./HttpResponseStream'); + +const FUNCTION_EXPR = /^([^.]*)\.(.*)$/; +const RELATIVE_PATH_SUBSTRING = '..'; +const HANDLER_STREAMING = Symbol.for('aws.lambda.runtime.handler.streaming'); +const HANDLER_HIGHWATERMARK = Symbol.for( + 'aws.lambda.runtime.handler.streaming.highWaterMark', +); +const STREAM_RESPONSE = 'response'; + +// `awslambda.streamifyResponse` function is provided by default. +const NoGlobalAwsLambda = + process.env['AWS_LAMBDA_NODEJS_NO_GLOBAL_AWSLAMBDA'] === '1' || + process.env['AWS_LAMBDA_NODEJS_NO_GLOBAL_AWSLAMBDA'] === 'true'; + +/** + * Break the full handler string into two pieces, the module root and the actual + * handler string. + * Given './somepath/something/module.nestedobj.handler' this returns + * ['./somepath/something', 'module.nestedobj.handler'] + */ +function _moduleRootAndHandler(fullHandlerString) { + let handlerString = path.basename(fullHandlerString); + let moduleRoot = fullHandlerString.substring( + 0, + fullHandlerString.indexOf(handlerString), + ); + return [moduleRoot, handlerString]; +} + +/** + * Split the handler string into two pieces: the module name and the path to + * the handler function. + */ +function _splitHandlerString(handler) { + let match = handler.match(FUNCTION_EXPR); + if (!match || match.length != 3) { + throw new MalformedHandlerName('Bad handler'); + } + return [match[1], match[2]]; // [module, function-path] +} + +/** + * Resolve the user's handler function from the module. + */ +function _resolveHandler(object, nestedProperty) { + return nestedProperty.split('.').reduce((nested, key) => { + return nested && nested[key]; + }, object); +} + +function _tryRequireFile(file, extension) { + const path = file + (extension || ''); + verbose('Try loading as commonjs:', path); + return fs.existsSync(path) ? require(path) : undefined; +} + +async function _tryAwaitImport(file, extension) { + const path = file + (extension || ''); + verbose('Try loading as esmodule:', path); + + if (fs.existsSync(path)) { + return await import(path); + } + + return undefined; +} + +function _hasFolderPackageJsonTypeModule(folder) { + // Check if package.json exists, return true if type === "module" in package json. + // If there is no package.json, and there is a node_modules, return false. + // Check parent folder otherwise, if there is one. + if (folder.endsWith('/node_modules')) { + return false; + } + + const pj = path.join(folder, '/package.json'); + if (fs.existsSync(pj)) { + try { + const pkg = JSON.parse(fs.readFileSync(pj)); + if (pkg) { + if (pkg.type === 'module') { + verbose('type: module detected in', pj); + return true; + } else { + verbose('type: module not detected in', pj); + return false; + } + } + } catch (e) { + console.warn( + `${pj} cannot be read, it will be ignored for ES module detection purposes.`, + e, + ); + return false; + } + } + + if (folder === '/') { + // We have reached root without finding either a package.json or a node_modules. + return false; + } + + return _hasFolderPackageJsonTypeModule(path.resolve(folder, '..')); +} + +function _hasPackageJsonTypeModule(file) { + // File must have a .js extension + const jsPath = file + '.js'; + return fs.existsSync(jsPath) + ? _hasFolderPackageJsonTypeModule(path.resolve(path.dirname(jsPath))) + : false; +} + +/** + * Attempt to load the user's module. + * Attempts to directly resolve the module relative to the application root, + * then falls back to the more general require(). + */ +async function _tryRequire(appRoot, moduleRoot, module) { + verbose( + 'Try loading as commonjs: ', + module, + ' with paths: ,', + appRoot, + moduleRoot, + ); + + const lambdaStylePath = path.resolve(appRoot, moduleRoot, module); + + // Extensionless files are loaded via require. + const extensionless = _tryRequireFile(lambdaStylePath); + if (extensionless) { + return extensionless; + } + + // If package.json type != module, .js files are loaded via require. + const pjHasModule = _hasPackageJsonTypeModule(lambdaStylePath); + if (!pjHasModule) { + const loaded = _tryRequireFile(lambdaStylePath, '.js'); + if (loaded) { + return loaded; + } + } + + // If still not loaded, try .js, .mjs, and .cjs in that order. + // Files ending with .js are loaded as ES modules when the nearest parent package.json + // file contains a top-level field "type" with a value of "module". + // https://nodejs.org/api/packages.html#packages_type + const loaded = + (pjHasModule && (await _tryAwaitImport(lambdaStylePath, '.js'))) || + (await _tryAwaitImport(lambdaStylePath, '.mjs')) || + _tryRequireFile(lambdaStylePath, '.cjs'); + if (loaded) { + return loaded; + } + + verbose( + 'Try loading as commonjs: ', + module, + ' with path(s): ', + appRoot, + moduleRoot, + ); + + // Why not just require(module)? + // Because require() is relative to __dirname, not process.cwd(). And the + // runtime implementation is not located in /var/task + // This won't work (yet) for esModules as import.meta.resolve is still experimental + // See: https://nodejs.org/api/esm.html#esm_import_meta_resolve_specifier_parent + const nodeStylePath = require.resolve(module, { + paths: [appRoot, moduleRoot], + }); + + return require(nodeStylePath); +} + +/** + * Load the user's application or throw a descriptive error. + * @throws Runtime errors in two cases + * 1 - UserCodeSyntaxError if there's a syntax error while loading the module + * 2 - ImportModuleError if the module cannot be found + */ +async function _loadUserApp(appRoot, moduleRoot, module) { + if (!NoGlobalAwsLambda) { + globalThis.awslambda = { + streamifyResponse: (handler, options) => { + handler[HANDLER_STREAMING] = STREAM_RESPONSE; + if (typeof options?.highWaterMark === 'number') { + handler[HANDLER_HIGHWATERMARK] = parseInt(options.highWaterMark); + } + return handler; + }, + HttpResponseStream: HttpResponseStream, + }; + } + + try { + return await _tryRequire(appRoot, moduleRoot, module); + } catch (e) { + if (e instanceof SyntaxError) { + throw new UserCodeSyntaxError(e); + } else if (e.code !== undefined && e.code === 'MODULE_NOT_FOUND') { + verbose('globalPaths', JSON.stringify(require('module').globalPaths)); + throw new ImportModuleError(e); + } else { + throw e; + } + } +} + +function _throwIfInvalidHandler(fullHandlerString) { + if (fullHandlerString.includes(RELATIVE_PATH_SUBSTRING)) { + throw new MalformedHandlerName( + `'${fullHandlerString}' is not a valid handler name. Use absolute paths when specifying root directories in handler names.`, + ); + } +} + +function _isHandlerStreaming(handler) { + if ( + typeof handler[HANDLER_STREAMING] === 'undefined' || + handler[HANDLER_STREAMING] === null || + handler[HANDLER_STREAMING] === false + ) { + return false; + } + + if (handler[HANDLER_STREAMING] === STREAM_RESPONSE) { + return STREAM_RESPONSE; + } else { + throw new MalformedStreamingHandler( + 'Only response streaming is supported.', + ); + } +} + +function _highWaterMark(handler) { + if ( + typeof handler[HANDLER_HIGHWATERMARK] === 'undefined' || + handler[HANDLER_HIGHWATERMARK] === null || + handler[HANDLER_HIGHWATERMARK] === false + ) { + return undefined; + } + + const hwm = parseInt(handler[HANDLER_HIGHWATERMARK]); + return isNaN(hwm) ? undefined : hwm; +} + +/** + * Load the user's function with the approot and the handler string. + * @param appRoot {string} + * The path to the application root. + * @param handlerString {string} + * The user-provided handler function in the form 'module.function'. + * @return userFuction {function} + * The user's handler function. This function will be passed the event body, + * the context object, and the callback function. + * @throws In five cases:- + * 1 - if the handler string is incorrectly formatted an error is thrown + * 2 - if the module referenced by the handler cannot be loaded + * 3 - if the function in the handler does not exist in the module + * 4 - if a property with the same name, but isn't a function, exists on the + * module + * 5 - the handler includes illegal character sequences (like relative paths + * for traversing up the filesystem '..') + * Errors for scenarios known by the runtime, will be wrapped by Runtime.* errors. + */ +module.exports.load = async function (appRoot, fullHandlerString) { + _throwIfInvalidHandler(fullHandlerString); + + let [moduleRoot, moduleAndHandler] = _moduleRootAndHandler(fullHandlerString); + let [module, handlerPath] = _splitHandlerString(moduleAndHandler); + + let userApp = await _loadUserApp(appRoot, moduleRoot, module); + let handlerFunc = _resolveHandler(userApp, handlerPath); + + if (!handlerFunc) { + throw new HandlerNotFound( + `${fullHandlerString} is undefined or not exported`, + ); + } + + if (typeof handlerFunc !== 'function') { + throw new HandlerNotFound(`${fullHandlerString} is not a function`); + } + + return handlerFunc; +}; + +module.exports.isHandlerFunction = function (value) { + return typeof value === 'function'; +}; + +function _isAsync(handler) { + try { + return ( + handler && + typeof handler === 'function' && + handler.constructor && + handler.constructor.name === 'AsyncFunction' + ); + } catch (error) { + return false; + } +} + +module.exports.getHandlerMetadata = function (handlerFunc) { + return { + streaming: _isHandlerStreaming(handlerFunc), + highWaterMark: _highWaterMark(handlerFunc), + isAsync: _isAsync(handlerFunc), + argsNum: handlerFunc.length, + }; +}; + +module.exports.STREAM_RESPONSE = STREAM_RESPONSE; diff --git a/src/VerboseLog.js b/src/VerboseLog.js new file mode 100644 index 00000000..1f4361f4 --- /dev/null +++ b/src/VerboseLog.js @@ -0,0 +1,49 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +const EnvVarName = 'AWS_LAMBDA_RUNTIME_VERBOSE'; +const Tag = 'RUNTIME'; +const Verbosity = (() => { + if (!process.env[EnvVarName]) { + return 0; + } + + try { + const verbosity = parseInt(process.env[EnvVarName]); + return verbosity < 0 ? 0 : verbosity > 3 ? 3 : verbosity; + } catch (_) { + return 0; + } +})(); + +exports.logger = function (category) { + return { + verbose: function () { + if (Verbosity >= 1) { + const args = [...arguments].map((arg) => + typeof arg === 'function' ? arg() : arg, + ); + console.log.apply(null, [Tag, category, ...args]); + } + }, + vverbose: function () { + if (Verbosity >= 2) { + const args = [...arguments].map((arg) => + typeof arg === 'function' ? arg() : arg, + ); + console.log.apply(null, [Tag, category, ...args]); + } + }, + vvverbose: function () { + if (Verbosity >= 3) { + const args = [...arguments].map((arg) => + typeof arg === 'function' ? arg() : arg, + ); + console.log.apply(null, [Tag, category, ...args]); + } + }, + }; +}; diff --git a/src/WarningForCallbackHandlers.js b/src/WarningForCallbackHandlers.js new file mode 100644 index 00000000..7c41cf6e --- /dev/null +++ b/src/WarningForCallbackHandlers.js @@ -0,0 +1,24 @@ +/* +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +'use strict'; + +const shouldWarnOnCallbackFunctionUse = (metadata) => { + return ( + process.env.AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING === undefined && + metadata !== undefined && + metadata.argsNum == 3 && + metadata.isAsync == false && + metadata.streaming == false + ); +}; + +module.exports.checkForDeprecatedCallback = function (metadata) { + if (shouldWarnOnCallbackFunctionUse(metadata)) { + console.warn( + `AWS Lambda plans to remove support for callback-based function handlers starting with Node.js 24. You will need to update this function to use an async handler to use Node.js 24 or later. For more information and to provide feedback on this change, see https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/issues/137. To disable this warning, set the AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING environment variable.`, + ); + } +}; \ No newline at end of file diff --git a/src/XRayError.js b/src/XRayError.js new file mode 100644 index 00000000..520152ec --- /dev/null +++ b/src/XRayError.js @@ -0,0 +1,94 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +module.exports.formatted = (err) => { + try { + return JSON.stringify(new XRayFormattedCause(err)); + } catch (err) { + return ''; + } +}; + +/** + * prepare an exception blob for sending to AWS X-Ray + * adapted from https://code.amazon.com/packages/AWSTracingSDKNode/blobs/c917508ca4fce6a795f95dc30c91b70c6bc6c617/--/core/lib/segments/attributes/captured_exception.js + * transform an Error, or Error-like, into an exception parseable by X-Ray's service. + * { + * "name": "CustomException", + * "message": "Something bad happend!", + * "stack": [ + * "exports.handler (/var/task/node_modules/event_invoke.js:3:502) + * ] + * } + * => + * { + * "working_directory": "/var/task", + * "exceptions": [ + * { + * "type": "CustomException", + * "message": "Something bad happend!", + * "stack": [ + * { + * "path": "/var/task/event_invoke.js", + * "line": 502, + * "label": "exports.throw_custom_exception" + * } + * ] + * } + * ], + * "paths": [ + * "/var/task/event_invoke.js" + * ] + * } + */ +class XRayFormattedCause { + constructor(err) { + this.working_directory = process.cwd(); // eslint-disable-line + + let stack = []; + if (err.stack) { + let stackLines = err.stack.replace(/\x7F/g, '%7F').split('\n'); + stackLines.shift(); + + stackLines.forEach((stackLine) => { + let line = stackLine.trim().replace(/\(|\)/g, ''); + line = line.substring(line.indexOf(' ') + 1); + + let label = + line.lastIndexOf(' ') >= 0 + ? line.slice(0, line.lastIndexOf(' ')) + : null; + let path = + label == undefined || label == null || label.length === 0 + ? line + : line.slice(line.lastIndexOf(' ') + 1); + path = path.split(':'); + + let entry = { + path: path[0], + line: parseInt(path[1]), + label: label || 'anonymous', + }; + + stack.push(entry); + }); + } + + this.exceptions = [ + { + type: err.name?.replace(/\x7F/g, '%7F'), + message: err.message?.replace(/\x7F/g, '%7F'), + stack: stack, + }, + ]; + + let paths = new Set(); + stack.forEach((entry) => { + paths.add(entry.path); + }); + this.paths = Array.from(paths); + } +} diff --git a/src/build.js b/src/build.js new file mode 100644 index 00000000..cb7baf48 --- /dev/null +++ b/src/build.js @@ -0,0 +1,49 @@ +/** + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +const { build } = require('esbuild'); +const fs = require('fs'); + +const shared = { + bundle: true, + entryPoints: ['index.mjs'], + external: ['./rapid-client.node'], + logLevel: 'info', + minify: false, + platform: 'node', + format: 'esm', + charset: 'utf8', + banner: { + js: `/** Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. */\nimport { createRequire } from \"module\";\nconst require = createRequire(import.meta.url);`, + }, +}; + +const buildOneSet = (target) => { + build({ + ...shared, + outfile: `../dist/index.mjs`, + target, + }); + + // Keep backward compatibility for Node14 + if (process.version.startsWith('v14')) { + build({ + ...shared, + format: 'cjs', + entryPoints: ['UserFunction.js'], + banner: { + js: '(function (){', + }, + footer: { + js: '})();', + }, + outfile: `../dist/UserFunction.js`, + target, + }); + } +}; + +buildOneSet('node14.21.3'); diff --git a/src/index.mjs b/src/index.mjs new file mode 100755 index 00000000..dd1d193e --- /dev/null +++ b/src/index.mjs @@ -0,0 +1,55 @@ +/** + * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * This module is the bootstrap entrypoint. It establishes the top-level event + * listeners and loads the user's code. + */ + +const RAPIDClient = require('./RAPIDClient.js'); +const Runtime = require('./Runtime.js'); +const UserFunction = require('./UserFunction.js'); +const Errors = require('./Errors.js'); +const BeforeExitListener = require('./BeforeExitListener.js'); +const LogPatch = require('./LogPatch'); +const { checkForDeprecatedCallback } = require('./WarningForCallbackHandlers'); + +export async function run(appRootOrHandler, handler = '') { + LogPatch.patchConsole(); + const client = new RAPIDClient(process.env.AWS_LAMBDA_RUNTIME_API); + + let errorCallbacks = { + uncaughtException: (error) => { + client.postInitError(error, () => process.exit(129)); + }, + unhandledRejection: (error) => { + client.postInitError(error, () => process.exit(128)); + }, + }; + + process.on('uncaughtException', (error) => { + LogPatch.structuredConsole.logError('Uncaught Exception', error); + errorCallbacks.uncaughtException(error); + }); + + process.on('unhandledRejection', (reason, promise) => { + let error = new Errors.UnhandledPromiseRejection(reason, promise); + LogPatch.structuredConsole.logError('Unhandled Promise Rejection', error); + errorCallbacks.unhandledRejection(error); + }); + + BeforeExitListener.reset(); + process.on('beforeExit', BeforeExitListener.invoke); + + const handlerFunc = UserFunction.isHandlerFunction(appRootOrHandler) + ? appRootOrHandler + : await UserFunction.load(appRootOrHandler, handler); + + const metadata = UserFunction.getHandlerMetadata(handlerFunc); + checkForDeprecatedCallback(metadata); + new Runtime( + client, + handlerFunc, + metadata, + errorCallbacks, + ).scheduleIteration(); +} diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index 336c1cad..00000000 --- a/src/index.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* eslint-disable no-console */ -/** - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * This module is the bootstrap entrypoint. It establishes the top-level event - * listeners and loads the user's code. - */ - -"use strict"; - -import { HandlerFunction } from "./Common"; -import * as Errors from "./Errors"; -import RuntimeClient from "./RuntimeClient"; -import Runtime from "./Runtime"; -import BeforeExitListener from "./Runtime/BeforeExitListener"; -import LogPatch from "./utils/LogPatch"; -import * as UserFunction from "./utils/UserFunction"; - -LogPatch.patchConsole(); - -export function run(appRoot: string, handler: string): void { - if (!process.env.AWS_LAMBDA_RUNTIME_API) { - throw new Error("Missing Runtime API Server configuration."); - } - const client = new RuntimeClient(process.env.AWS_LAMBDA_RUNTIME_API); - - const errorCallbacks = { - uncaughtException: (error: Error) => { - client.postInitError(error, () => process.exit(129)); - }, - unhandledRejection: (error: Error) => { - client.postInitError(error, () => process.exit(128)); - }, - }; - - process.on("uncaughtException", (error) => { - console.error("Uncaught Exception", Errors.toFormatted(error)); - errorCallbacks.uncaughtException(error); - }); - - process.on("unhandledRejection", (reason, promise) => { - const error = new Errors.UnhandledPromiseRejection( - reason?.toString(), - promise - ); - console.error("Unhandled Promise Rejection", Errors.toFormatted(error)); - errorCallbacks.unhandledRejection(error); - }); - - BeforeExitListener.reset(); - process.on("beforeExit", BeforeExitListener.invoke); - - const handlerFunc = UserFunction.load(appRoot, handler) as HandlerFunction; - const runtime = new Runtime(client, handlerFunc, errorCallbacks); - - runtime.scheduleIteration(); -} diff --git a/src/rapid-client.cc b/src/rapid-client.cc new file mode 100644 index 00000000..aea0b1d7 --- /dev/null +++ b/src/rapid-client.cc @@ -0,0 +1,161 @@ +/* + * Copyright 2019-present Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include +#include "aws/lambda-runtime/runtime.h" +#include "napi.h" +#include +#include +#include +#include + +static const std::string ENDPOINT(getenv("AWS_LAMBDA_RUNTIME_API")); +static aws::lambda_runtime::runtime CLIENT(ENDPOINT); + +// Napi::AsyncWorker docs: https://github.com/nodejs/node-addon-api/blob/main/doc/async_worker.md +class RuntimeApiNextPromiseWorker : public Napi::AsyncWorker { +public: + RuntimeApiNextPromiseWorker(Napi::Env &env) + : Napi::AsyncWorker(env), response(), deferred(Napi::Promise::Deferred::New(env)) {} + + ~RuntimeApiNextPromiseWorker() {} + + void Execute() override { + auto outcome = CLIENT.get_next(); + if (!outcome.is_success()) { + std::string err = "Failed to get next invocation, error "; + err.append(std::to_string(static_cast(outcome.get_failure()))); + SetError(err); + return; + } + + // TODO: See if json parsing works on V8:Buffer objects, which might be a way to reduce copying large payloads + response = outcome.get_result(); + } + + Napi::Value Promise() { + return deferred.Promise(); + } + + void OnOK() override { + Napi::Env env = Env(); + auto response_data = Napi::String::New(env, response.payload.c_str()); + + // TODO: The current javascript code (InvokeContext.js) to handle the header values itself. + // These type conversions might be replaced by returning the final context object. + auto headers = Napi::Object::New(env); + headers.Set( + Napi::String::New(env, "lambda-runtime-deadline-ms"), + Napi::Number::New(env, + std::chrono::duration_cast( + response.deadline.time_since_epoch() + ).count() + )); + headers.Set( + Napi::String::New(env, "lambda-runtime-aws-request-id"), + Napi::String::New(env, response.request_id.c_str())); + headers.Set( + Napi::String::New(env, "lambda-runtime-trace-id"), + Napi::String::New(env, response.xray_trace_id.c_str())); + headers.Set( + Napi::String::New(env, "lambda-runtime-invoked-function-arn"), + Napi::String::New(env, response.function_arn.c_str())); + if (response.client_context != "") { + headers.Set( + Napi::String::New(env, "lambda-runtime-client-context"), + Napi::String::New(env, response.client_context.c_str())); + } + if (response.cognito_identity != "") { + headers.Set( + Napi::String::New(env, "lambda-runtime-cognito-identity"), + Napi::String::New(env, response.cognito_identity.c_str())); + } + if (response.tenant_id != "") { + headers.Set( + Napi::String::New(env, "lambda-runtime-aws-tenant-id"), + Napi::String::New(env, response.tenant_id.c_str())); + } + + auto ret = Napi::Object::New(env); + ret.Set(Napi::String::New(env, "bodyJson"), response_data); + ret.Set(Napi::String::New(env, "headers"), headers); + + deferred.Resolve(ret); + } + + void OnError(Napi::Error const &error) override { + deferred.Reject(error.Value()); + } + +private: + aws::lambda_runtime::invocation_request response; + Napi::Promise::Deferred deferred; +}; + + +Napi::Value Next(const Napi::CallbackInfo & info) +{ + Napi::Env env = info.Env(); + RuntimeApiNextPromiseWorker *nextWorker = new RuntimeApiNextPromiseWorker(env); + nextWorker->Queue(); + return nextWorker->Promise(); +} + +Napi::Value Done(const Napi::CallbackInfo & info) +{ + Napi::Env env = info.Env(); + if (info.Length() < 2) { + Napi::TypeError::New(env, "Wrong number of arguments, expected 2").ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsString() || !info[1].IsString()) { + Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + auto requestId = info[0].As(); + auto responseString = info[1].As(); + auto response = aws::lambda_runtime::invocation_response::success(responseString.Utf8Value(), "application/json"); + auto outcome = CLIENT.post_success(requestId.Utf8Value(), response); + return env.Null(); +} + +Napi::Value Error(const Napi::CallbackInfo & info) +{ + Napi::Env env = info.Env(); + if (info.Length() < 3) { + Napi::TypeError::New(env, "Wrong number of arguments, expected 3").ThrowAsJavaScriptException(); + return env.Null(); + } + if (!info[0].IsString() || !info[1].IsString() || !info[2].IsString()) { + Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException(); + return env.Null(); + } + auto requestId = info[0].As(); + auto responseString = info[1].As(); + auto xrayResponse = info[2].As(); + auto response = aws::lambda_runtime::invocation_response(responseString.Utf8Value(), "application/json", false, xrayResponse.Utf8Value()); + auto outcome = CLIENT.post_failure(requestId.Utf8Value(), response); + return env.Null(); +} + +Napi::Object Init(Napi::Env env, Napi::Object exports) +{ + exports.Set(Napi::String::New(env, "next"), Napi::Function::New(env, Next)); + exports.Set(Napi::String::New(env, "done"), Napi::Function::New(env, Done)); + exports.Set(Napi::String::New(env, "error"), Napi::Function::New(env, Error)); + return exports; +} + +NODE_API_MODULE(addon, Init); diff --git a/src/tsconfig.json b/src/tsconfig.json deleted file mode 100644 index 8888b7ee..00000000 --- a/src/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "../tsconfig-base.json", - "compilerOptions": { - "outDir": "../lib" - } -} \ No newline at end of file diff --git a/src/types/awslambda.d.ts b/src/types/awslambda.d.ts new file mode 100644 index 00000000..1c5153ed --- /dev/null +++ b/src/types/awslambda.d.ts @@ -0,0 +1,10 @@ +export class HttpResponseStream { + static from(underlyingStream: any, prelude: any): any; +} + +declare global { + namespace awslambda { + function streamifyResponse(handler: any, options: any): any; + let HttpResponseStream: HttpResponseStream; + } +} \ No newline at end of file diff --git a/src/types/index.d.mts b/src/types/index.d.mts new file mode 100644 index 00000000..e08f6b0d --- /dev/null +++ b/src/types/index.d.mts @@ -0,0 +1 @@ +export function run(appRootOrHandler: any, handler?: string): Promise; \ No newline at end of file diff --git a/src/utils/LogPatch.ts b/src/utils/LogPatch.ts deleted file mode 100644 index bec949da..00000000 --- a/src/utils/LogPatch.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable no-console */ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -import * as fs from "fs"; -import * as util from "util"; - -const levels = Object.freeze({ - INFO: { name: "INFO" }, - DEBUG: { name: "DEBUG" }, - WARN: { name: "WARN" }, - ERROR: { name: "ERROR" }, - TRACE: { name: "TRACE" }, - FATAL: { name: "FATAL" }, -}); - -/* Use a unique symbol to provide global access without risk of name clashes. */ -const REQUEST_ID_SYMBOL = Symbol.for("aws.lambda.runtime.requestId"); -const _currentRequestId = { - get: () => (global as any)[REQUEST_ID_SYMBOL], - set: (id: any) => ((global as any)[REQUEST_ID_SYMBOL] = id), -}; - -/** - * Write logs to stdout. - */ -const _logToStdout = (level: any, message: any) => { - const time = new Date().toISOString(); - const requestId = _currentRequestId.get(); - let line = `${time}\t${requestId}\t${level.name}\t${message}`; - line = line.replace(/\n/g, "\r"); - process.stdout.write(line + "\n"); -}; - -/** - * Write logs to filedescriptor. - * Implements the logging contract between runtimes and the platform. - * Each entry is framed as: - * +----------------------+------------------------+-----------------------+ - * | Frame Type - 4 bytes | Length (len) - 4 bytes | Message - 'len' bytes | - * +----------------------+------------------------+-----------------------+ - * The frist 4 bytes are the frame type. For logs this is always 0xa55a0001. - * The second 4 bytes are the length of the message. - * The remaining bytes ar ethe message itself. Byte order is big-endian. - */ -const _logToFd = function (logTarget: any) { - const typeAndLength = Buffer.alloc(8); - typeAndLength.writeUInt32BE(0xa55a0001, 0); - typeAndLength.writeUInt32BE(0x00000000, 4); - - return (level: any, message: any) => { - const time = new Date().toISOString(); - const requestId = _currentRequestId.get(); - const enrichedMessage = `${time}\t${requestId}\t${level.name}\t${message}\n`; - const messageBytes = Buffer.from(enrichedMessage, "utf8"); - typeAndLength.writeInt32BE(messageBytes.length, 4); - fs.writeSync(logTarget, typeAndLength); - fs.writeSync(logTarget, messageBytes); - }; -}; - -/** - * Replace console functions with a log function. - * @param {Function(level, String)} log - */ -function _patchConsoleWith(log: any) { - console.log = (msg, ...params) => { - log(levels.INFO, util.format(msg, ...params)); - }; - console.debug = (msg, ...params) => { - log(levels.DEBUG, util.format(msg, ...params)); - }; - console.info = (msg, ...params) => { - log(levels.INFO, util.format(msg, ...params)); - }; - console.warn = (msg, ...params) => { - log(levels.WARN, util.format(msg, ...params)); - }; - console.error = (msg, ...params) => { - log(levels.ERROR, util.format(msg, ...params)); - }; - console.trace = (msg, ...params) => { - log(levels.TRACE, util.format(msg, ...params)); - }; - (console as any).fatal = (msg: any, ...params: any[]) => { - log(levels.FATAL, util.format(msg, ...params)); - }; -} - -const _patchConsole = (): void => { - if ( - process.env["_LAMBDA_TELEMETRY_LOG_FD"] != null && - process.env["_LAMBDA_TELEMETRY_LOG_FD"] != undefined - ) { - const logFd = parseInt(process.env["_LAMBDA_TELEMETRY_LOG_FD"]); - _patchConsoleWith(_logToFd(logFd)); - delete process.env["_LAMBDA_TELEMETRY_LOG_FD"]; - } else { - _patchConsoleWith(_logToStdout); - } -}; - -export default { - setCurrentRequestId: _currentRequestId.set, - patchConsole: _patchConsole, -}; diff --git a/src/utils/UserFunction.ts b/src/utils/UserFunction.ts deleted file mode 100644 index cf39e07d..00000000 --- a/src/utils/UserFunction.ts +++ /dev/null @@ -1,165 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/** - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * This module defines the functions for loading the user's code as specified - * in a handler string. - */ - -"use strict"; - -import path from "path"; -import fs from "fs"; -import { HandlerFunction } from "../Common"; -import { - HandlerNotFound, - MalformedHandlerName, - ImportModuleError, - UserCodeSyntaxError, -} from "../Errors"; - -const FUNCTION_EXPR = /^([^.]*)\.(.*)$/; -const RELATIVE_PATH_SUBSTRING = ".."; - -/** - * Break the full handler string into two pieces, the module root and the actual - * handler string. - * Given './somepath/something/module.nestedobj.handler' this returns - * ['./somepath/something', 'module.nestedobj.handler'] - */ -function _moduleRootAndHandler(fullHandlerString: string): [string, string] { - const handlerString = path.basename(fullHandlerString); - const moduleRoot = fullHandlerString.substring( - 0, - fullHandlerString.indexOf(handlerString) - ); - return [moduleRoot, handlerString]; -} - -/** - * Split the handler string into two pieces: the module name and the path to - * the handler function. - */ -function _splitHandlerString(handler: string): [string, string] { - const match = handler.match(FUNCTION_EXPR); - if (!match || match.length != 3) { - throw new MalformedHandlerName("Bad handler"); - } - return [match[1], match[2]]; // [module, function-path] -} - -/** - * Resolve the user's handler function from the module. - */ -function _resolveHandler(object: any, nestedProperty: string): any { - return nestedProperty.split(".").reduce((nested, key) => { - return nested && nested[key]; - }, object); -} - -/** - * Verify that the provided path can be loaded as a file per: - * https://nodejs.org/dist/latest-v10.x/docs/api/modules.html#modules_all_together - * @param string - the fully resolved file path to the module - * @return bool - */ -function _canLoadAsFile(modulePath: string): boolean { - return fs.existsSync(modulePath) || fs.existsSync(modulePath + ".js"); -} - -/** - * Attempt to load the user's module. - * Attempts to directly resolve the module relative to the application root, - * then falls back to the more general require(). - */ -function _tryRequire(appRoot: string, moduleRoot: string, module: string): any { - const lambdaStylePath = path.resolve(appRoot, moduleRoot, module); - if (_canLoadAsFile(lambdaStylePath)) { - return require(lambdaStylePath); - } else { - // Why not just require(module)? - // Because require() is relative to __dirname, not process.cwd() - const nodeStylePath = require.resolve(module, { - paths: [appRoot, moduleRoot], - }); - return require(nodeStylePath); - } -} - -/** - * Load the user's application or throw a descriptive error. - * @throws Runtime errors in two cases - * 1 - UserCodeSyntaxError if there's a syntax error while loading the module - * 2 - ImportModuleError if the module cannot be found - */ -function _loadUserApp( - appRoot: string, - moduleRoot: string, - module: string -): any { - try { - return _tryRequire(appRoot, moduleRoot, module); - } catch (e) { - if (e instanceof SyntaxError) { - throw new UserCodeSyntaxError(e); - } else if (e.code !== undefined && e.code === "MODULE_NOT_FOUND") { - throw new ImportModuleError(e); - } else { - throw e; - } - } -} - -function _throwIfInvalidHandler(fullHandlerString: string): void { - if (fullHandlerString.includes(RELATIVE_PATH_SUBSTRING)) { - throw new MalformedHandlerName( - `'${fullHandlerString}' is not a valid handler name. Use absolute paths when specifying root directories in handler names.` - ); - } -} - -/** - * Load the user's function with the approot and the handler string. - * @param appRoot {string} - * The path to the application root. - * @param handlerString {string} - * The user-provided handler function in the form 'module.function'. - * @return userFuction {function} - * The user's handler function. This function will be passed the event body, - * the context object, and the callback function. - * @throws In five cases:- - * 1 - if the handler string is incorrectly formatted an error is thrown - * 2 - if the module referenced by the handler cannot be loaded - * 3 - if the function in the handler does not exist in the module - * 4 - if a property with the same name, but isn't a function, exists on the - * module - * 5 - the handler includes illegal character sequences (like relative paths - * for traversing up the filesystem '..') - * Errors for scenarios known by the runtime, will be wrapped by Runtime.* errors. - */ -export const load = function ( - appRoot: string, - fullHandlerString: string -): HandlerFunction { - _throwIfInvalidHandler(fullHandlerString); - - const [moduleRoot, moduleAndHandler] = _moduleRootAndHandler( - fullHandlerString - ); - const [module, handlerPath] = _splitHandlerString(moduleAndHandler); - - const userApp = _loadUserApp(appRoot, moduleRoot, module); - const handlerFunc = _resolveHandler(userApp, handlerPath); - - if (!handlerFunc) { - throw new HandlerNotFound( - `${fullHandlerString} is undefined or not exported` - ); - } - - if (typeof handlerFunc !== "function") { - throw new HandlerNotFound(`${fullHandlerString} is not a function`); - } - - return handlerFunc; -}; diff --git a/test/handlers/asyncInit.mjs b/test/handlers/asyncInit.mjs new file mode 100644 index 00000000..b8fb8488 --- /dev/null +++ b/test/handlers/asyncInit.mjs @@ -0,0 +1,11 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +let awaited = false; + +awaited = await new Promise((resolve) => setTimeout(() => resolve(true), 900)); + +export const handler = async () => { + if (!awaited) { + throw new Error('The async initialization of this module was not awaited!'); + } + return 'Hi'; +}; diff --git a/test/handlers/asyncInitRejection.mjs b/test/handlers/asyncInitRejection.mjs new file mode 100644 index 00000000..ebc6926d --- /dev/null +++ b/test/handlers/asyncInitRejection.mjs @@ -0,0 +1,26 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +let awaited = false; + +class AsyncInitRejectionException extends Error { + constructor(msg) { + super(msg); + this.name = this.constructor.name; + } +} + +awaited = await new Promise((_, reject) => + setTimeout( + () => + reject( + new AsyncInitRejectionException('Oh noes! something bad happened'), + ), + 900, + ), +); + +export const handler = async () => { + if (!awaited) { + throw new Error('The async initialization of this module was not awaited!'); + } + return 'Hi'; +}; diff --git a/test/handlers/async_init_package/cjsModuleInEsmPackage.js b/test/handlers/async_init_package/cjsModuleInEsmPackage.js new file mode 100644 index 00000000..af1bbf69 --- /dev/null +++ b/test/handlers/async_init_package/cjsModuleInEsmPackage.js @@ -0,0 +1,7 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +exports.echo = async (event) => { + return event; +}; diff --git a/test/handlers/async_init_package/index.js b/test/handlers/async_init_package/index.js new file mode 100644 index 00000000..b8fb8488 --- /dev/null +++ b/test/handlers/async_init_package/index.js @@ -0,0 +1,11 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ +let awaited = false; + +awaited = await new Promise((resolve) => setTimeout(() => resolve(true), 900)); + +export const handler = async () => { + if (!awaited) { + throw new Error('The async initialization of this module was not awaited!'); + } + return 'Hi'; +}; diff --git a/test/handlers/async_init_package/nested/even/more/index.js b/test/handlers/async_init_package/nested/even/more/index.js new file mode 100644 index 00000000..021c8188 --- /dev/null +++ b/test/handlers/async_init_package/nested/even/more/index.js @@ -0,0 +1,5 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +exports.handler = () => { + return 42; +}; diff --git a/test/handlers/async_init_package/nested/even/package.json b/test/handlers/async_init_package/nested/even/package.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/test/handlers/async_init_package/nested/even/package.json @@ -0,0 +1 @@ +{} diff --git a/test/handlers/async_init_package/nested/even/readme.txt b/test/handlers/async_init_package/nested/even/readme.txt new file mode 100644 index 00000000..6b63f607 --- /dev/null +++ b/test/handlers/async_init_package/nested/even/readme.txt @@ -0,0 +1 @@ +package.json exists and does not contain `type: "module"`. \ No newline at end of file diff --git a/test/handlers/async_init_package/nested/index.js b/test/handlers/async_init_package/nested/index.js new file mode 100644 index 00000000..bce62df5 --- /dev/null +++ b/test/handlers/async_init_package/nested/index.js @@ -0,0 +1,7 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +await new Promise((r) => setTimeout(r, 100)); + +export const handler = async () => { + return 42; +}; diff --git a/test/handlers/async_init_package/package.json b/test/handlers/async_init_package/package.json new file mode 100644 index 00000000..3680116d --- /dev/null +++ b/test/handlers/async_init_package/package.json @@ -0,0 +1,12 @@ +{ + "name": "async-init-package-test", + "version": "1.0.0", + "description": "dummy package for the loading esm packages", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "AWS Lambda", + "license": "Apache-2.0" +} diff --git a/test/handlers/async_init_type_not_module/index.js b/test/handlers/async_init_type_not_module/index.js new file mode 100644 index 00000000..315d2f3c --- /dev/null +++ b/test/handlers/async_init_type_not_module/index.js @@ -0,0 +1,7 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +exports.ret42 = () => { + return 42; +}; diff --git a/test/handlers/async_init_type_not_module/package.json b/test/handlers/async_init_type_not_module/package.json new file mode 100644 index 00000000..f82e3d8e --- /dev/null +++ b/test/handlers/async_init_type_not_module/package.json @@ -0,0 +1,3 @@ +{ + "type": "Ceci n’est pas une module" +} diff --git a/test/handlers/async_init_with_node_modules/node_modules/index.js b/test/handlers/async_init_with_node_modules/node_modules/index.js new file mode 100644 index 00000000..53494e43 --- /dev/null +++ b/test/handlers/async_init_with_node_modules/node_modules/index.js @@ -0,0 +1,7 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +"use strict"; + +exports.ret42 = () => { + return 42; +}; diff --git a/test/handlers/async_init_with_node_modules/package.json b/test/handlers/async_init_with_node_modules/package.json new file mode 100644 index 00000000..3680116d --- /dev/null +++ b/test/handlers/async_init_with_node_modules/package.json @@ -0,0 +1,12 @@ +{ + "name": "async-init-package-test", + "version": "1.0.0", + "description": "dummy package for the loading esm packages", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "AWS Lambda", + "license": "Apache-2.0" +} diff --git a/test/handlers/beforeExitBehaviour.js b/test/handlers/beforeExitBehaviour.js new file mode 100644 index 00000000..df5c6aac --- /dev/null +++ b/test/handlers/beforeExitBehaviour.js @@ -0,0 +1,24 @@ +/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +process.on('beforeExit', () => { + setImmediate(() => console.log('from setImmediate')); +}); + +process.on('beforeExit', () => { + process.nextTick(() => console.log('from process.nextTick')); +}); + +exports.callbackWithTrueFlag = (_event, _cxt, callback) => { + callback(null, 'hello'); +}; + +exports.callbackWithFalseFlag = (_event, cxt, callback) => { + cxt.callbackWaitsForEmptyEventLoop = false; + callback(null, 'hello'); +}; + +exports.asyncFunction = async (_event) => { + return 'hello'; +}; diff --git a/test/handlers/cjsModule.cjs b/test/handlers/cjsModule.cjs new file mode 100644 index 00000000..f43705d8 --- /dev/null +++ b/test/handlers/cjsModule.cjs @@ -0,0 +1,5 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +exports.echo = async (event) => { + return event; +}; diff --git a/test/handlers/core.js b/test/handlers/core.js new file mode 100644 index 00000000..962252c1 --- /dev/null +++ b/test/handlers/core.js @@ -0,0 +1,39 @@ +/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +exports.workingDirectory = async () => process.cwd(); + +exports.echo = async (event) => { + return event; +}; + +exports.ping = async (event) => { + return { + msg: `pong[${event['msg']}]`, + }; +}; + +exports.env = async () => { + return process.env; +}; + +exports.clientContext = async (_, ctx) => { + return ctx.clientContext; +}; + +exports.cognitoIdentity = async (_, _ctx) => { + return context.identity; +}; + +exports.nodePathContainsMajorVersion = async () => { + let majorVersion = process.version.match(/(\d+)/g)[0]; + let expectedNodeString = `node${majorVersion}`; + let nodePath = process.env['NODE_PATH']; + + console.log(nodePath, 'should include', expectedNodeString); + + return { + nodePathIncludesMajorVersion: nodePath.includes(expectedNodeString), + }; +}; diff --git a/test/handlers/defaultHandler.js b/test/handlers/defaultHandler.js new file mode 100644 index 00000000..9f260242 --- /dev/null +++ b/test/handlers/defaultHandler.js @@ -0,0 +1,7 @@ +/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +module.exports = { + default: () => 42, +}; diff --git a/test/handlers/defaultHandlerESM.mjs b/test/handlers/defaultHandlerESM.mjs new file mode 100644 index 00000000..bb46151c --- /dev/null +++ b/test/handlers/defaultHandlerESM.mjs @@ -0,0 +1,3 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +export default () => 42; diff --git a/test/handlers/esModule.mjs b/test/handlers/esModule.mjs new file mode 100644 index 00000000..e44d0ea3 --- /dev/null +++ b/test/handlers/esModule.mjs @@ -0,0 +1,5 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +export const echo = async (event) => { + return event; +}; diff --git a/test/handlers/esModuleImports.mjs b/test/handlers/esModuleImports.mjs new file mode 100644 index 00000000..c9179e90 --- /dev/null +++ b/test/handlers/esModuleImports.mjs @@ -0,0 +1,19 @@ +/** Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +import { echo as esModuleEcho } from './esModule.mjs'; +import * as util from 'util'; +import { Buffer } from 'buffer'; +import defaultExport from './defaultHandlerESM.mjs'; + +export const echo = async (event) => { + // Use an arbitrary internal node module, with import star. + console.log(util.format('can import node module: %s+%s', 'yes', 'yes')); + + // Use an arbitrary internal node module. + console.log(Buffer.from('yes')); + + // Use an arbitrary default export. + console.log(defaultExport()); + + return esModuleEcho(event); +}; diff --git a/test/handlers/extensionless/esm-extensionless b/test/handlers/extensionless/esm-extensionless new file mode 100644 index 00000000..537c57b1 --- /dev/null +++ b/test/handlers/extensionless/esm-extensionless @@ -0,0 +1,6 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +// This should fail because it's ESM syntax in a CJS context +export const handler = async (event) => { + return "This should fail"; +}; diff --git a/test/handlers/extensionless/index b/test/handlers/extensionless/index new file mode 100644 index 00000000..00b048de --- /dev/null +++ b/test/handlers/extensionless/index @@ -0,0 +1,8 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; +// This is a CommonJS module without file extension + +module.exports.handler = async (event) => { + return "Hello from extensionless CJS"; +}; diff --git a/test/handlers/isAsync.mjs b/test/handlers/isAsync.mjs new file mode 100644 index 00000000..03383932 --- /dev/null +++ b/test/handlers/isAsync.mjs @@ -0,0 +1,20 @@ +/* +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +export const handlerAsync = async () => { + const response = { + statusCode: 200, + body: JSON.stringify('Hello from Lambda!'), + }; + return response; +}; + +export const handlerNotAsync = () => { + const response = { + statusCode: 200, + body: JSON.stringify('Hello from Lambda!'), + }; + return response; +}; diff --git a/test/handlers/isAsyncCallback.js b/test/handlers/isAsyncCallback.js new file mode 100644 index 00000000..2c4f99c6 --- /dev/null +++ b/test/handlers/isAsyncCallback.js @@ -0,0 +1,12 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +exports.handler = (_event, _context, callback) => { + callback(null, { + statusCode: 200, + body: JSON.stringify({ + message: 'hello world', + }), + }); +}; \ No newline at end of file diff --git a/test/handlers/nestedHandler.js b/test/handlers/nestedHandler.js new file mode 100644 index 00000000..115feef5 --- /dev/null +++ b/test/handlers/nestedHandler.js @@ -0,0 +1,11 @@ +/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +module.exports = { + nested: { + somethingComplex: { + handler: async () => 'something interesting', + }, + }, +}; diff --git a/test/handlers/package-lock.json b/test/handlers/package-lock.json new file mode 100644 index 00000000..d667ecca --- /dev/null +++ b/test/handlers/package-lock.json @@ -0,0 +1,872 @@ +{ + "name": "handlers", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "handlers", + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "aws-serverless-express": "^3.3.6", + "body-parser": "^1.18.3", + "cors": "^2.8.5", + "express": "^4.16.4", + "function-bluebird": "file:./fake_node_modules/function-bluebird", + "not-shadowed": "file:./fake_node_modules/not-shadowed", + "precedence": "file:./fake_node_modules/precedence" + }, + "devDependencies": {} + }, + "fake_node_modules/function-bluebird": {}, + "fake_node_modules/not-shadowed": {}, + "fake_node_modules/precedence": {}, + "node_modules/@vendia/serverless-express": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@vendia/serverless-express/-/serverless-express-3.4.0.tgz", + "integrity": "sha512-/UAAbi9qRjUtjRISt5MJ1sfhtrHb26hqQ0nvE5qhMLsAdR5H7ErBwPD8Q/v2OENKm0iWsGwErIZEg7ebUeFDjQ==", + "dependencies": { + "binary-case": "^1.0.0", + "type-is": "^1.6.16" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/aws-serverless-express": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/aws-serverless-express/-/aws-serverless-express-3.4.0.tgz", + "integrity": "sha512-YG9ZjAOI9OpwqDDWzkRc3kKJYJuR7gTMjLa3kAWopO17myoprxskCUyCEee+RKe34tcR4UNrVtgAwW5yDe74bw==", + "dependencies": { + "@vendia/serverless-express": "^3.4.0", + "binary-case": "^1.0.0", + "type-is": "^1.6.16" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/binary-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/binary-case/-/binary-case-1.1.4.tgz", + "integrity": "sha512-9Kq8m6NZTAgy05Ryuh7U3Qc4/ujLQU1AZ5vMw4cr3igTdi5itZC6kCNrRr2X8NzPiDn2oUIFTfa71DKMnue/Zg==" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-bluebird": { + "resolved": "fake_node_modules/function-bluebird", + "link": true + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/not-shadowed": { + "resolved": "fake_node_modules/not-shadowed", + "link": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/precedence": { + "resolved": "fake_node_modules/precedence", + "link": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/test/handlers/package.json b/test/handlers/package.json new file mode 100644 index 00000000..d03a227d --- /dev/null +++ b/test/handlers/package.json @@ -0,0 +1,63 @@ +{ + "name": "handlers", + "version": "1.0.0", + "description": "test handlers for nodes runtime project", + "main": "index.js", + "dependencies": { + "aws-serverless-express": "^3.3.6", + "body-parser": "^1.18.3", + "cors": "^2.8.5", + "express": "^4.16.4", + "function-bluebird": "file:./fake_node_modules/function-bluebird", + "not-shadowed": "file:./fake_node_modules/not-shadowed", + "precedence": "file:./fake_node_modules/precedence" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "AWS Lambda", + "license": "Apache-2.0", + "eslintConfig": { + "extends": [ + "plugin:prettier/recommended" + ], + "env": { + "node": true, + "mocha": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 2020 + }, + "rules": { + "strict": [ + "error", + "global" + ], + "indent": [ + "error", + 2 + ], + "camelcase": "error", + "no-console": "off", + "no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_" + } + ] + } + }, + "eslintIgnore": [ + "syntax_error.js", + "node_modules", + "async_init_package" + ], + "prettier": { + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true + } +} diff --git a/test/handlers/pkg-less/cjsAndMjs.js b/test/handlers/pkg-less/cjsAndMjs.js new file mode 100644 index 00000000..b3f2ec95 --- /dev/null +++ b/test/handlers/pkg-less/cjsAndMjs.js @@ -0,0 +1,9 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +import { someESMFunction } from './esmModule.js'; // ESM import + +module.exports.handler = async (event) => { // CJS export + return someESMFunction(event); +}; + +export const esm = 'This is ESM syntax'; // ESM export diff --git a/test/handlers/pkg-less/cjsImportCjs.js b/test/handlers/pkg-less/cjsImportCjs.js new file mode 100644 index 00000000..6ba9088d --- /dev/null +++ b/test/handlers/pkg-less/cjsImportCjs.js @@ -0,0 +1,9 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +const { getMessage } = require('./cjsModule.cjs') + +exports.handler = async (_event) => { + return getMessage(); +} diff --git a/test/handlers/pkg-less/cjsImportESM.cjs b/test/handlers/pkg-less/cjsImportESM.cjs new file mode 100644 index 00000000..76aa80f9 --- /dev/null +++ b/test/handlers/pkg-less/cjsImportESM.cjs @@ -0,0 +1,10 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +// This static import is not allowed in CJS +import { getMessage } from './esmModule'; + +module.exports.handler = async () => { + return getMessage(); +}; diff --git a/test/handlers/pkg-less/cjsInMjs.mjs b/test/handlers/pkg-less/cjsInMjs.mjs new file mode 100644 index 00000000..e331a104 --- /dev/null +++ b/test/handlers/pkg-less/cjsInMjs.mjs @@ -0,0 +1,8 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +// This should fail because it's CJS syntax in a ESM context +module.exports.handler = async (_event) => { + return 'This should fail'; +}; diff --git a/test/handlers/pkg-less/cjsModule.cjs b/test/handlers/pkg-less/cjsModule.cjs new file mode 100644 index 00000000..9ffea34d --- /dev/null +++ b/test/handlers/pkg-less/cjsModule.cjs @@ -0,0 +1,7 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +module.exports.getMessage = () => { + return "Hello from CJS!"; +}; diff --git a/test/handlers/pkg-less/esmImportCjs.mjs b/test/handlers/pkg-less/esmImportCjs.mjs new file mode 100644 index 00000000..6bccc872 --- /dev/null +++ b/test/handlers/pkg-less/esmImportCjs.mjs @@ -0,0 +1,7 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +import { getMessage } from './cjsModule.cjs'; + +export const handler = async (_event) => { + return getMessage(); +}; diff --git a/test/handlers/pkg-less/esmInCjs.cjs b/test/handlers/pkg-less/esmInCjs.cjs new file mode 100644 index 00000000..57f4769b --- /dev/null +++ b/test/handlers/pkg-less/esmInCjs.cjs @@ -0,0 +1,6 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +// This should fail because it's ESM syntax in a CJS context +export const handler = async (_event) => { + return 'This should fail'; +}; diff --git a/test/handlers/pkg-less/esmModule.js b/test/handlers/pkg-less/esmModule.js new file mode 100644 index 00000000..5c6aaf24 --- /dev/null +++ b/test/handlers/pkg-less/esmModule.js @@ -0,0 +1,9 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +export const handler = async (_event) => { + return 'Hello from ESM.js'; +}; + +export const getMessage = () => { + return "Hello from ESM!"; +}; diff --git a/test/handlers/pkg-less/esmRequireCjs.mjs b/test/handlers/pkg-less/esmRequireCjs.mjs new file mode 100644 index 00000000..e7d84f1d --- /dev/null +++ b/test/handlers/pkg-less/esmRequireCjs.mjs @@ -0,0 +1,7 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +const { getMessage } = require('./cjsModule.cjs') + +export const handler = async (_event) => { + return getMessage(); +}; diff --git a/test/handlers/pkg/type-cjs/cjs b/test/handlers/pkg/type-cjs/cjs new file mode 100644 index 00000000..00b048de --- /dev/null +++ b/test/handlers/pkg/type-cjs/cjs @@ -0,0 +1,8 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; +// This is a CommonJS module without file extension + +module.exports.handler = async (event) => { + return "Hello from extensionless CJS"; +}; diff --git a/test/handlers/pkg/type-cjs/cjsModule.js b/test/handlers/pkg/type-cjs/cjsModule.js new file mode 100644 index 00000000..0ef96cf3 --- /dev/null +++ b/test/handlers/pkg/type-cjs/cjsModule.js @@ -0,0 +1,7 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +module.exports.handler = async (_event) => { + return 'Hello from CJS.js'; +}; diff --git a/test/handlers/pkg/type-cjs/esm b/test/handlers/pkg/type-cjs/esm new file mode 100644 index 00000000..537c57b1 --- /dev/null +++ b/test/handlers/pkg/type-cjs/esm @@ -0,0 +1,6 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +// This should fail because it's ESM syntax in a CJS context +export const handler = async (event) => { + return "This should fail"; +}; diff --git a/test/handlers/pkg/type-cjs/esmModule.js b/test/handlers/pkg/type-cjs/esmModule.js new file mode 100644 index 00000000..57f4769b --- /dev/null +++ b/test/handlers/pkg/type-cjs/esmModule.js @@ -0,0 +1,6 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +// This should fail because it's ESM syntax in a CJS context +export const handler = async (_event) => { + return 'This should fail'; +}; diff --git a/test/handlers/pkg/type-cjs/package.json b/test/handlers/pkg/type-cjs/package.json new file mode 100644 index 00000000..5bbefffb --- /dev/null +++ b/test/handlers/pkg/type-cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/test/handlers/pkg/type-esm/cjs b/test/handlers/pkg/type-esm/cjs new file mode 100644 index 00000000..00b048de --- /dev/null +++ b/test/handlers/pkg/type-esm/cjs @@ -0,0 +1,8 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; +// This is a CommonJS module without file extension + +module.exports.handler = async (event) => { + return "Hello from extensionless CJS"; +}; diff --git a/test/handlers/pkg/type-esm/cjsModule.js b/test/handlers/pkg/type-esm/cjsModule.js new file mode 100644 index 00000000..e331a104 --- /dev/null +++ b/test/handlers/pkg/type-esm/cjsModule.js @@ -0,0 +1,8 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +// This should fail because it's CJS syntax in a ESM context +module.exports.handler = async (_event) => { + return 'This should fail'; +}; diff --git a/test/handlers/pkg/type-esm/esm b/test/handlers/pkg/type-esm/esm new file mode 100644 index 00000000..537c57b1 --- /dev/null +++ b/test/handlers/pkg/type-esm/esm @@ -0,0 +1,6 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +// This should fail because it's ESM syntax in a CJS context +export const handler = async (event) => { + return "This should fail"; +}; diff --git a/test/handlers/pkg/type-esm/esmModule.js b/test/handlers/pkg/type-esm/esmModule.js new file mode 100644 index 00000000..e0f37504 --- /dev/null +++ b/test/handlers/pkg/type-esm/esmModule.js @@ -0,0 +1,5 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +export const handler = async (_event) => { + return 'Hello from ESM.js'; +}; diff --git a/test/handlers/pkg/type-esm/package.json b/test/handlers/pkg/type-esm/package.json new file mode 100644 index 00000000..3dbc1ca5 --- /dev/null +++ b/test/handlers/pkg/type-esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test/handlers/precedence b/test/handlers/precedence new file mode 100644 index 00000000..eb8b4dea --- /dev/null +++ b/test/handlers/precedence @@ -0,0 +1,6 @@ +/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.*/ + +'use strict'; + +module.exports.handler = async () => "I don't have a .js file suffix"; + diff --git a/test/handlers/precedence.js b/test/handlers/precedence.js new file mode 100644 index 00000000..c150e3a4 --- /dev/null +++ b/test/handlers/precedence.js @@ -0,0 +1,5 @@ +/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +module.exports.handler = async () => 'I do have a .js file suffix'; diff --git a/test/handlers/precedence.json b/test/handlers/precedence.json new file mode 100644 index 00000000..9f7ede55 --- /dev/null +++ b/test/handlers/precedence.json @@ -0,0 +1,3 @@ +{ + "handler": "this should never be used" +} diff --git a/test/handlers/precedence.mjs b/test/handlers/precedence.mjs new file mode 100644 index 00000000..4f796375 --- /dev/null +++ b/test/handlers/precedence.mjs @@ -0,0 +1,5 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +module.exports.handler = async () => 'I do have a .mjs file suffix'; diff --git a/test/handlers/precedence.node b/test/handlers/precedence.node new file mode 100644 index 00000000..a88a4c5b --- /dev/null +++ b/test/handlers/precedence.node @@ -0,0 +1 @@ +this isn't actually a node extension diff --git a/test/handlers/precedenceJsVsMjs.js b/test/handlers/precedenceJsVsMjs.js new file mode 100644 index 00000000..3e7ea8e7 --- /dev/null +++ b/test/handlers/precedenceJsVsMjs.js @@ -0,0 +1,5 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +module.exports.handler = async () => 'I do have a .js file suffix'; diff --git a/test/handlers/precedenceJsVsMjs.mjs b/test/handlers/precedenceJsVsMjs.mjs new file mode 100644 index 00000000..5278ce03 --- /dev/null +++ b/test/handlers/precedenceJsVsMjs.mjs @@ -0,0 +1,5 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +export const handler = async () => 'I do have a .mjs file suffix'; diff --git a/test/handlers/precedenceMjsVsCjs.cjs b/test/handlers/precedenceMjsVsCjs.cjs new file mode 100644 index 00000000..42f425b4 --- /dev/null +++ b/test/handlers/precedenceMjsVsCjs.cjs @@ -0,0 +1,5 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +module.exports.handler = async () => 'I do have a .cjs file suffix'; diff --git a/test/handlers/precedenceMjsVsCjs.mjs b/test/handlers/precedenceMjsVsCjs.mjs new file mode 100644 index 00000000..5278ce03 --- /dev/null +++ b/test/handlers/precedenceMjsVsCjs.mjs @@ -0,0 +1,5 @@ +/** Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +export const handler = async () => 'I do have a .mjs file suffix'; diff --git a/test/integration/codebuild-local/Dockerfile.agent b/test/integration/codebuild-local/Dockerfile.agent deleted file mode 100644 index e9a9ffe5..00000000 --- a/test/integration/codebuild-local/Dockerfile.agent +++ /dev/null @@ -1,5 +0,0 @@ -FROM amazonlinux:2 - -RUN amazon-linux-extras enable docker && \ - yum clean metadata && \ - yum install -y docker tar diff --git a/test/integration/codebuild-local/codebuild_build.sh b/test/integration/codebuild-local/codebuild_build.sh deleted file mode 100755 index ffadfa30..00000000 --- a/test/integration/codebuild-local/codebuild_build.sh +++ /dev/null @@ -1,194 +0,0 @@ -#!/bin/bash -# This file is copied from https://github.com/aws/aws-codebuild-docker-images/blob/f0912e4b16e427da35351fc102f0f56f4ceb938a/local_builds/codebuild_build.sh - -function allOSRealPath() { - if isOSWindows - then - path="" - case $1 in - .* ) path="$PWD/${1#./}" ;; - /* ) path="$1" ;; - * ) path="/$1" ;; - esac - - echo "/$path" | sed -e 's/\\/\//g' -e 's/://' -e 's/./\U&/3' - else - case $1 in - /* ) echo "$1"; exit;; - * ) echo "$PWD/${1#./}"; exit;; - esac - fi -} - -function isOSWindows() { - if [ $OSTYPE == "msys" ] - then - return 0 - else - return 1 - fi -} - -function usage { - echo "usage: codebuild_build.sh [-i image_name] [-a artifact_output_directory] [options]" - echo "Required:" - echo " -i Used to specify the customer build container image." - echo " -a Used to specify an artifact output directory." - echo "Options:" - echo " -l IMAGE Used to override the default local agent image." - echo " -s Used to specify source information. Defaults to the current working directory for primary source." - echo " * First (-s) is for primary source" - echo " * Use additional (-s) in : format for secondary source" - echo " * For sourceIdentifier, use a value that is fewer than 128 characters and contains only alphanumeric characters and underscores" - echo " -c Use the AWS configuration and credentials from your local host. This includes ~/.aws and any AWS_* environment variables." - echo " -p Used to specify the AWS CLI Profile." - echo " -b FILE Used to specify a buildspec override file. Defaults to buildspec.yml in the source directory." - echo " -m Used to mount the source directory to the customer build container directly." - echo " -d Used to run the build container in docker privileged mode." - echo " -e FILE Used to specify a file containing environment variables." - echo " (-e) File format expectations:" - echo " * Each line is in VAR=VAL format" - echo " * Lines beginning with # are processed as comments and ignored" - echo " * Blank lines are ignored" - echo " * File can be of type .env or .txt" - echo " * There is no special handling of quotation marks, meaning they will be part of the VAL" - exit 1 -} - -image_flag=false -artifact_flag=false -awsconfig_flag=false -mount_src_dir_flag=false -docker_privileged_mode_flag=false - -while getopts "cmdi:a:s:b:e:l:p:h" opt; do - case $opt in - i ) image_flag=true; image_name=$OPTARG;; - a ) artifact_flag=true; artifact_dir=$OPTARG;; - b ) buildspec=$OPTARG;; - c ) awsconfig_flag=true;; - m ) mount_src_dir_flag=true;; - d ) docker_privileged_mode_flag=true;; - s ) source_dirs+=("$OPTARG");; - e ) environment_variable_file=$OPTARG;; - l ) local_agent_image=$OPTARG;; - p ) aws_profile=$OPTARG;; - h ) usage; exit;; - \? ) echo "Unknown option: -$OPTARG" >&2; exit 1;; - : ) echo "Missing option argument for -$OPTARG" >&2; exit 1;; - * ) echo "Invalid option: -$OPTARG" >&2; exit 1;; - esac -done - -if ! $image_flag -then - echo "The image name flag (-i) must be included for a build to run" >&2 -fi - -if ! $artifact_flag -then - echo "The artifact directory (-a) must be included for a build to run" >&2 -fi - -if ! $image_flag || ! $artifact_flag -then - exit 1 -fi - -docker_command="docker run " -if isOSWindows -then - docker_command+="-v //var/run/docker.sock:/var/run/docker.sock -e " -else - docker_command+="-v /var/run/docker.sock:/var/run/docker.sock -e " -fi - -docker_command+="\"IMAGE_NAME=$image_name\" -e \ - \"ARTIFACTS=$(allOSRealPath "$artifact_dir")\"" - -if [ -z "$source_dirs" ] -then - docker_command+=" -e \"SOURCE=$(allOSRealPath "$PWD")\"" -else - for index in "${!source_dirs[@]}"; do - if [ $index -eq 0 ] - then - docker_command+=" -e \"SOURCE=$(allOSRealPath "${source_dirs[$index]}")\"" - else - identifier=${source_dirs[$index]%%:*} - src_dir=$(allOSRealPath "${source_dirs[$index]#*:}") - - docker_command+=" -e \"SECONDARY_SOURCE_$index=$identifier:$src_dir\"" - fi - done -fi - -if [ -n "$buildspec" ] -then - docker_command+=" -e \"BUILDSPEC=$(allOSRealPath "$buildspec")\"" -fi - -if [ -n "$environment_variable_file" ] -then - environment_variable_file_path=$(allOSRealPath "$environment_variable_file") - environment_variable_file_dir=$(dirname "$environment_variable_file_path") - environment_variable_file_basename=$(basename "$environment_variable_file") - docker_command+=" -v \"$environment_variable_file_dir:/LocalBuild/envFile/\" -e \"ENV_VAR_FILE=$environment_variable_file_basename\"" -fi - -if [ -n "$local_agent_image" ] -then - docker_command+=" -e \"LOCAL_AGENT_IMAGE_NAME=$local_agent_image\"" -fi - -if $awsconfig_flag -then - if [ -d "$HOME/.aws" ] - then - configuration_file_path=$(allOSRealPath "$HOME/.aws") - docker_command+=" -e \"AWS_CONFIGURATION=$configuration_file_path\"" - else - docker_command+=" -e \"AWS_CONFIGURATION=NONE\"" - fi - - if [ -n "$aws_profile" ] - then - docker_command+=" -e \"AWS_PROFILE=$aws_profile\"" - fi - - docker_command+="$(env | grep ^AWS_ | while read -r line; do echo " -e \"$line\""; done )" -fi - -if $mount_src_dir_flag -then - docker_command+=" -e \"MOUNT_SOURCE_DIRECTORY=TRUE\"" -fi - -if $docker_privileged_mode_flag -then - docker_command+=" -e \"DOCKER_PRIVILEGED_MODE=TRUE\"" -fi - -if isOSWindows -then - docker_command+=" -e \"INITIATOR=$USERNAME\"" -else - docker_command+=" -e \"INITIATOR=$USER\"" -fi - -docker_command+=" amazon/aws-codebuild-local:latest" - -# Note we do not expose the AWS_SECRET_ACCESS_KEY or the AWS_SESSION_TOKEN -exposed_command=$docker_command -secure_variables=( "AWS_SECRET_ACCESS_KEY=" "AWS_SESSION_TOKEN=") -for variable in "${secure_variables[@]}" -do - exposed_command="$(echo $exposed_command | sed "s/\($variable\)[^ ]*/\1********\"/")" -done - -echo "Build Command:" -echo "" -echo $exposed_command -echo "" - -eval $docker_command diff --git a/test/integration/codebuild-local/test_all.sh b/test/integration/codebuild-local/test_all.sh deleted file mode 100755 index 0c5168cb..00000000 --- a/test/integration/codebuild-local/test_all.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - -set -euo pipefail - -CODEBUILD_IMAGE_TAG="${CODEBUILD_IMAGE_TAG:-al2/x86_64/standard/3.0}" -DRYRUN="${DRYRUN-0}" - -function usage { - echo "usage: test_all.sh buildspec_yml_dir" - echo "Runs all buildspec build-matrix combinations via test_one.sh." - echo "Required:" - echo " buildspec_yml_dir Used to specify the CodeBuild buildspec template file." -} - -do_one_yaml() { - local -r YML="$1" - - OS_DISTRIBUTION=$(grep -oE 'OS_DISTRIBUTION:\s*(\S+)' "$YML" | cut -d' ' -f2) - DISTRO_VERSIONS=$(sed '1,/DISTRO_VERSION/d;/RUNTIME_VERSION/,$d' "$YML" | tr -d '\-" ') - RUNTIME_VERSIONS=$(sed '1,/RUNTIME_VERSION/d;/phases/,$d' "$YML" | sed '/#.*$/d' | tr -d '\-" ') - - for DISTRO_VERSION in $DISTRO_VERSIONS ; do - for RUNTIME_VERSION in $RUNTIME_VERSIONS ; do - if (( DRYRUN == 1 )) ; then - echo DRYRUN test_one_combination "$YML" "$OS_DISTRIBUTION" "$DISTRO_VERSION" "$RUNTIME_VERSION" - else - test_one_combination "$YML" "$OS_DISTRIBUTION" "$DISTRO_VERSION" "$RUNTIME_VERSION" - fi - done - done -} - -test_one_combination() { - local -r YML="$1" - local -r OS_DISTRIBUTION="$2" - local -r DISTRO_VERSION="$3" - local -r RUNTIME_VERSION="$4" - - echo Testing: - echo " BUILDSPEC" "$YML" - echo " with" "$OS_DISTRIBUTION"-"$DISTRO_VERSION" "$RUNTIME_VERSION" - - "$(dirname "$0")"/test_one.sh "$YML" "$OS_DISTRIBUTION" "$DISTRO_VERSION" "$RUNTIME_VERSION" \ - > >(sed "s/^/$OS_DISTRIBUTION$DISTRO_VERSION-$RUNTIME_VERSION: /") 2> >(sed "s/^/$OS_DISTRIBUTION-$DISTRO_VERSION:$RUNTIME_VERSION: /" >&2) -} - -main() { - if (( $# != 1 && $# != 2)); then - >&2 echo "Invalid number of parameters." - usage - exit 1 - fi - - BUILDSPEC_YML_DIR="$1" - HAS_YML=0 - for f in "$BUILDSPEC_YML_DIR"/*.yml ; do - [ -f "$f" ] || continue; - do_one_yaml "$f" - HAS_YML=1 - done - - if (( HAS_YML == 0 )); then - >&2 echo At least one buildspec is required. - exit 2 - fi -} - -main "$@" diff --git a/test/integration/codebuild-local/test_one.sh b/test/integration/codebuild-local/test_one.sh deleted file mode 100755 index 22c2f90c..00000000 --- a/test/integration/codebuild-local/test_one.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - -set -euo pipefail - -CODEBUILD_IMAGE_TAG="${CODEBUILD_IMAGE_TAG:-al2/x86_64/standard/3.0}" - -function usage { - >&2 echo "usage: test_one.sh buildspec_yml os_distribution distro_version runtime_version [env]" - >&2 echo "Runs one buildspec version combination from a build-matrix buildspec." - >&2 echo "Required:" - >&2 echo " buildspec_yml Used to specify the CodeBuild buildspec template file." - >&2 echo " os_distribution Used to specify the OS distribution to build." - >&2 echo " distro_version Used to specify the distro version of ." - >&2 echo " runtime_version Used to specify the runtime version to test on the selected ." - >&2 echo "Optional:" - >&2 echo " env Additional environment variables file." -} - -main() { - if (( $# != 3 && $# != 4)); then - >&2 echo "Invalid number of parameters." - usage - exit 1 - fi - - BUILDSPEC_YML="$1" - OS_DISTRIBUTION="$2" - DISTRO_VERSION="$3" - RUNTIME_VERSION="$4" - EXTRA_ENV="${5-}" - - CODEBUILD_TEMP_DIR=$(mktemp -d codebuild."$OS_DISTRIBUTION"-"$DISTRO_VERSION"-"$RUNTIME_VERSION".XXXXXXXXXX) - trap 'rm -rf $CODEBUILD_TEMP_DIR' EXIT - - # Create an env file for codebuild_build. - ENVFILE="$CODEBUILD_TEMP_DIR/.env" - if [ -f "$EXTRA_ENV" ]; then - cat "$EXTRA_ENV" > "$ENVFILE" - fi - { - echo "" - echo "OS_DISTRIBUTION=$OS_DISTRIBUTION" - echo "DISTRO_VERSION=$DISTRO_VERSION" - echo "RUNTIME_VERSION=$RUNTIME_VERSION" - } >> "$ENVFILE" - - ARTIFACTS_DIR="$CODEBUILD_TEMP_DIR/artifacts" - mkdir -p "$ARTIFACTS_DIR" - - # Run CodeBuild local agent. - "$(dirname "$0")"/codebuild_build.sh \ - -i "$CODEBUILD_IMAGE_TAG" \ - -a "$ARTIFACTS_DIR" \ - -e "$ENVFILE" \ - -b "$BUILDSPEC_YML" -} - -main "$@" diff --git a/test/integration/codebuild/buildspec.os.alpine.1.yml b/test/integration/codebuild/buildspec.os.alpine.1.yml deleted file mode 100644 index 1cb927cf..00000000 --- a/test/integration/codebuild/buildspec.os.alpine.1.yml +++ /dev/null @@ -1,103 +0,0 @@ -version: 0.2 - -env: - variables: - OS_DISTRIBUTION: alpine - NPX_BINARY_LOCATION: "/usr/local/bin/npx" -batch: - build-matrix: - static: - ignore-failure: false - env: - type: LINUX_CONTAINER - privileged-mode: true - dynamic: - env: - variables: - DISTRO_VERSION: - - "3.10" - - "3.11" - RUNTIME_VERSION: - - "10" - - "12" - - "14" -phases: - pre_build: - commands: - - export IMAGE_TAG="nodejs-${OS_DISTRIBUTION}-${DISTRO_VERSION}:${RUNTIME_VERSION}" - - echo "Extracting and including the Runtime Interface Emulator" - - SCRATCH_DIR=".scratch" - - mkdir "${SCRATCH_DIR}" - - tar -xvf test/integration/resources/aws-lambda-rie.tar.gz --directory "${SCRATCH_DIR}" - - > - cp "test/integration/docker/Dockerfile.echo.${OS_DISTRIBUTION}" \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "RUN apk add curl" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "COPY ${SCRATCH_DIR}/aws-lambda-rie /usr/bin/aws-lambda-rie" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - if [[ -z "${DOCKERHUB_USERNAME}" && -z "${DOCKERHUB_PASSWORD}" ]]; - then - echo "DockerHub credentials not set as CodeBuild environment variables. Continuing without docker login." - else - echo "Performing DockerHub login . . ." - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - fi - - echo "Building image ${IMAGE_TAG}" - - > - docker build . \ - -f "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" \ - -t "${IMAGE_TAG}" \ - --build-arg RUNTIME_VERSION="${RUNTIME_VERSION}" \ - --build-arg DISTRO_VERSION="${DISTRO_VERSION}" - build: - commands: - - set -x - - echo "Running Image ${IMAGE_TAG}" - - docker network create "${OS_DISTRIBUTION}-network" - - > - docker run \ - --detach \ - -e "NPX_BINARY_LOCATION=${NPX_BINARY_LOCATION}" \ - --name "${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c '/usr/bin/aws-lambda-rie ${NPX_BINARY_LOCATION} aws-lambda-ric index.handler' - - sleep 2 - - > - docker run \ - --name "${OS_DISTRIBUTION}-tester" \ - --env "TARGET=${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10' - - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)" - - expected='success' - - | - echo "Response: ${actual}" - if [[ "$actual" != "$expected" ]]; then - echo "fail! runtime: $RUNTIME - expected output $expected - got $actual" - echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------" - echo - docker logs "${OS_DISTRIBUTION}-app" - echo - echo "---------------------------------------------------" - echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------" - echo - docker logs "${OS_DISTRIBUTION}-tester" - echo - echo "---------------------------------------------------" - exit -1 - fi - finally: - - echo "Cleaning up..." - - docker stop "${OS_DISTRIBUTION}-app" || true - - docker rm --force "${OS_DISTRIBUTION}-app" || true - - docker stop "${OS_DISTRIBUTION}-tester" || true - - docker rm --force "${OS_DISTRIBUTION}-tester" || true - - docker network rm "${OS_DISTRIBUTION}-network" || true \ No newline at end of file diff --git a/test/integration/codebuild/buildspec.os.alpine.2.yml b/test/integration/codebuild/buildspec.os.alpine.2.yml deleted file mode 100644 index d36ba583..00000000 --- a/test/integration/codebuild/buildspec.os.alpine.2.yml +++ /dev/null @@ -1,101 +0,0 @@ -version: 0.2 - -env: - variables: - OS_DISTRIBUTION: alpine - NPX_BINARY_LOCATION: "/usr/local/bin/npx" -batch: - build-matrix: - static: - ignore-failure: false - env: - type: LINUX_CONTAINER - privileged-mode: true - dynamic: - env: - variables: - DISTRO_VERSION: - - "3.12" - RUNTIME_VERSION: - - "12" - - "14" -phases: - pre_build: - commands: - - export IMAGE_TAG="nodejs-${OS_DISTRIBUTION}-${DISTRO_VERSION}:${RUNTIME_VERSION}" - - echo "Extracting and including the Runtime Interface Emulator" - - SCRATCH_DIR=".scratch" - - mkdir "${SCRATCH_DIR}" - - tar -xvf test/integration/resources/aws-lambda-rie.tar.gz --directory "${SCRATCH_DIR}" - - > - cp "test/integration/docker/Dockerfile.echo.${OS_DISTRIBUTION}" \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "RUN apk add curl" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "COPY ${SCRATCH_DIR}/aws-lambda-rie /usr/bin/aws-lambda-rie" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - if [[ -z "${DOCKERHUB_USERNAME}" && -z "${DOCKERHUB_PASSWORD}" ]]; - then - echo "DockerHub credentials not set as CodeBuild environment variables. Continuing without docker login." - else - echo "Performing DockerHub login . . ." - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - fi - - echo "Building image ${IMAGE_TAG}" - - > - docker build . \ - -f "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" \ - -t "${IMAGE_TAG}" \ - --build-arg RUNTIME_VERSION="${RUNTIME_VERSION}" \ - --build-arg DISTRO_VERSION="${DISTRO_VERSION}" - build: - commands: - - set -x - - echo "Running Image ${IMAGE_TAG}" - - docker network create "${OS_DISTRIBUTION}-network" - - > - docker run \ - --detach \ - -e "NPX_BINARY_LOCATION=${NPX_BINARY_LOCATION}" \ - --name "${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c '/usr/bin/aws-lambda-rie ${NPX_BINARY_LOCATION} aws-lambda-ric index.handler' - - sleep 2 - - > - docker run \ - --name "${OS_DISTRIBUTION}-tester" \ - --env "TARGET=${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10' - - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)" - - expected='success' - - | - echo "Response: ${actual}" - if [[ "$actual" != "$expected" ]]; then - echo "fail! runtime: $RUNTIME - expected output $expected - got $actual" - echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------" - echo - docker logs "${OS_DISTRIBUTION}-app" - echo - echo "---------------------------------------------------" - echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------" - echo - docker logs "${OS_DISTRIBUTION}-tester" - echo - echo "---------------------------------------------------" - exit -1 - fi - finally: - - echo "Cleaning up..." - - docker stop "${OS_DISTRIBUTION}-app" || true - - docker rm --force "${OS_DISTRIBUTION}-app" || true - - docker stop "${OS_DISTRIBUTION}-tester" || true - - docker rm --force "${OS_DISTRIBUTION}-tester" || true - - docker network rm "${OS_DISTRIBUTION}-network" || true \ No newline at end of file diff --git a/test/integration/codebuild/buildspec.os.alpine.3.yml b/test/integration/codebuild/buildspec.os.alpine.3.yml deleted file mode 100644 index ac16570d..00000000 --- a/test/integration/codebuild/buildspec.os.alpine.3.yml +++ /dev/null @@ -1,101 +0,0 @@ -version: 0.2 - -env: - variables: - OS_DISTRIBUTION: alpine - NPX_BINARY_LOCATION: "/usr/local/bin/npx" -batch: - build-matrix: - static: - ignore-failure: false - env: - type: LINUX_CONTAINER - privileged-mode: true - dynamic: - env: - variables: - DISTRO_VERSION: - - "3.9" - RUNTIME_VERSION: - - "10" - - "12" -phases: - pre_build: - commands: - - export IMAGE_TAG="nodejs-${OS_DISTRIBUTION}-${DISTRO_VERSION}:${RUNTIME_VERSION}" - - echo "Extracting and including the Runtime Interface Emulator" - - SCRATCH_DIR=".scratch" - - mkdir "${SCRATCH_DIR}" - - tar -xvf test/integration/resources/aws-lambda-rie.tar.gz --directory "${SCRATCH_DIR}" - - > - cp "test/integration/docker/Dockerfile.echo.${OS_DISTRIBUTION}" \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "RUN apk add curl" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "COPY ${SCRATCH_DIR}/aws-lambda-rie /usr/bin/aws-lambda-rie" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - if [[ -z "${DOCKERHUB_USERNAME}" && -z "${DOCKERHUB_PASSWORD}" ]]; - then - echo "DockerHub credentials not set as CodeBuild environment variables. Continuing without docker login." - else - echo "Performing DockerHub login . . ." - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - fi - - echo "Building image ${IMAGE_TAG}" - - > - docker build . \ - -f "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" \ - -t "${IMAGE_TAG}" \ - --build-arg RUNTIME_VERSION="${RUNTIME_VERSION}" \ - --build-arg DISTRO_VERSION="${DISTRO_VERSION}" - build: - commands: - - set -x - - echo "Running Image ${IMAGE_TAG}" - - docker network create "${OS_DISTRIBUTION}-network" - - > - docker run \ - --detach \ - -e "NPX_BINARY_LOCATION=${NPX_BINARY_LOCATION}" \ - --name "${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c '/usr/bin/aws-lambda-rie ${NPX_BINARY_LOCATION} aws-lambda-ric index.handler' - - sleep 2 - - > - docker run \ - --name "${OS_DISTRIBUTION}-tester" \ - --env "TARGET=${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10' - - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)" - - expected='success' - - | - echo "Response: ${actual}" - if [[ "$actual" != "$expected" ]]; then - echo "fail! runtime: $RUNTIME - expected output $expected - got $actual" - echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------" - echo - docker logs "${OS_DISTRIBUTION}-app" - echo - echo "---------------------------------------------------" - echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------" - echo - docker logs "${OS_DISTRIBUTION}-tester" - echo - echo "---------------------------------------------------" - exit -1 - fi - finally: - - echo "Cleaning up..." - - docker stop "${OS_DISTRIBUTION}-app" || true - - docker rm --force "${OS_DISTRIBUTION}-app" || true - - docker stop "${OS_DISTRIBUTION}-tester" || true - - docker rm --force "${OS_DISTRIBUTION}-tester" || true - - docker network rm "${OS_DISTRIBUTION}-network" || true \ No newline at end of file diff --git a/test/integration/codebuild/buildspec.os.amazonlinux.yml b/test/integration/codebuild/buildspec.os.amazonlinux.yml deleted file mode 100644 index 26c0988d..00000000 --- a/test/integration/codebuild/buildspec.os.amazonlinux.yml +++ /dev/null @@ -1,100 +0,0 @@ -version: 0.2 - -env: - variables: - OS_DISTRIBUTION: amazonlinux - NPX_BINARY_LOCATION: "/usr/bin/npx" -batch: - build-matrix: - static: - ignore-failure: false - env: - type: LINUX_CONTAINER - privileged-mode: true - dynamic: - env: - variables: - DISTRO_VERSION: - - "1" - - "2" - RUNTIME_VERSION: - - "10" - - "12" - - "14" -phases: - pre_build: - commands: - - export IMAGE_TAG="nodejs-${OS_DISTRIBUTION}-${DISTRO_VERSION}:${RUNTIME_VERSION}" - - echo "Extracting and including the Runtime Interface Emulator" - - SCRATCH_DIR=".scratch" - - mkdir "${SCRATCH_DIR}" - - tar -xvf test/integration/resources/aws-lambda-rie.tar.gz --directory "${SCRATCH_DIR}" - - > - cp "test/integration/docker/Dockerfile.echo.${OS_DISTRIBUTION}" \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "COPY ${SCRATCH_DIR}/aws-lambda-rie /usr/bin/aws-lambda-rie" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - if [[ -z "${DOCKERHUB_USERNAME}" && -z "${DOCKERHUB_PASSWORD}" ]]; - then - echo "DockerHub credentials not set as CodeBuild environment variables. Continuing without docker login." - else - echo "Performing DockerHub login . . ." - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - fi - - echo "Building image ${IMAGE_TAG}" - - > - docker build . \ - -f "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" \ - -t "${IMAGE_TAG}" \ - --build-arg RUNTIME_VERSION="${RUNTIME_VERSION}" \ - --build-arg DISTRO_VERSION="${DISTRO_VERSION}" - build: - commands: - - set -x - - echo "Running Image ${IMAGE_TAG}" - - docker network create "${OS_DISTRIBUTION}-network" - - > - docker run \ - --detach \ - -e "NPX_BINARY_LOCATION=${NPX_BINARY_LOCATION}" \ - --name "${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c '/usr/bin/aws-lambda-rie ${NPX_BINARY_LOCATION} aws-lambda-ric index.handler' - - sleep 2 - - > - docker run \ - --name "${OS_DISTRIBUTION}-tester" \ - --env "TARGET=${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10' - - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)" - - expected='success' - - | - echo "Response: ${actual}" - if [[ "$actual" != "$expected" ]]; then - echo "fail! runtime: $RUNTIME - expected output $expected - got $actual" - echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------" - echo - docker logs "${OS_DISTRIBUTION}-app" - echo - echo "---------------------------------------------------" - echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------" - echo - docker logs "${OS_DISTRIBUTION}-tester" - echo - echo "---------------------------------------------------" - exit -1 - fi - finally: - - echo "Cleaning up..." - - docker stop "${OS_DISTRIBUTION}-app" || true - - docker rm --force "${OS_DISTRIBUTION}-app" || true - - docker stop "${OS_DISTRIBUTION}-tester" || true - - docker rm --force "${OS_DISTRIBUTION}-tester" || true - - docker network rm "${OS_DISTRIBUTION}-network" || true \ No newline at end of file diff --git a/test/integration/codebuild/buildspec.os.centos.yml b/test/integration/codebuild/buildspec.os.centos.yml deleted file mode 100644 index 963c8e88..00000000 --- a/test/integration/codebuild/buildspec.os.centos.yml +++ /dev/null @@ -1,100 +0,0 @@ -version: 0.2 - -env: - variables: - OS_DISTRIBUTION: centos - NPX_BINARY_LOCATION: "/usr/bin/npx" -batch: - build-matrix: - static: - ignore-failure: false - env: - type: LINUX_CONTAINER - privileged-mode: true - dynamic: - env: - variables: - DISTRO_VERSION: - - "7" - - "8" - RUNTIME_VERSION: - - "10" - - "12" - - "14" -phases: - pre_build: - commands: - - export IMAGE_TAG="nodejs-${OS_DISTRIBUTION}-${DISTRO_VERSION}:${RUNTIME_VERSION}" - - echo "Extracting and including the Runtime Interface Emulator" - - SCRATCH_DIR=".scratch" - - mkdir "${SCRATCH_DIR}" - - tar -xvf test/integration/resources/aws-lambda-rie.tar.gz --directory "${SCRATCH_DIR}" - - > - cp "test/integration/docker/Dockerfile.echo.${OS_DISTRIBUTION}" \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "COPY ${SCRATCH_DIR}/aws-lambda-rie /usr/bin/aws-lambda-rie" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - if [[ -z "${DOCKERHUB_USERNAME}" && -z "${DOCKERHUB_PASSWORD}" ]]; - then - echo "DockerHub credentials not set as CodeBuild environment variables. Continuing without docker login." - else - echo "Performing DockerHub login . . ." - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - fi - - echo "Building image ${IMAGE_TAG}" - - > - docker build . \ - -f "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" \ - -t "${IMAGE_TAG}" \ - --build-arg RUNTIME_VERSION="${RUNTIME_VERSION}" \ - --build-arg DISTRO_VERSION="${DISTRO_VERSION}" - build: - commands: - - set -x - - echo "Running Image ${IMAGE_TAG}" - - docker network create "${OS_DISTRIBUTION}-network" - - > - docker run \ - --detach \ - -e "NPX_BINARY_LOCATION=${NPX_BINARY_LOCATION}" \ - --name "${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c '/usr/bin/aws-lambda-rie ${NPX_BINARY_LOCATION} aws-lambda-ric index.handler' - - sleep 2 - - > - docker run \ - --name "${OS_DISTRIBUTION}-tester" \ - --env "TARGET=${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10' - - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)" - - expected='success' - - | - echo "Response: ${actual}" - if [[ "$actual" != "$expected" ]]; then - echo "fail! runtime: $RUNTIME - expected output $expected - got $actual" - echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------" - echo - docker logs "${OS_DISTRIBUTION}-app" - echo - echo "---------------------------------------------------" - echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------" - echo - docker logs "${OS_DISTRIBUTION}-tester" - echo - echo "---------------------------------------------------" - exit -1 - fi - finally: - - echo "Cleaning up..." - - docker stop "${OS_DISTRIBUTION}-app" || true - - docker rm --force "${OS_DISTRIBUTION}-app" || true - - docker stop "${OS_DISTRIBUTION}-tester" || true - - docker rm --force "${OS_DISTRIBUTION}-tester" || true - - docker network rm "${OS_DISTRIBUTION}-network" || true \ No newline at end of file diff --git a/test/integration/codebuild/buildspec.os.debian.yml b/test/integration/codebuild/buildspec.os.debian.yml deleted file mode 100644 index 52d52803..00000000 --- a/test/integration/codebuild/buildspec.os.debian.yml +++ /dev/null @@ -1,102 +0,0 @@ -version: 0.2 - -env: - variables: - OS_DISTRIBUTION: debian - NPX_BINARY_LOCATION: "/usr/local/bin/npx" -batch: - build-matrix: - static: - ignore-failure: false - env: - type: LINUX_CONTAINER - privileged-mode: true - dynamic: - env: - variables: - DISTRO_VERSION: - - "buster" - RUNTIME_VERSION: - - "10" - - "12" - - "14" -phases: - pre_build: - commands: - - export IMAGE_TAG="nodejs-${OS_DISTRIBUTION}-${DISTRO_VERSION}:${RUNTIME_VERSION}" - - echo "Extracting and including the Runtime Interface Emulator" - - SCRATCH_DIR=".scratch" - - mkdir "${SCRATCH_DIR}" - - tar -xvf test/integration/resources/aws-lambda-rie.tar.gz --directory "${SCRATCH_DIR}" - - > - cp "test/integration/docker/Dockerfile.echo.${OS_DISTRIBUTION}" \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "COPY ${SCRATCH_DIR}/aws-lambda-rie /usr/bin/aws-lambda-rie" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - if [[ -z "${DOCKERHUB_USERNAME}" && -z "${DOCKERHUB_PASSWORD}" ]]; - then - echo "DockerHub credentials not set as CodeBuild environment variables. Continuing without docker login." - else - echo "Performing DockerHub login . . ." - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - fi - - > - echo "RUN apt-get update && apt-get install -y curl" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - echo "Building image ${IMAGE_TAG}" - - > - docker build . \ - -f "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" \ - -t "${IMAGE_TAG}" \ - --build-arg RUNTIME_VERSION="${RUNTIME_VERSION}" \ - --build-arg DISTRO_VERSION="${DISTRO_VERSION}" - build: - commands: - - set -x - - echo "Running Image ${IMAGE_TAG}" - - docker network create "${OS_DISTRIBUTION}-network" - - > - docker run \ - --detach \ - -e "NPX_BINARY_LOCATION=${NPX_BINARY_LOCATION}" \ - --name "${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c '/usr/bin/aws-lambda-rie ${NPX_BINARY_LOCATION} aws-lambda-ric index.handler' - - sleep 2 - - > - docker run \ - --name "${OS_DISTRIBUTION}-tester" \ - --env "TARGET=${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10' - - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)" - - expected='success' - - | - echo "Response: ${actual}" - if [[ "$actual" != "$expected" ]]; then - echo "fail! runtime: $RUNTIME - expected output $expected - got $actual" - echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------" - echo - docker logs "${OS_DISTRIBUTION}-app" - echo - echo "---------------------------------------------------" - echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------" - echo - docker logs "${OS_DISTRIBUTION}-tester" - echo - echo "---------------------------------------------------" - exit -1 - fi - finally: - - echo "Cleaning up..." - - docker stop "${OS_DISTRIBUTION}-app" || true - - docker rm --force "${OS_DISTRIBUTION}-app" || true - - docker stop "${OS_DISTRIBUTION}-tester" || true - - docker rm --force "${OS_DISTRIBUTION}-tester" || true - - docker network rm "${OS_DISTRIBUTION}-network" || true \ No newline at end of file diff --git a/test/integration/codebuild/buildspec.os.ubuntu.yml b/test/integration/codebuild/buildspec.os.ubuntu.yml deleted file mode 100644 index 6873f657..00000000 --- a/test/integration/codebuild/buildspec.os.ubuntu.yml +++ /dev/null @@ -1,101 +0,0 @@ -version: 0.2 - -env: - variables: - OS_DISTRIBUTION: ubuntu - NPX_BINARY_LOCATION: "/usr/bin/npx" -batch: - build-matrix: - static: - ignore-failure: false - env: - type: LINUX_CONTAINER - privileged-mode: true - dynamic: - env: - variables: - DISTRO_VERSION: - - "16.04" - - "18.04" - - "20.04" - RUNTIME_VERSION: - - "10" - - "12" - - "14" -phases: - pre_build: - commands: - - export IMAGE_TAG="nodejs-${OS_DISTRIBUTION}-${DISTRO_VERSION}:${RUNTIME_VERSION}" - - echo "Extracting and including the Runtime Interface Emulator" - - SCRATCH_DIR=".scratch" - - mkdir "${SCRATCH_DIR}" - - tar -xvf test/integration/resources/aws-lambda-rie.tar.gz --directory "${SCRATCH_DIR}" - - > - cp "test/integration/docker/Dockerfile.echo.${OS_DISTRIBUTION}" \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - echo "COPY ${SCRATCH_DIR}/aws-lambda-rie /usr/bin/aws-lambda-rie" >> \ - "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" - - > - if [[ -z "${DOCKERHUB_USERNAME}" && -z "${DOCKERHUB_PASSWORD}" ]]; - then - echo "DockerHub credentials not set as CodeBuild environment variables. Continuing without docker login." - else - echo "Performing DockerHub login . . ." - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - fi - - echo "Building image ${IMAGE_TAG}" - - > - docker build . \ - -f "${SCRATCH_DIR}/Dockerfile.echo.${OS_DISTRIBUTION}.tmp" \ - -t "${IMAGE_TAG}" \ - --build-arg RUNTIME_VERSION="${RUNTIME_VERSION}" \ - --build-arg DISTRO_VERSION="${DISTRO_VERSION}" - build: - commands: - - set -x - - echo "Running Image ${IMAGE_TAG}" - - docker network create "${OS_DISTRIBUTION}-network" - - > - docker run \ - --detach \ - -e "NPX_BINARY_LOCATION=${NPX_BINARY_LOCATION}" \ - --name "${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c '/usr/bin/aws-lambda-rie ${NPX_BINARY_LOCATION} aws-lambda-ric index.handler' - - sleep 2 - - > - docker run \ - --name "${OS_DISTRIBUTION}-tester" \ - --env "TARGET=${OS_DISTRIBUTION}-app" \ - --network "${OS_DISTRIBUTION}-network" \ - --entrypoint="" \ - "${IMAGE_TAG}" \ - sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10' - - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)" - - expected='success' - - | - echo "Response: ${actual}" - if [[ "$actual" != "$expected" ]]; then - echo "fail! runtime: $RUNTIME - expected output $expected - got $actual" - echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------" - echo - docker logs "${OS_DISTRIBUTION}-app" - echo - echo "---------------------------------------------------" - echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------" - echo - docker logs "${OS_DISTRIBUTION}-tester" - echo - echo "---------------------------------------------------" - exit -1 - fi - finally: - - echo "Cleaning up..." - - docker stop "${OS_DISTRIBUTION}-app" || true - - docker rm --force "${OS_DISTRIBUTION}-app" || true - - docker stop "${OS_DISTRIBUTION}-tester" || true - - docker rm --force "${OS_DISTRIBUTION}-tester" || true - - docker network rm "${OS_DISTRIBUTION}-network" || true \ No newline at end of file diff --git a/test/integration/docker/Dockerfile.echo.alpine b/test/integration/docker/Dockerfile.echo.alpine deleted file mode 100644 index 89a17774..00000000 --- a/test/integration/docker/Dockerfile.echo.alpine +++ /dev/null @@ -1,53 +0,0 @@ -# Define global args -ARG FUNCTION_DIR="/home/app/" -ARG RUNTIME_VERSION -ARG DISTRO_VERSION - -# Stage 1 - build function and dependencies -FROM node:${RUNTIME_VERSION}-alpine${DISTRO_VERSION} AS build-image -# Install aws-lambda-cpp build dependencies -RUN apk add --update-cache \ - build-base \ - libtool \ - musl-dev \ - libressl-dev \ - libffi-dev \ - autoconf \ - automake \ - libexecinfo-dev \ - make \ - cmake \ - python3 \ - libcurl - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Create function directory -RUN mkdir -p ${FUNCTION_DIR} - -# Copy & build Runtime Interface Client package (as we're installing it from a local filesystem source) -WORKDIR ${FUNCTION_DIR}/deps/aws-lambda-ric -COPY . . -RUN make build && \ - npm run test:unit - -# Copy function code -COPY test/integration/test-handlers/echo/* ${FUNCTION_DIR} -# Install the function's dependencies -WORKDIR ${FUNCTION_DIR} -RUN npm install - - -# Stage 2 - final runtime image -# Grab a fresh copy of the Node image -FROM node:${RUNTIME_VERSION}-alpine${DISTRO_VERSION} - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Set working directory to function root directory -WORKDIR ${FUNCTION_DIR} -# Copy in the built dependencies -COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} - -ENTRYPOINT [ "/usr/local/bin/npx", "aws-lambda-ric" ] -CMD [ "index.handler" ] diff --git a/test/integration/docker/Dockerfile.echo.amazonlinux b/test/integration/docker/Dockerfile.echo.amazonlinux deleted file mode 100644 index a5316c5e..00000000 --- a/test/integration/docker/Dockerfile.echo.amazonlinux +++ /dev/null @@ -1,68 +0,0 @@ -# Define global args -ARG FUNCTION_DIR="/home/app/" -ARG RUNTIME_VERSION -ARG DISTRO_VERSION - -# Stage 1 - bundle base image + runtime -# Grab a fresh copy of the image and install Node -FROM amazonlinux:${DISTRO_VERSION} AS node-amazonlinux -# Include global arg in this stage of the build -ARG RUNTIME_VERSION -# Install NodeJS -RUN curl -sL https://rpm.nodesource.com/setup_${RUNTIME_VERSION}.x | bash - && \ - yum install -y nodejs - - -# Stage 2 - build function and dependencies -FROM node-amazonlinux AS build-image -# Install aws-lambda-cpp build dependencies -RUN yum install -y \ - tar \ - gzip \ - make \ - autoconf \ - automake \ - libtool \ - libcurl-devel \ - gcc-c++ -# Install CMake > 3.9 -RUN if [ "$(printf '%s\n' "3.9.0" "$(cmake --version | head -n1 | tr -dc '0-9.')" | sort -V | head -n1)" != "3.9.0" ]; then \ - curl -o cmake3.tar.gz https://cmake.org/files/v3.10/cmake-3.10.0.tar.gz && \ - tar -xzf cmake3.tar.gz && \ - cd cmake-3.10.0 && \ - ./bootstrap && \ - make && \ - make install \ - ; fi - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Create function directory -RUN mkdir -p ${FUNCTION_DIR} - -# Copy & build Runtime Interface Client package (as we're installing it from a local filesystem source) -WORKDIR ${FUNCTION_DIR}/deps/aws-lambda-ric -COPY . . -RUN make build && \ - npm run test:unit - -# Copy function code -COPY test/integration/test-handlers/echo/* ${FUNCTION_DIR} -# Install the function's dependencies -WORKDIR ${FUNCTION_DIR} -RUN npm install - - -# Stage 3 - final runtime image -# Grab a fresh copy of the Node image -FROM node-amazonlinux - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Set working directory to function root directory -WORKDIR ${FUNCTION_DIR} -# Copy in the built dependencies -COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} - -ENTRYPOINT [ "/usr/bin/npx", "aws-lambda-ric" ] -CMD [ "index.handler" ] diff --git a/test/integration/docker/Dockerfile.echo.centos b/test/integration/docker/Dockerfile.echo.centos deleted file mode 100644 index e57352fa..00000000 --- a/test/integration/docker/Dockerfile.echo.centos +++ /dev/null @@ -1,66 +0,0 @@ -# Define global args -ARG FUNCTION_DIR="/home/app/" -ARG RUNTIME_VERSION -ARG DISTRO_VERSION - -# Stage 1 - bundle base image + runtime -# Grab a fresh copy of the image and install Node -FROM centos:${DISTRO_VERSION} AS node-centos -# Include global arg in this stage of the build -ARG RUNTIME_VERSION -# Install NodeJS -RUN curl -sL https://rpm.nodesource.com/setup_${RUNTIME_VERSION}.x | bash - && \ - yum install -y nodejs - - -# Stage 2 - build function and dependencies -FROM node-centos AS build-image -# Install aws-lambda-cpp build dependencies -RUN yum install -y \ - tar \ - gzip \ - make \ - autoconf \ - automake \ - libtool \ - libcurl-devel \ - gcc-c++ -# Install CMake > 3.9 -RUN curl -o cmake3.tar.gz https://cmake.org/files/v3.10/cmake-3.10.0.tar.gz && \ - tar -xzf cmake3.tar.gz && \ - cd cmake-3.10.0 && \ - ./bootstrap && \ - make && \ - make install - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Create function directory -RUN mkdir -p ${FUNCTION_DIR} - -# Copy & build Runtime Interface Client package (as we're installing it from a local filesystem source) -WORKDIR ${FUNCTION_DIR}/deps/aws-lambda-ric -COPY . . -RUN make build && \ - npm run test:unit - -# Copy function code -COPY test/integration/test-handlers/echo/* ${FUNCTION_DIR} -# Install the function's dependencies -WORKDIR ${FUNCTION_DIR} -RUN npm install - - -# Stage 3 - final runtime image -# Grab a fresh copy of the Node image -FROM node-centos - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Set working directory to function root directory -WORKDIR ${FUNCTION_DIR} -# Copy in the built dependencies -COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} - -ENTRYPOINT [ "/usr/bin/npx", "aws-lambda-ric" ] -CMD [ "index.handler" ] diff --git a/test/integration/docker/Dockerfile.echo.debian b/test/integration/docker/Dockerfile.echo.debian deleted file mode 100644 index 66fd302d..00000000 --- a/test/integration/docker/Dockerfile.echo.debian +++ /dev/null @@ -1,46 +0,0 @@ -# Define global args -ARG FUNCTION_DIR="/function/" -ARG RUNTIME_VERSION -ARG DISTRO_VERSION - -# Stage 1 - build function and dependencies -FROM node:${RUNTIME_VERSION}-${DISTRO_VERSION} AS build-image -# Install aws-lambda-cpp build dependencies -RUN apt-get update && \ - apt-get install -y \ - g++ \ - make \ - cmake \ - libcurl4-openssl-dev - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Create function directory -RUN mkdir -p ${FUNCTION_DIR} - -# Copy & build Runtime Interface Client package (as we're installing it from a local filesystem source) -WORKDIR ${FUNCTION_DIR}/deps/aws-lambda-ric -COPY . . -RUN make build && \ - npm run test:unit - -# Copy function code -COPY test/integration/test-handlers/echo/* ${FUNCTION_DIR} -# Install the function's dependencies -WORKDIR ${FUNCTION_DIR} -RUN npm install - - -# Stage 2 - final runtime image -# Grab a fresh slim copy of the Node image -FROM node:${RUNTIME_VERSION}-${DISTRO_VERSION}-slim - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Set working directory to function root directory -WORKDIR ${FUNCTION_DIR} -# Copy in the built dependencies -COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} - -ENTRYPOINT [ "/usr/local/bin/npx", "aws-lambda-ric" ] -CMD [ "index.handler" ] diff --git a/test/integration/docker/Dockerfile.echo.ubuntu b/test/integration/docker/Dockerfile.echo.ubuntu deleted file mode 100644 index 398a2ab2..00000000 --- a/test/integration/docker/Dockerfile.echo.ubuntu +++ /dev/null @@ -1,76 +0,0 @@ -# Define global args -ARG FUNCTION_DIR="/home/app/" -ARG RUNTIME_VERSION -ARG DISTRO_VERSION - -# Stage 1 - bundle base image + runtime -# Grab a fresh copy of the image and install Node -FROM ubuntu:${DISTRO_VERSION} AS node-ubuntu -# Non-interactive mode -ENV DEBIAN_FRONTEND=noninteractive -# Install NodeJS -ARG RUNTIME_VERSION -RUN apt-get update && \ - apt-get install -y \ - curl && \ - curl -sL https://deb.nodesource.com/setup_${RUNTIME_VERSION}.x | bash - && \ - apt-get install -y nodejs - - -# Stage 2 - build function and dependencies -FROM node-ubuntu AS build-image -# Install aws-lambda-cpp build dependencies -RUN apt-get update && \ - apt-get install -y \ - g++ \ - gcc \ - tar \ - curl \ - gzip \ - make \ - cmake \ - autoconf \ - automake \ - libtool \ - libcurl4-openssl-dev -# Install CMake > 3.9 for Ubuntu 16.04 -RUN if [ "$(printf '%s\n' "3.9.0" "$(cmake --version | head -n1 | tr -dc '0-9.')" | sort -V | head -n1)" != "3.9.0" ]; then \ - curl -o cmake3.tar.gz https://cmake.org/files/v3.10/cmake-3.10.0.tar.gz && \ - tar -xzf cmake3.tar.gz && \ - cd cmake-3.10.0 && \ - ./bootstrap && \ - make && \ - make install \ - ; fi - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Create function directory -RUN mkdir -p ${FUNCTION_DIR} - -# Copy & build Runtime Interface Client package (as we're installing it from a local filesystem source) -WORKDIR ${FUNCTION_DIR}/deps/aws-lambda-ric -COPY . . -RUN make build && \ - npm run test:unit - -# Copy function code -COPY test/integration/test-handlers/echo/* ${FUNCTION_DIR} -# Install the function's dependencies -WORKDIR ${FUNCTION_DIR} -RUN npm install - - -# Stage 3 - final runtime image -# Grab a fresh copy of the Node image -FROM node-ubuntu - -# Include global arg in this stage of the build -ARG FUNCTION_DIR -# Set working directory to function root directory -WORKDIR ${FUNCTION_DIR} -# Copy in the built dependencies -COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} - -ENTRYPOINT [ "/usr/bin/npx", "aws-lambda-ric" ] -CMD [ "index.handler" ] diff --git a/test/integration/resources/aws-lambda-rie.tar.gz b/test/integration/resources/aws-lambda-rie.tar.gz deleted file mode 100644 index feda16d9..00000000 Binary files a/test/integration/resources/aws-lambda-rie.tar.gz and /dev/null differ diff --git a/test/integration/test-handlers/echo/index.js b/test/integration/test-handlers/echo/index.js deleted file mode 100644 index d7ce65a5..00000000 --- a/test/integration/test-handlers/echo/index.js +++ /dev/null @@ -1,4 +0,0 @@ -exports.handler = async (event, context) => { - console.log('hello world'); - return 'success' -}; diff --git a/test/integration/test-handlers/echo/package.json b/test/integration/test-handlers/echo/package.json deleted file mode 100644 index b60909d0..00000000 --- a/test/integration/test-handlers/echo/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "echo-hanlder", - "version": "1.0.0", - "description": "Sample Lambda echo handler for NodeJS", - "main": "app.js", - "author": "AWS Lambda", - "license": "Apache-2.0", - "dependencies": { - "aws-lambda-ric": "file:deps/aws-lambda-ric" - } -} diff --git a/test/unit/Dockerfile.nodejs18.x b/test/unit/Dockerfile.nodejs18.x new file mode 100644 index 00000000..b8e8787b --- /dev/null +++ b/test/unit/Dockerfile.nodejs18.x @@ -0,0 +1,7 @@ +FROM node:18 +RUN apt-get update +RUN apt-get install -y cmake +WORKDIR /tmp +COPY . /tmp +RUN npm install --ci +CMD ["npm", "run", "test"] diff --git a/test/unit/Dockerfile.nodejs20.x b/test/unit/Dockerfile.nodejs20.x new file mode 100644 index 00000000..ccb7c96e --- /dev/null +++ b/test/unit/Dockerfile.nodejs20.x @@ -0,0 +1,7 @@ +FROM node:20 +RUN apt-get update +RUN apt-get install -y cmake +WORKDIR /tmp +COPY . /tmp +RUN npm install --ci +CMD ["npm", "run", "test"] diff --git a/test/unit/Dockerfile.nodejs22.x b/test/unit/Dockerfile.nodejs22.x new file mode 100644 index 00000000..c0745cb4 --- /dev/null +++ b/test/unit/Dockerfile.nodejs22.x @@ -0,0 +1,7 @@ +FROM node:22 +RUN apt-get update +RUN apt-get install -y cmake +WORKDIR /tmp +COPY . /tmp +RUN npm install --ci +CMD ["npm", "run", "test"] diff --git a/test/unit/Errors/Errors.test.ts b/test/unit/Errors/Errors.test.ts deleted file mode 100644 index e2841efa..00000000 --- a/test/unit/Errors/Errors.test.ts +++ /dev/null @@ -1,125 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -require("should"); -import * as Errors from "../../../src/Errors"; - -class CircularError extends Error { - backlink: Error; - - constructor(message?: string) { - super(message); - - this.backlink = this; - this.name = "CircularError"; - } -} - -class ExtendedError extends Error { - code?: number; - customProperty?: string; - - constructor(message?: string) { - super(message); - - this.name = "ExtendedError"; - this.stack = "ExtendedErrorStack"; - this.code = 100; - this.customProperty = "ExtendedErrorCustomProperty"; - } -} - -describe("Formatting CircularError Logging", () => { - it("should fall back to a minimal error format when an exception occurs", () => { - const error = new CircularError("custom message"); - error.backlink = error; - - const loggedError = JSON.parse(Errors.toFormatted(error).trim()); - loggedError.should.have.property("errorType", "CircularError"); - loggedError.should.have.property("errorMessage", "custom message"); - loggedError.should.have.property("trace"); - loggedError.trace.length.should.be.aboveOrEqual(1); - }); -}); - -describe("Formatting Error Logging", () => { - it("should fall back to an extended error format when an exception occurs", () => { - const error = new ExtendedError("custom message"); - - const loggedError = JSON.parse(Errors.toFormatted(error).trim()); - loggedError.should.have.property("errorType", "ExtendedError"); - loggedError.should.have.property("errorMessage", "custom message"); - loggedError.should.have.property("stack", ["ExtendedErrorStack"]); - loggedError.should.have.property("code", 100); - loggedError.should.have.property( - "customProperty", - "ExtendedErrorCustomProperty" - ); - }); -}); - -describe("Converting an Error to a Runtime response", () => { - it("should create a RuntimeErrorResponse object when an Error object is given", () => { - const error = new Error("custom message"); - error.name = "Runtime.TestError"; - - const errorResponse = Errors.toRuntimeResponse(error); - - errorResponse.should.have.property("errorType", "Runtime.TestError"); - errorResponse.should.have.property("errorMessage", "custom message"); - errorResponse.should.have.property("trace"); - errorResponse.trace.length.should.be.aboveOrEqual(1); - }); - - it("should return a handled error response when the trace is missing", () => { - const error = new Error("custom message"); - error.name = "Runtime.TestError"; - error.stack = undefined; - - const errorResponse = Errors.toRuntimeResponse(error); - - errorResponse.should.have.property("errorType", "handled"); - errorResponse.should.have - .property("errorMessage") - .with.match(/message, name, and stack/); - errorResponse.should.have.property("trace"); - errorResponse.trace.length.should.be.equal(0); - }); - - it("should handle strings by setting them as the message and assigning error type to string", () => { - const error = "custom message"; - const errorResponse = Errors.toRuntimeResponse(error); - - errorResponse.should.have.property("errorType", "string"); - errorResponse.should.have.property("errorMessage", "custom message"); - errorResponse.should.have.property("trace"); - errorResponse.trace.length.should.be.equal(0); - }); - - it("should handle arbitrary objects by converting them to string", () => { - const error = { - text: "custom message", - }; - - const errorResponse = Errors.toRuntimeResponse(error); - - errorResponse.should.have.property("errorType", "object"); - errorResponse.should.have.property("errorMessage", "[object Object]"); - errorResponse.should.have.property("trace"); - errorResponse.trace.length.should.be.equal(0); - }); - - it("should handle arbitrary objects by converting them to string by calling the toString method", () => { - const error = { - text: "custom message", - }; - error.toString = () => error.text; - const errorResponse = Errors.toRuntimeResponse(error); - - errorResponse.should.have.property("errorType", "object"); - errorResponse.should.have.property("errorMessage", "custom message"); - errorResponse.should.have.property("trace"); - errorResponse.trace.length.should.be.equal(0); - }); -}); diff --git a/test/unit/Errors/XRayError.test.ts b/test/unit/Errors/XRayError.test.ts deleted file mode 100644 index 5fd10354..00000000 --- a/test/unit/Errors/XRayError.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -require("should"); -import * as XRayError from "../../../src/Errors/XRayError"; - -describe("Formatted Error Logging", () => { - it("should fall back to a minimal error format when an exception occurs", () => { - const error = new Error("custom message"); - error.name = "CircularError"; - error.stack = `CircularError: custom message - at exports.handler (/var/function/node_modules/event_invoke.js:3:502) - at exports.handler (/var/function/node_modules/event_invoke.js:5:242) - at (/var/function/test_exec.js:4:123)`; - - const loggedXRayError = JSON.parse(XRayError.toFormatted(error).trim()); - loggedXRayError.should.have.property("working_directory"); - loggedXRayError.should.have.property("exceptions"); - loggedXRayError.should.have - .property("paths") - .with.containDeep([ - "/var/function/node_modules/event_invoke.js", - "/var/function/test_exec.js", - ]); - - const exceptions = loggedXRayError.exceptions; - - exceptions.should.have.length(1); - - const loggedError = exceptions[0]; - - loggedError.should.have.property("type", "CircularError"); - loggedError.should.have.property("message", "custom message"); - loggedError.should.have.property("stack").containDeep([ - { - path: "/var/function/node_modules/event_invoke.js", - line: 3, - label: "exports.handler", - }, - { - path: "/var/function/node_modules/event_invoke.js", - line: 5, - label: "exports.handler", - }, - { - path: "/var/function/test_exec.js", - line: 4, - label: "anonymous", - }, - ]); - }); -}); diff --git a/test/unit/ErrorsTest.js b/test/unit/ErrorsTest.js new file mode 100644 index 00000000..ea98fd19 --- /dev/null +++ b/test/unit/ErrorsTest.js @@ -0,0 +1,41 @@ +/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +require('should'); +let Errors = require('lambda-runtime/Errors'); + +describe('Formatted Error Logging', () => { + it('should fall back to a minimal error format when an exception occurs', () => { + let error = new Error('custom message'); + error.name = 'CircularError'; + error.backlink = error; + + let loggedError = JSON.parse(Errors.toFormatted(error).trim()); + loggedError.should.have.property('errorType', 'CircularError'); + loggedError.should.have.property('errorMessage', 'custom message'); + loggedError.should.have.property('trace').with.length(11); + }); +}); + +describe('Invalid chars in HTTP header', () => { + it('should be replaced', () => { + let errorWithInvalidChar = new Error('\x7F'); + errorWithInvalidChar.name = 'ErrorWithInvalidChar'; + + let loggedError = Errors.toRapidResponse(errorWithInvalidChar); + loggedError.should.have.property('errorType', 'ErrorWithInvalidChar'); + loggedError.should.have.property('errorMessage', '%7F'); + }); +}); + +describe('NodeJsExit error ctor', () => { + it('should be have a fixed reason', () => { + let nodeJsExit = new Errors.NodeJsExit(); + let loggedError = Errors.toRapidResponse(nodeJsExit); + loggedError.should.have.property('errorType', 'Runtime.NodeJsExit'); + loggedError.errorMessage.should.containEql( + 'runtime client detected an unexpected Node.js', + ); + }); +}); diff --git a/test/unit/FakeTelemetryTarget.js b/test/unit/FakeTelemetryTarget.js new file mode 100644 index 00000000..21b38fcf --- /dev/null +++ b/test/unit/FakeTelemetryTarget.js @@ -0,0 +1,130 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +const os = require('os'); +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); + +const levels = Object.freeze({ + TRACE: { name: 'TRACE', tlvMask: 0b00100 }, + DEBUG: { name: 'DEBUG', tlvMask: 0b01000 }, + INFO: { name: 'INFO', tlvMask: 0b01100 }, + WARN: { name: 'WARN', tlvMask: 0b10000 }, + ERROR: { name: 'ERROR', tlvMask: 0b10100 }, + FATAL: { name: 'FATAL', tlvMask: 0b11000 }, +}); + +const TextName = 'TEXT'; + +/** + * A fake implementation of the multilne logging protocol. + * Read and write log frames to a temp file and provide an asserting helper for + * reading individual log statements from the file. + */ +module.exports = class FakeTelemetryTarget { + constructor() { + this.readTarget = 0; + this.writeTarget = 0; + } + + openFile() { + let tempTelemetryDir = fs.mkdtempSync( + path.join(os.tmpdir(), 'AWSLambdaNodeJsTelemetry-'), + ); + this.writeTarget = fs.openSync(path.join(tempTelemetryDir, 'log'), 'as+'); + this.readTarget = fs.openSync(path.join(tempTelemetryDir, 'log'), 'rs+'); + console.log( + 'Generate new telemetry file', + tempTelemetryDir, + 'with file descriptor', + this.readTarget, + ); + } + + closeFile() { + console.log(`Close telemetry filedescriptor ${this.readTarget}`); + fs.closeSync(this.readTarget); + fs.closeSync(this.writeTarget); + this.readTarget = 0; + this.writeTarget = 0; + } + + updateEnv() { + process.env['_LAMBDA_TELEMETRY_LOG_FD'] = this.writeTarget; + } + + /** + * Read a single line from the telemetry file. + * Explodes when: + * - no line is present + * - the prefix is malformed + * - there aren't enough bytes + */ + readLine(level = 'INFO', format = TextName, expectEmpty = false) { + let readLength = () => { + let logPrefix = Buffer.alloc(16); + let actualReadBytes = fs.readSync( + this.readTarget, + logPrefix, + 0, + logPrefix.length, + ); + + if (expectEmpty) { + assert.strictEqual( + actualReadBytes, + 0, + `Expected actualReadBytes[${actualReadBytes}] = 0`, + ); + return 0; + } + + assert.strictEqual( + actualReadBytes, + logPrefix.length, + `Expected actualReadBytes[${actualReadBytes}] = ${logPrefix.length}`, + ); + + var _tlvHeader; + if (format === TextName) + _tlvHeader = (0xa55a0003 | levels[level].tlvMask) >>> 0; + else _tlvHeader = (0xa55a0002 | levels[level].tlvMask) >>> 0; + + let _logIdentifier = Buffer.from(_tlvHeader.toString(16), 'hex'); + assert.strictEqual( + logPrefix.lastIndexOf(_logIdentifier), + 0, + `log prefix ${logPrefix.toString( + 'hex', + )} should start with ${_logIdentifier.toString('hex')}`, + ); + let len = logPrefix.readUInt32BE(4); + // discard the timestamp + logPrefix.readBigUInt64BE(8); + return len; + }; + + let lineLength = readLength(); + if (lineLength === 0) { + return ''; + } + + let lineBytes = Buffer.alloc(lineLength); + let actualLineSize = fs.readSync( + this.readTarget, + lineBytes, + 0, + lineBytes.length, + ); + assert.strictEqual( + actualLineSize, + lineBytes.length, + 'The log line must match the length specified in the frame header', + ); + return lineBytes.toString('utf8'); + } +}; diff --git a/test/unit/InvokeContextTest.js b/test/unit/InvokeContextTest.js new file mode 100644 index 00000000..e0d6bfd3 --- /dev/null +++ b/test/unit/InvokeContextTest.js @@ -0,0 +1,66 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +require('should'); +const sleep = require('util').promisify(setTimeout); + +let InvokeContext = require('lambda-runtime/InvokeContext'); + +describe('Getting remaining invoke time', () => { + it('should reduce by at least elapsed time', async () => { + let ctx = new InvokeContext({ + 'lambda-runtime-deadline-ms': Date.now() + 1000, + }); + + const timeout = 100; + let before = ctx._headerData().getRemainingTimeInMillis(); + await sleep(timeout + 10); + let after = ctx._headerData().getRemainingTimeInMillis(); + (before - after).should.greaterThanOrEqual( + timeout - 1 /* Timers are not precise, allow 1 ms drift */, + ); + }); + + it('should be within range', () => { + let ctx = new InvokeContext({ + 'lambda-runtime-deadline-ms': Date.now() + 1000, + }); + + let remainingTime = ctx._headerData().getRemainingTimeInMillis(); + + remainingTime.should.greaterThan(0); + remainingTime.should.lessThanOrEqual(1000); + }); +}); + +describe('Verifying tenant id', () => { + it('should return undefined if tenant id is not set', () => { + let ctx = new InvokeContext({}); + + (ctx._headerData().tenantId === undefined).should.be.true(); + }); + it('should return undefined if tenant id is set to undefined', () => { + let ctx = new InvokeContext({ + 'lambda-runtime-aws-tenant-id': undefined, + }); + + (ctx._headerData().tenantId === undefined).should.be.true(); + }); + it('should return empty if tenant id is set to empty string', () => { + let ctx = new InvokeContext({ + 'lambda-runtime-aws-tenant-id': '', + }); + + (ctx._headerData().tenantId === '').should.be.true(); + }); + it('should return the same id if a valid tenant id is set', () => { + let ctx = new InvokeContext({ + 'lambda-runtime-aws-tenant-id': 'blue', + }); + + ctx._headerData().tenantId.should.equal('blue'); + }); +}); diff --git a/test/unit/IsAsyncTest.js b/test/unit/IsAsyncTest.js new file mode 100644 index 00000000..a4df41ae --- /dev/null +++ b/test/unit/IsAsyncTest.js @@ -0,0 +1,37 @@ +/** Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ + +'use strict'; + +require('should'); +const path = require('path'); +const UserFunction = require('lambda-runtime/UserFunction.js'); + +const TEST_ROOT = path.join(__dirname, '../'); +const HANDLERS_ROOT = path.join(TEST_ROOT, 'handlers'); + +describe('isAsync tests', () => { + it('is async should be true', async () => { + const handlerFunc = await UserFunction.load( + HANDLERS_ROOT, + 'isAsync.handlerAsync', + ); + const metadata = UserFunction.getHandlerMetadata(handlerFunc); + metadata.isAsync.should.be.true(); + }); + it('is async should be false', async () => { + const handlerFunc = await UserFunction.load( + HANDLERS_ROOT, + 'isAsync.handlerNotAsync', + ); + const metadata = UserFunction.getHandlerMetadata(handlerFunc); + metadata.isAsync.should.be.false(); + }); + it('is async should be false since it is a callback', async () => { + const handlerFunc = await UserFunction.load( + HANDLERS_ROOT, + 'isAsyncCallback.handler', + ); + const metadata = UserFunction.getHandlerMetadata(handlerFunc); + metadata.isAsync.should.be.false(); + }); +}); \ No newline at end of file diff --git a/test/unit/LogPatchTest.js b/test/unit/LogPatchTest.js new file mode 100644 index 00000000..8cadb5b0 --- /dev/null +++ b/test/unit/LogPatchTest.js @@ -0,0 +1,965 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +const util = require('util'); + +let should = require('should'); +let LogPatch = require('lambda-runtime/LogPatch'); +let Errors = require('lambda-runtime/Errors'); +let assert = require('assert'); + +let { + captureStream, + consoleSnapshot, + loggingConfig, +} = require('./LoggingGlobals'); +let FakeTelemetryTarget = require('./FakeTelemetryTarget'); +let fakeLoggingConfig = new loggingConfig(); +const logFunctions = [ + [ + function (message, ...params) { + console.trace(message, ...params); + }, + 'TRACE', + ], + [ + function (message, ...params) { + console.debug(message, ...params); + }, + 'DEBUG', + ], + [ + function (message, ...params) { + console.info(message, ...params); + }, + 'INFO', + ], + [ + function (message, ...params) { + console.log(message, ...params); + }, + 'INFO', + ], + [ + function (message, ...params) { + console.warn(message, ...params); + }, + 'WARN', + ], + [ + function (message, ...params) { + console.error(message, ...params); + }, + 'ERROR', + ], + [ + function (message, ...params) { + console.fatal(message, ...params); + }, + 'FATAL', + ], +]; + +describe('Apply the default console log patch', () => { + let restoreConsole = consoleSnapshot(); + let capturedStdout = captureStream(process.stdout); + + beforeEach('capture stdout', () => capturedStdout.hook()); + beforeEach('apply console patch', () => LogPatch.patchConsole()); + afterEach('remove console patch', () => restoreConsole()); + afterEach('unhook stdout', () => capturedStdout.unhook()); + + it('should have four tab-separated fields on a normal line', () => { + console.log('anything'); + capturedStdout.captured().should.match(/.*\t.*\t.*\t.*\n/); + }); + + it('should have five tab-separated fields when logging an error', () => { + console.error('message', Errors.toFormatted(new Error('garbage'))); + capturedStdout.captured().should.match(/.*\t.*\t.*\t.*\t.*\n/); + }); + + describe('When the global requestId is set', () => { + const EXPECTED_ID = 'some fake request id'; + + beforeEach('set the request id', () => { + LogPatch.setCurrentRequestId(EXPECTED_ID); + }); + afterEach('unset the request id', () => { + LogPatch.setCurrentRequestId(EXPECTED_ID); + }); + + it('should include the requestId as the second field', () => { + console.info('something'); + capturedStdout + .captured() + .should.match(new RegExp(`.*\t${EXPECTED_ID}\t.*\t.*\n`)); + }); + }); + + it('should include the level field as the third field', () => { + console.warn('content'); + capturedStdout.captured().should.match(new RegExp(`.*\t.*\tWARN\t.*\n`)); + }); + + it('should include the message as the fourth field', () => { + let message = 'my turbo message'; + console.trace(message); + capturedStdout + .captured() + .should.match(new RegExp(`.*\t.*\t.*\t${message}\n`)); + }); + + describe('Each console.* method should include a level value', () => { + it('should use INFO for console.log', () => { + console.log('hello'); + capturedStdout.captured().should.containEql('INFO'); + }); + + it('should use INFO for console.info', () => { + console.info('hello'); + capturedStdout.captured().should.containEql('INFO'); + }); + + it('should use WARN for console.warn', () => { + console.warn('hello'); + capturedStdout.captured().should.containEql('WARN'); + }); + + it('should use ERROR for console.error', () => { + console.error('hello'); + capturedStdout.captured().should.containEql('ERROR'); + }); + + it('should use TRACE for console.trace', () => { + console.trace('hello'); + capturedStdout.captured().should.containEql('TRACE'); + }); + + it('should use FATAL for console.fatal', () => { + console.fatal('hello'); + capturedStdout.captured().should.containEql('FATAL'); + }); + }); + + it('should log an error as json', () => { + let expected = new Error('some error'); + expected.code = 1234; + expected.custom = 'my custom field'; + + console.error('message', Errors.toFormatted(expected)); + + let errorString = capturedStdout.captured().split('\t')[4]; + let recoveredError = JSON.parse(errorString); + + recoveredError.should.have.property('errorType', expected.name); + recoveredError.should.have.property('errorMessage', expected.message); + recoveredError.should.have.property('stack', expected.stack.split('\n')); + recoveredError.should.have.property('code', expected.code); + recoveredError.should.have.property('custom', expected.custom); + }); + + describe('Structured logging for new line delimited logs', () => { + const EXPECTED_ID = 'structured logging for nd logging request id'; + beforeEach('set the request id', () => { + LogPatch.setCurrentRequestId(EXPECTED_ID); + }); + + beforeEach('turn on structured logging', () => { + fakeLoggingConfig.turnOnStructuredLogging(); + LogPatch.patchConsole(); + }); + afterEach('turn off structured logging', () => { + fakeLoggingConfig.turnOffStructuredLogging(); + }); + + it('should format messages as json correctly', () => { + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + logFunctions[fIdx][0]('hello structured logging'); + let receivedMessage = capturedStdout.captured(); + receivedMessage = JSON.parse(receivedMessage); + + receivedMessage.should.have.property('timestamp'); + let receivedTime = new Date(receivedMessage.timestamp); + let now = new Date(); + assert(now >= receivedTime && now - receivedTime <= 1000); + + receivedMessage.should.have.property( + 'message', + 'hello structured logging', + ); + receivedMessage.should.have.property('level', logFunctions[fIdx][1]); + receivedMessage.should.have.property('requestId', EXPECTED_ID); + + capturedStdout.resetBuffer(); + } + }); + }); + describe(' `structuredConsole.logError()` method in TEXT mode', () => { + const EXPECTED_ID = 'structured logging request id'; + const originalDate = Date; + beforeEach('set the request id', () => { + LogPatch.setCurrentRequestId(EXPECTED_ID); + }); + beforeEach('freeze current date', () => { + function mockDate() { + return new originalDate('2023-09-25T12:00:00Z'); + } + global.Date = mockDate; + }); + afterEach('unfreeze current date', () => { + global.Date = originalDate; + }); + it('should produce stringified output for TEXT mode', () => { + let expected = new Error('some error'); + expected.code = 1234; + expected.custom = 'my custom field'; + LogPatch.structuredConsole.logError('Invocation Error', expected); + + let recoveredMessage = capturedStdout.captured().split('\t'); + recoveredMessage[2].should.be.equal('ERROR'); + recoveredMessage[3].should.be.equal('Invocation Error '); + + let recoveredError = JSON.parse(recoveredMessage[4]); + recoveredError.should.have.property('errorType', expected.name); + recoveredError.should.have.property('errorMessage', expected.message); + recoveredError.should.have.property('stack', expected.stack.split('\n')); + recoveredError.should.have.property('code', expected.code); + recoveredError.should.have.property('custom', expected.custom); + }); + }); +}); + +describe('The multiline log patch', () => { + let restoreConsole = consoleSnapshot(); + let telemetryTarget = new FakeTelemetryTarget(); + + beforeEach('create a new telemetry file and patch the console', () => { + telemetryTarget.openFile(); + telemetryTarget.updateEnv(); + LogPatch.patchConsole(); + }); + afterEach('close the telemetry file and unpatch the console', () => { + restoreConsole(); + telemetryTarget.closeFile(); + }); + + it('should clear the telemetry env var', () => { + should.not.exist(process.env['_LAMBDA_TELEMETRY_LOG_FD']); + }); + + it('should write a line', () => { + console.log('a line'); + telemetryTarget.readLine().should.containEql('a line'); + }); + + it('should have four tab-separated fields on a normal line', () => { + console.log('anything'); + telemetryTarget.readLine().should.match(/.*\t.*\t.*\t.*/); + }); + + it('should end with a newline', () => { + console.log('lol'); + telemetryTarget.readLine().should.match(/.*\n$/); + }); + + it('should have five tab-separated fields when logging an error', () => { + console.error('message', Errors.toFormatted(new Error('garbage'))); + telemetryTarget.readLine('ERROR').should.match(/.*\t.*\t.*\t.*\t.*/); + }); + + describe('When the global requestId is set', () => { + const EXPECTED_ID = 'some fake request id'; + + beforeEach('set the request id', () => { + LogPatch.setCurrentRequestId(EXPECTED_ID); + }); + afterEach('unset the request id', () => { + LogPatch.setCurrentRequestId(EXPECTED_ID); + }); + + it('should include the requestId as the second field', () => { + console.info('something'); + telemetryTarget + .readLine() + .should.match(new RegExp(`.*\t${EXPECTED_ID}\t.*\t.*`)); + }); + }); + + it('should include the level field as the third field', () => { + console.warn('content'); + telemetryTarget + .readLine('WARN') + .should.match(new RegExp(`.*\t.*\tWARN\t.*`)); + }); + + it('should include the message as the fourth field', () => { + let message = 'my turbo message'; + console.trace(message); + telemetryTarget + .readLine('TRACE') + .should.match(new RegExp(`.*\t.*\t.*\t${message}`)); + }); + + describe('Each console.* method should include a level value', () => { + it('should use INFO for console.log', () => { + console.log('hello'); + telemetryTarget.readLine().should.containEql('INFO'); + }); + + it('should use INFO for console.info', () => { + console.info('hello'); + telemetryTarget.readLine().should.containEql('INFO'); + }); + + it('should use WARN for console.warn', () => { + console.warn('hello'); + telemetryTarget.readLine('WARN').should.containEql('WARN'); + }); + + it('should use ERROR for console.error', () => { + console.error('hello'); + telemetryTarget.readLine('ERROR').should.containEql('ERROR'); + }); + + it('should use TRACE for console.trace', () => { + console.trace('hello'); + telemetryTarget.readLine('TRACE').should.containEql('TRACE'); + }); + + it('should use FATAL for console.fatal', () => { + console.fatal('hello'); + telemetryTarget.readLine('FATAL').should.containEql('FATAL'); + }); + }); + + it('should log an error as json', () => { + let expected = new Error('some error'); + expected.code = 1234; + expected.custom = 'my custom field'; + + console.error('message', Errors.toFormatted(expected)); + + let errorString = telemetryTarget.readLine('ERROR').split('\t')[4]; + let recoveredError = JSON.parse(errorString); + + recoveredError.should.have.property('errorType', expected.name); + recoveredError.should.have.property('errorMessage', expected.message); + recoveredError.should.have.property('stack', expected.stack.split('\n')); + recoveredError.should.have.property('code', expected.code); + recoveredError.should.have.property('custom', expected.custom); + }); + + describe('Structured logging', () => { + const EXPECTED_ID = 'structured logging request id'; + const originalDate = Date; + beforeEach('set the request id', () => { + LogPatch.setCurrentRequestId(EXPECTED_ID); + }); + + beforeEach('turn on structured logging', () => { + fakeLoggingConfig.turnOnStructuredLogging(); + telemetryTarget.openFile(); + telemetryTarget.updateEnv(); + LogPatch.patchConsole(); + }); + beforeEach('freeze current date', () => { + function mockDate() { + return new originalDate('2023-09-25T12:00:00Z'); + } + global.Date = mockDate; + }); + + afterEach('turn off structured logging & reset log level', () => { + fakeLoggingConfig.turnOffStructuredLogging(); + fakeLoggingConfig.resetLogLevel(); + }); + afterEach('unfreeze current date', () => { + global.Date = originalDate; + }); + + it('should format messages as json correctly', () => { + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + logFunctions[fIdx][0]( + 'hello', + 3.14, + 'structured logging', + false, + { test: 'structured logging' }, + ['random', 'logs'], + ); + let receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + + receivedMessage.should.have.property('timestamp'); + let receivedTime = new Date(receivedMessage.timestamp); + let now = new Date(); + assert(now >= receivedTime && now - receivedTime <= 1000); + + receivedMessage.should.have.property( + 'message', + util.format( + 'hello', + 3.14, + 'structured logging', + false, + { test: 'structured logging' }, + ['random', 'logs'], + ), + ); + receivedMessage.should.have.property('level', logFunctions[fIdx][1]); + receivedMessage.should.have.property('requestId', EXPECTED_ID); + receivedMessage.should.not.have.property('tenantId'); + } + }); + + it('should format messages with tenant id as json correctly', () => { + const EXPECTED_TENANT_ID = 'tenantId'; + LogPatch.setCurrentTenantId(EXPECTED_TENANT_ID); + + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + logFunctions[fIdx][0]('structured logging with tenant id'); + let receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + + receivedMessage.should.have.property('timestamp'); + let receivedTime = new Date(receivedMessage.timestamp); + let now = new Date(); + assert(now >= receivedTime && now - receivedTime <= 1000); + + receivedMessage.should.have.property( + 'message', + 'structured logging with tenant id', + ); + receivedMessage.should.have.property('level', logFunctions[fIdx][1]); + receivedMessage.should.have.property('requestId', EXPECTED_ID); + receivedMessage.should.have.property('tenantId', EXPECTED_TENANT_ID); + } + LogPatch.setCurrentTenantId(undefined); + }); + + it('should filter messages correctly', () => { + const loglevelSettings = [ + undefined, + 'TRACE', + 'DEBUG', + 'INFO', + 'WARN', + 'ERROR', + 'FATAL', + ]; + const filterMatrix = [ + [false, false, false, false, false, false, false], + [false, false, false, false, false, false, false], + [true, false, false, false, false, false, false], + [true, true, false, false, false, false, false], + [true, true, true, true, false, false, false], + [true, true, true, true, true, false, false], + [true, true, true, true, true, true, false], + ]; + + let receivedMessage, + expectEmpty = true; + for (let idx = 0; idx < loglevelSettings.length; idx++) { + fakeLoggingConfig.setLogLevel(loglevelSettings[idx]); + telemetryTarget.openFile(); + telemetryTarget.updateEnv(); + LogPatch.patchConsole(); + + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + logFunctions[fIdx][0]('random log message'); + if (filterMatrix[idx][fIdx]) { + telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + expectEmpty, + ); + } else { + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.have.property( + 'message', + 'random log message', + ); + } + } + } + }); + + it('should add error fields to messages if error is supplied', () => { + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + let e1 = new SyntaxError('random syntax error'); + let e2 = new ReferenceError('random reference error'); + logFunctions[fIdx][0]( + 'logged an error', + e1, + 'logged another error', + e2, + ); + let receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.have.property('errorType', e1.constructor.name); + receivedMessage.should.have.property('errorMessage', e1.message); + receivedMessage.should.have.property( + 'stackTrace', + e1.stack.split('\n'), + ); + } + }); + + it('should handle malformed errors', () => { + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + let e1 = new Error(), + e2 = new Error(), + e3 = new Error(), + e4 = new Error(), + e5 = new Error(), + e6 = new Error(), + e7 = new Error(), + e8 = new Error(), + e9 = new Error(); + e1.constructor = null; + e2.stack = null; + e3.message = null; + e4.stack = undefined; + e5.constructor = undefined; + e6.message = undefined; + e7.stack = { customStack: 'of object type' }; + e8.message = 1.23; + e8.constructor = { name: 'overwritten type' }; + e8.stack = 'overwritten\nstack\ntrace'; + e9.errorType = 1.23; + e9.errorMessage = 456; + e9.stackTrace = 'overwritten'; + + logFunctions[fIdx][0]('error with null constructor', e1); + let receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.have.property('errorType', 'UnknownError'); + + logFunctions[fIdx][0]('error with undefined constructor', e5); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.have.property('errorType', 'UnknownError'); + + logFunctions[fIdx][0]('error with null stacktrace', e2); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.have.property('stackTrace', []); + + logFunctions[fIdx][0]('error with undefined stacktrace', e4); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.have.property('stackTrace', []); + + logFunctions[fIdx][0]('error with non-string stacktrace', e7); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.have.property('stackTrace', []); + + logFunctions[fIdx][0]('error with null message', e3); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.have.property('errorMessage', null); + + logFunctions[fIdx][0]('error with undefined message', e6); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage = JSON.parse(receivedMessage); + receivedMessage.should.not.have.property('errorMessage'); + + logFunctions[fIdx][0]( + 'error with overwritten `message`, `constructor.name`, `stack`', + e8, + ); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: util.format( + 'error with overwritten `message`, `constructor.name`, `stack`', + e8, + ), + errorType: 'overwritten type', + errorMessage: 1.23, + stackTrace: ['overwritten', 'stack', 'trace'], + }), + ); + + logFunctions[fIdx][0]( + 'error with overwritten `errorType`, `errorMessage`, `stackTrace`', + e9, + ); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: util.format( + 'error with overwritten `errorType`, `errorMessage`, `stackTrace`', + e9, + ), + errorType: 'Error', + errorMessage: '', + stackTrace: e9.stack.split('\n'), + }), + ); + } + }); + + it('should not strinfigy single arg', () => { + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + logFunctions[fIdx][0](100.123); + let receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: 100.123, + }), + ); + + logFunctions[fIdx][0]([ + { someKey: 'some_val', data: 1000 }, + false, + [1, 2, 3], + 3.14, + ]); // arrays + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: [ + { someKey: 'some_val', data: 1000 }, + false, + [1, 2, 3], + 3.14, + ], + }), + ); + + logFunctions[fIdx][0]({ transactionId: 100, data: 3.14, state: false }); // objects + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: { transactionId: 100, data: 3.14, state: false }, + }), + ); + } + }); + + it('should use custom serializer for single arg containing error instances', () => { + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + let err = new TypeError('some message'); + logFunctions[fIdx][0](err); + let receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: { + errorType: 'TypeError', + errorMessage: 'some message', + stackTrace: err.stack.split('\n'), + }, + }), + ); + + // malformed null error + err = new Error('some error'); + err.constructor = null; + err.message = null; + err.stack = null; + logFunctions[fIdx][0](err); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: { + errorType: 'UnknownError', + errorMessage: null, + stackTrace: null, + constructor: null, + }, + }), + ); + + // malformed undefined error + err = new Error('some error'); + err.constructor = undefined; + err.message = undefined; + err.stack = undefined; + logFunctions[fIdx][0](err); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: { + errorType: 'UnknownError', + }, + }), + ); + + // nested error + err = new ReferenceError('some error message'); + logFunctions[fIdx][0]({ transactionId: 100, error: err }); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: { + transactionId: 100, + error: { + errorType: 'ReferenceError', + errorMessage: 'some error message', + stackTrace: err.stack.split('\n'), + }, + }, + }), + ); + + // error with custom fields + err = new SyntaxError('some error'); + err.custom1 = 'custom error data'; + err.custom2 = 123.456; + logFunctions[fIdx][0](err); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: { + errorType: 'SyntaxError', + errorMessage: 'some error', + stackTrace: err.stack.split('\n'), + custom1: 'custom error data', + custom2: 123.456, + }, + }), + ); + + // error with overriden `err.message`, `err.constructor.name`, `err.stack` + err = new SyntaxError('some error'); + err.message = 123.456; + err.constructor = { name: false }; + err.stack = { customStack: 'should not be formatted' }; + logFunctions[fIdx][0](err); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: { + errorType: false, + errorMessage: 123.456, + stackTrace: { customStack: 'should not be formatted' }, + constructor: { name: false }, + }, + }), + ); + + // error with overriden `errorMessage`, `errorType`, `stackTrace` + err = new SyntaxError('some error'); + err.errorType = 1.23; + err.errorMessage = 456; + err.stackTrace = ['random', 'values', 1, 2, false]; + logFunctions[fIdx][0](err); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: { + errorType: 1.23, + errorMessage: 456, + stackTrace: ['random', 'values', 1, 2, false], + }, + }), + ); + } + }); + it('should default to stringifying if single arg contains un-serializable objects', () => { + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + // circular object + let obj = { data: 123 }; + obj.backlink = obj; + + logFunctions[fIdx][0](obj); + let receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: ' { data: 123, backlink: [Circular *1] }', + }), + ); + + // circular error + let err = new Error('circular error'); + err.backlink = err; + logFunctions[fIdx][0](err); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: util.format(err), + }), + ); + } + }); + it('should handle single arg object with custom toJSON implementation', () => { + for (let fIdx = 0; fIdx < logFunctions.length; fIdx++) { + let obj = { data: 123 }; + obj.toJSON = () => 'custom serialized'; + + logFunctions[fIdx][0](obj); + let receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: 'custom serialized', + }), + ); + + logFunctions[fIdx][0]('as part of multiple args', obj); + receivedMessage = telemetryTarget.readLine( + logFunctions[fIdx][1], + 'JSON', + ); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: logFunctions[fIdx][1], + requestId: 'structured logging request id', + message: + 'as part of multiple args { data: 123, toJSON: [Function (anonymous)] }', + }), + ); + } + }); + it(' `structuredConsole.logError()` output should not be stringified in JSON mode', () => { + let err = new SyntaxError('user syntax error'); + err.code = 123; + LogPatch.structuredConsole.logError('Invoke Error', err); + + let receivedMessage = telemetryTarget.readLine('ERROR', 'JSON'); + receivedMessage.should.be.equal( + JSON.stringify({ + timestamp: '2023-09-25T12:00:00.000Z', + level: 'ERROR', + requestId: 'structured logging request id', + message: { + errorType: 'SyntaxError', + errorMessage: 'user syntax error', + stackTrace: err.stack.split('\n'), + code: 123, + }, + }), + ); + }); + }); +}); diff --git a/test/unit/LoggingGlobals.js b/test/unit/LoggingGlobals.js new file mode 100644 index 00000000..7ffce3da --- /dev/null +++ b/test/unit/LoggingGlobals.js @@ -0,0 +1,87 @@ +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +/** + * Testing logging in unit tests requires manipulating the global console and + * stdout objects. + * This module provides methods for safely capturing and restoring these + * objects under test. + */ + +const levels = Object.freeze({ + TRACE: { name: 'TRACE' }, + DEBUG: { name: 'DEBUG' }, + INFO: { name: 'INFO' }, + WARN: { name: 'WARN' }, + ERROR: { name: 'ERROR' }, + FATAL: { name: 'FATAL' }, +}); + +const formats = Object.freeze({ + TEXT: { name: 'TEXT' }, + JSON: { name: 'JSON' }, +}); + +module.exports.consoleSnapshot = () => { + let log = console.log; + let debug = console.debug; + let info = console.info; + let warn = console.warn; + let error = console.error; + let trace = console.trace; + let fatal = console.fatal; + + return function restoreConsole() { + console.log = log; + console.debug = debug; + console.info = info; + console.warn = warn; + console.error = error; + console.trace = trace; + console.fatal = fatal; + }; +}; + +/** + * Capture all of the writes to a given stream. + */ +module.exports.captureStream = function captureStream(stream) { + let originalWrite = stream.write; + let buf = ''; + return { + hook: () => { + buf = ''; // reset the buffer + stream.write = function (chunk, _encoding, _callback) { + buf += chunk.toString(); + originalWrite.apply(stream, arguments); + }; + }, + unhook: () => (stream.write = originalWrite), + captured: () => buf, + resetBuffer: () => (buf = ''), + }; +}; + +module.exports.loggingConfig = class loggingConfig { + turnOnStructuredLogging() { + process.env['AWS_LAMBDA_LOG_FORMAT'] = formats.JSON.name; + } + + turnOffStructuredLogging() { + delete process.env['AWS_LAMBDA_LOG_FORMAT']; + } + + setLogLevel(level) { + if (levels[level] === undefined) { + return; + } + process.env['AWS_LAMBDA_LOG_LEVEL'] = levels[level].name; + } + + resetLogLevel() { + delete process.env['AWS_LAMBDA_LOG_LEVEL']; + } +}; diff --git a/test/unit/RAPIDClientTest.js b/test/unit/RAPIDClientTest.js new file mode 100644 index 00000000..a5851c0e --- /dev/null +++ b/test/unit/RAPIDClientTest.js @@ -0,0 +1,213 @@ +/** + * Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +require('should'); + +let RAPIDClient = require('lambda-runtime/RAPIDClient.js'); +let runtimeErrors = require('lambda-runtime/Errors.js'); + +/** + * Stub request object. + * Provides no-op definitions of the request functions used by the rapid client. + */ +const noOpRequest = Object.freeze({ + /* no op, return itself to allow continuations/chaining */ + on: () => noOpRequest, + /* no op, return itself to allow continuations/chaining */ + end: () => noOpRequest, +}); + +class StubHttp { + constructor() { + this.lastUsedOptions = {}; + this.Agent = class FakeAgent {}; + } + + request(options, _callback) { + this.lastUsedOptions = options; + return noOpRequest; + } +} + +class NoOpNativeHttp { + constructor() { + this.lastRequestId = ''; + this.lastErrorRequestId = ''; + } + + done(requestId) { + this.lastRequestId = requestId; + } + + error(requestId) { + this.lastErrorRequestId = requestId; + } +} + +class MockNativeClient { + constructor(response) { + this.response = response; + this.called = false; + this.shouldThrowError = false; + } + + next() { + this.called = true; + if (this.shouldThrowError) { + return Promise.reject(new Error('Failed to get next invocation')); + } else { + return Promise.resolve(this.response); + } + } +} + +class EvilError extends Error { + get name() { + throw 'gotcha'; + } +} + +const EXPECTED_ERROR_HEADER = 'Lambda-Runtime-Function-Error-Type'; + +describe('building error requests with the RAPIDClient', () => { + let stubHttp = new StubHttp(); + let client = new RAPIDClient('notUsed:1337', stubHttp, new NoOpNativeHttp()); + + let errors = [ + [new Error('generic failure'), 'Error'], + [new runtimeErrors.ImportModuleError(), 'Runtime.ImportModuleError'], + [new runtimeErrors.HandlerNotFound(), 'Runtime.HandlerNotFound'], + [new runtimeErrors.MalformedHandlerName(), 'Runtime.MalformedHandlerName'], + [new runtimeErrors.UserCodeSyntaxError(), 'Runtime.UserCodeSyntaxError'], + [{ data: 'some random object' }, 'object'], + [new EvilError(), 'handled'], + ]; + + describe('the error header in postInitError', () => { + errors.forEach(([error, name]) => { + it(`should be ${name} for ${error.constructor.name}`, () => { + client.postInitError(error); + stubHttp.lastUsedOptions.should.have + .property('headers') + .have.property(EXPECTED_ERROR_HEADER, name); + }); + }); + }); +}); + +describe('invalid request id works', () => { + const nativeClient = new NoOpNativeHttp(); + const client = new RAPIDClient('notUsed:1337', undefined, nativeClient); + + [ + // Encoding expected: + ['#', '%23'], + ['%', '%25'], + ['/', '%2F'], + ['?', '%3F'], + ['\x7F', '%7F'], + ["", "%3Cscript%3Ealert('1')%3C%2Fscript%3E"], + ['⚡', '%E2%9A%A1'], + + // No encoding: + ['.', '.'], + ['..', '..'], + ['a', 'a'], + [ + '59b22c65-fa81-47fb-a6dc-23028a63566f', + '59b22c65-fa81-47fb-a6dc-23028a63566f', + ], + ].forEach(([requestId, expected]) => { + it(`postInvocationResponse should encode requestId: '${requestId}'`, () => { + client.postInvocationResponse({}, requestId, () => {}); + nativeClient.lastRequestId.should.be.equal(expected); + }); + + it(`postInvocationError should encode requestId: '${requestId}'`, () => { + client.postInvocationError(new Error(), requestId, () => {}); + nativeClient.lastErrorRequestId.should.be.equal(expected); + }); + }); +}); + +describe('next invocation with native client works', () => { + it('should call the native client next() method', async () => { + const mockNative = new MockNativeClient({ + bodyJson: '', + headers: { + 'lambda-runtime-aws-request-id': 'test-request-id', + }, + }); + const client = new RAPIDClient('notUsed:1337', undefined, mockNative); + client.useAlternativeClient = false; + + await client.nextInvocation(); + // verify native client was called + mockNative.called.should.be.true(); + }); + it('should parse all required headers', async () => { + const mockResponse = { + bodyJson: '{"message":"Hello from Lambda!"}', + headers: { + 'lambda-runtime-aws-request-id': 'test-request-id', + 'lambda-runtime-deadline-ms': 1619712000000, + 'lambda-runtime-trace-id': 'test-trace-id', + 'lambda-runtime-invoked-function-arn': 'test-function-arn', + 'lambda-runtime-client-context': '{"client":{"app_title":"MyApp"}}', + 'lambda-runtime-cognito-identity': + '{"identityId":"id123","identityPoolId":"pool123"}', + 'lambda-runtime-aws-tenant-id': 'test-tenant-id', + }, + }; + + const mockNative = new MockNativeClient(mockResponse); + const client = new RAPIDClient('notUsed:1337', undefined, mockNative); + + client.useAlternativeClient = false; + const response = await client.nextInvocation(); + + // Verify all headers are present + response.headers.should.have.property( + 'lambda-runtime-aws-request-id', + 'test-request-id', + ); + response.headers.should.have.property( + 'lambda-runtime-deadline-ms', + 1619712000000, + ); + response.headers.should.have.property( + 'lambda-runtime-trace-id', + 'test-trace-id', + ); + response.headers.should.have.property( + 'lambda-runtime-invoked-function-arn', + 'test-function-arn', + ); + response.headers.should.have.property( + 'lambda-runtime-client-context', + '{"client":{"app_title":"MyApp"}}', + ); + response.headers.should.have.property( + 'lambda-runtime-cognito-identity', + '{"identityId":"id123","identityPoolId":"pool123"}', + ); + response.headers.should.have.property( + 'lambda-runtime-aws-tenant-id', + 'test-tenant-id', + ); + // Verify body is correctly passed through + response.bodyJson.should.equal('{"message":"Hello from Lambda!"}'); + }); + it('should handle native client errors', async () => { + const nativeClient = new MockNativeClient({}); + nativeClient.shouldThrowError = true; + + const client = new RAPIDClient('localhost:8080', null, nativeClient); + client.useAlternativeClient = false; + + await client.nextInvocation().should.be.rejectedWith('Failed to get next invocation'); + }); +}); diff --git a/test/unit/ResponseStreamTest.js b/test/unit/ResponseStreamTest.js new file mode 100644 index 00000000..b5d46c26 --- /dev/null +++ b/test/unit/ResponseStreamTest.js @@ -0,0 +1,577 @@ +/** + * Copyright 2021-2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +require('should'); +const ServerMock = require('mock-http-server'); +const { + createResponseStream, + tryCallFail, +} = require('lambda-runtime/ResponseStream.js'); +const { HttpResponseStream } = require('lambda-runtime/HttpResponseStream.js'); +const { InvalidStreamingOperation } = require('lambda-runtime/Errors.js'); +const { verbose, vverbose, vvverbose } = require('lambda-runtime/VerboseLog').logger( + 'TEST', +); +const Throttle = require('throttle'); +const pipeline = require('util').promisify(require('stream').pipeline); +const { Readable } = require('stream'); +const { Buffer } = require('buffer'); +const http = require('http'); + +/** + * Node.js 17 changed the default DNS resolution ordering from always prioritizing ipv4 to the ordering + * returned by the DNS provider. In some environments, this can result in `localhost` resolving to + * an ipv6 address instead of ipv4 and a consequent failure to connect to the server. + * Hence, using `127.0.0.1` in place of localhost. + * ref: https://github.com/nodejs/node/pull/39987 + */ +const HOSTNAME = '127.0.0.1'; +const PATH = '/asd/efg'; + +const createStream = (port, options) => { + const { + request: stream, + headersDone, + responseDone: streamDone, + } = createResponseStream({ + httpOptions: { + hostname: HOSTNAME, + port, + path: PATH, + method: options?.method || 'POST', + http: options?.http || require('http'), + agent: new http.Agent({ + // keepAlive: true, + // maxSockets: 1, + }), + }, + contentType: options?.contentType, + }); + + return { stream, headersDone, streamDone }; +}; + +const streamSpy = (name, stream) => + stream + .on('end', () => verbose(name, 'ended')) + .on('close', () => verbose(name, 'closed')) + .on('finish', () => verbose(name, 'finished')) + .on('drain', () => verbose(name, 'drained')) + .on('error', () => verbose(name, 'errored')) + .on('pause', () => verbose(name, 'paused')) + .on('readable', () => verbose(name, 'readabled')) + .on('resume', () => verbose(name, 'resumed')); + +const assertStream = async (port, useStream) => { + const { stream, headersDone, streamDone } = createStream(port); + streamSpy('test stream', stream); + + vverbose('assertStream 1'); + await useStream(stream); + vverbose('assertStream 2'); + + // auto-close. + stream.end(); + vverbose('assertStream 3'); + + const info = await headersDone; + vverbose('assertStream 4'); + + const body = await streamDone; + vverbose('assertStream 5'); + + const response = { + statusCode: info.statusCode, + headers: info.headers, + body, + }; + vverbose('assertStream 6'); + return response; +}; + +const destroyConnections = (server) => { + server.connections().forEach((c) => c.destroy()); +}; + +describe('stream - throws uncaughtException', () => { + const server = new ServerMock({ host: HOSTNAME, port: 0 }); + let originalListener; + + before(function (done) { + server.start(done); + }); + after(function () { + process.addListener('uncaughtException', originalListener); + }); + + it('no end will timeout', function (done) { + this.timeout(1000); //increase timeout. + + originalListener = process.listeners('uncaughtException').pop(); + process.removeListener('uncaughtException', originalListener); + + const { stream, streamDone } = createStream(server.getHttpPort()); + streamSpy('ender', stream); + stream.setContentType('moon/dust'); + + // Write to the stream, do not call .end + stream.write(Buffer.from([1])); + + process.prependOnceListener('uncaughtException', (err) => { + should(err).be.not.empty(); + err.code.should.be.equal('ECONNRESET'); + }); + + setTimeout(() => { + stream.writableFinished.should.be.false(); + stream.end(); + streamDone.then(() => { + destroyConnections(server); + server.stop(done); + }); + }, 500); + }); +}); + +describe('stream/pipeline', function () { + this.timeout(10000); + + const server = new ServerMock({ host: HOSTNAME, port: 0 }); + + beforeEach(function (done) { + server.start(done); + }); + + afterEach(function (done) { + server.stop(done); + }); + + it('can pipeline', async () => { + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.setContentType('application/octet-stream'); + const input = Readable.from(Buffer.from('moon')); + + await pipeline(input, stream); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].body.should.be.equal('moon'); + }); + + it('can pipeline with throttle', async () => { + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.setContentType('application/octet-stream'); + const input = Readable.from(Buffer.from('moon '.repeat(1000))); + + await pipeline(input, new Throttle({ bps: 20000, chunkSize: 2 }), stream); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].body.should.be.equal('moon '.repeat(1000)); + }); + + it('can pipeline with throttle 2', async () => { + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.setContentType('application/octet-stream'); + const input = Readable.from(Buffer.from('moon')); + + await pipeline(input, new Throttle({ bps: 1, chunkSize: 1 }), stream); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].body.should.be.equal('moon'); + }); + + it('can pipeline generator function', async () => { + async function* generateContent() { + // Push 1 MiB of data in 1 KiB chunks + for (let i = 1; i <= 100; i++) { + yield (i % 10).toString().repeat(1024); // push 1 KiB to the stream + } + } + + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.setContentType('application/octet-stream'); + + const input = generateContent(); + + await pipeline(input, stream); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + + let expected = ''; + for await (let s of generateContent()) { + expected += s; + } + reqs[0].body.should.be.equal(expected); + }); +}); + +describe('stream', () => { + const server = new ServerMock({ host: HOSTNAME, port: 0 }); + + beforeEach(function (done) { + server.start(done); + }); + + afterEach(function (done) { + server.stop(done); + }); + + it('write returns true', async () => { + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.setContentType('application/octet-stream'); + + const result = stream.write('moon'); + result.should.be.true(); + + await new Promise((r) => stream.end(r)); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + + reqs[0].body.should.be.equal('moon'); + }); + + it('default content type', (done) => { + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.end(() => { + streamDone.then(() => { + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].headers['content-type'].should.be.equal( + 'application/octet-stream', + ); + reqs[0].headers[ + 'lambda-runtime-function-response-mode' + ].should.be.equal('streaming'); + + done(); + }); + }); + }); + + it('expect error trailer', async () => { + const { stream, streamDone } = createStream(server.getHttpPort()); + + await new Promise((r) => stream.end(r)); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].headers['trailer'].should.be.equal( + 'Lambda-Runtime-Function-Error-Type, Lambda-Runtime-Function-Error-Body', + ); + reqs[0].headers['lambda-runtime-function-response-mode'].should.be.equal( + 'streaming', + ); + }); + + it('chunked encoding', async () => { + const { stream, streamDone } = createStream(server.getHttpPort()); + + await new Promise((r) => stream.end(r)); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].headers['transfer-encoding'].should.be.equal('chunked'); + reqs[0].headers['lambda-runtime-function-response-mode'].should.be.equal( + 'streaming', + ); + }); + + it("setContentType doesn't throw when constructed", async () => { + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.setContentType('moon/dust'); + + await new Promise((r) => stream.end(r)); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].headers['content-type'].should.be.equal('moon/dust'); + reqs[0].headers['lambda-runtime-function-response-mode'].should.be.equal( + 'streaming', + ); + }); + + it('content type from options', async () => { + const { stream, streamDone } = createStream(server.getHttpPort(), { + contentType: 'moon/dust', + }); + + await new Promise((r) => stream.end(r)); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].headers['content-type'].should.be.equal('moon/dust'); + reqs[0].headers['lambda-runtime-function-response-mode'].should.be.equal( + 'streaming', + ); + }); + + it('override content type from options', async () => { + const { stream, streamDone } = createStream(server.getHttpPort(), { + contentType: 'moon/flake', + }); + stream.setContentType('moon/dust'); + + await new Promise((r) => stream.end(r)); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].headers['content-type'].should.be.equal('moon/dust'); + reqs[0].headers['lambda-runtime-function-response-mode'].should.be.equal( + 'streaming', + ); + }); + + it('override content type, metadata prelude', async () => { + let { stream, streamDone } = createStream(server.getHttpPort(), { + contentType: 'moon/flake', + }); + stream = HttpResponseStream.from(stream, { + loc: 'mare\x00tranquillitatis', + }); + + stream.write('ABC'); + + await new Promise((r) => stream.end(r)); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + + reqs[0].headers['content-type'].should.be.equal( + 'application/vnd.awslambda.http-integration-response', + ); + reqs[0].headers['lambda-runtime-function-response-mode'].should.be.equal( + 'streaming', + ); + + // Null in the object value is escaped, prelude added followed by a null byte. + reqs[0].body.should.be.equal( + '{"loc":"mare\\u0000tranquillitatis"}\u0000\u0000\u0000\u0000\u0000\u0000\x00\u0000ABC', + ); + }); + + it('metadata prelude, do not use return value', async () => { + let { stream, streamDone } = createStream(server.getHttpPort()); + + // Ignore the return value. + HttpResponseStream.from(stream, { + loc: 'mare\x00tranquillitatis', + }); + + stream.write('ABC'); + + await new Promise((r) => stream.end(r)); + await streamDone; + + const reqs = server.requests(); + reqs.length.should.be.equal(1); + + reqs[0].headers['content-type'].should.be.equal( + 'application/vnd.awslambda.http-integration-response', + ); + reqs[0].headers['lambda-runtime-function-response-mode'].should.be.equal( + 'streaming', + ); + + // Null in the object value is escaped, prelude added followed by a null byte. + reqs[0].body.should.be.equal( + '{"loc":"mare\\u0000tranquillitatis"}\x00\x00\x00\x00\x00\x00\x00\x00ABC', + ); + }); + + it('setContentType throws after first write', (done) => { + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.write(Buffer.from(JSON.stringify({}))); + should(() => stream.setContentType('moon/trust')).throw({ + name: 'Runtime.InvalidStreamingOperation', + message: 'Cannot set content-type, too late.', + }); + stream.end(() => streamDone.then(() => done())); + }); + + it('setContentType throws after first write, non-default', (done) => { + const { stream, streamDone } = createStream(server.getHttpPort()); + stream.setContentType('moon/dust'); + stream.write(Buffer.from([1, 2, 3, 2, 1])); + should(() => stream.setContentType('moon/trust')).throw({ + name: 'Runtime.InvalidStreamingOperation', + message: 'Cannot set content-type, too late.', + }); + stream.end(() => streamDone.then(() => done())); + }); + + it('send error in trailer', (done) => { + const { stream, streamDone } = createStream(server.getHttpPort(), {}); + tryCallFail(stream, 42); + stream.end(() => { + streamDone.then(() => { + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].trailers['lambda-runtime-function-error-type'].should.be.equal( + 'number', + ); + const body = JSON.parse( + Buffer.from( + reqs[0].trailers['lambda-runtime-function-error-body'], + 'base64', + ).toString(), + ); + + body.should.be.eql({ + errorType: 'number', + errorMessage: '42', + trace: [], + }); + + done(); + }); + }); + }); + + it('send InvalidStreamingOperation in trailer', (done) => { + const { stream, streamDone } = createStream(server.getHttpPort(), {}); + tryCallFail( + stream, + new InvalidStreamingOperation('Cannot set content-type, too late.'), + ); + stream.end(() => { + streamDone.then(() => { + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].trailers['lambda-runtime-function-error-type'].should.be.equal( + 'Runtime.InvalidStreamingOperation', + ); + const body = JSON.parse( + Buffer.from( + reqs[0].trailers['lambda-runtime-function-error-body'], + 'base64', + ).toString(), + ); + + body.errorType.should.be.equal('Runtime.InvalidStreamingOperation'); + body.errorMessage.should.be.equal('Cannot set content-type, too late.'); + body.trace.should.be.not.empty(); + + done(); + }); + }); + }); + + it('send error in trailer, callback from fail', (done) => { + const { stream, streamDone } = createStream(server.getHttpPort(), {}); + tryCallFail(stream, 42, () => { + streamDone.then(() => { + const reqs = server.requests(); + reqs.length.should.be.equal(1); + reqs[0].trailers['lambda-runtime-function-error-type'].should.be.equal( + 'number', + ); + + const body = JSON.parse( + Buffer.from( + reqs[0].trailers['lambda-runtime-function-error-body'], + 'base64', + ).toString(), + ); + + body.should.be.eql({ + errorType: 'number', + errorMessage: '42', + trace: [], + }); + + done(); + }); + }); + }); + + const TypeErrorMsg = + 'The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Object'; + [0, 1, 2, 100, 1000].forEach((repeat) => { + [ + { + name: 'object, should fail', + value: { moon: 'dust' }, + error: { code: 'ERR_INVALID_ARG_TYPE', message: TypeErrorMsg }, + }, + { + name: 'string', + value: JSON.stringify({ moon: 'dust' }), + expected: '{"moon":"dust"}', + }, + { + name: 'buffer', + value: Buffer.from(JSON.stringify({ moon: 'dust' })), + expected: '{"moon":"dust"}', + }, + { + name: 'Uint8Array', + value: new TextEncoder().encode(JSON.stringify({ moon: 'dust' })), + expected: '{"moon":"dust"}', + }, + ].forEach((v) => { + it(`write ${repeat} ${v.name}`, async () => { + server.on({ + method: 'POST', + path: PATH, + reply: { + status: 200, + headers: { 'content-type': 'application/octet-stream' }, + body: (req) => { + return req.body; + }, + }, + }); + + const response = await assertStream(server.getHttpPort(), (stream) => { + stream.setContentType('moon/sparkle'); + for (let i = 1; i <= repeat; i++) { + try { + stream.write(v.value); + } catch (err) { + if (!v.error) { + throw err; + } + + if (v.error.code) { + err.code.should.be.equal(v.error.code); + } + if (v.error.message) { + err.message.should.be.equal(v.error.message); + } + } + } + stream.end(); + }); + + vvverbose('response', response); + response.statusCode.should.be.equal(200); + + if (v.error) { + return; + } + const expected = v.expected.repeat(repeat); + const body = response.body ? response.body.toString('utf-8') : ''; + + body.should.be.equal(expected); + }); + }); + }); +}); diff --git a/test/unit/Runtime/BeforeExitListener.test.ts b/test/unit/Runtime/BeforeExitListener.test.ts deleted file mode 100644 index bfd00c5d..00000000 --- a/test/unit/Runtime/BeforeExitListener.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -require("should"); - -describe("Invoke the BeforeExitListener", () => { - it("should not fail if a listerner has not been set", async () => { - const beforeExitListenerModule = await import( - "../../../src/Runtime/BeforeExitListener" - ); - const beforeExitListener = beforeExitListenerModule.default; - - beforeExitListener.invoke(); - }); - - it("should use the listener", async () => { - let count = 0; - const listener = () => { - count++; - }; - - const beforeExitListenerModule = await import( - "../../../src/Runtime/BeforeExitListener" - ); - const beforeExitListener = beforeExitListenerModule.default; - - beforeExitListener.set(listener); - - beforeExitListener.invoke(); - count.should.be.equal(1); - - beforeExitListener.invoke(); - count.should.be.equal(2); - }); - - it("should use the same listener even when imported again", async () => { - let count = 0; - const listener = () => { - count++; - }; - - const beforeExitListenerModule = await import( - "../../../src/Runtime/BeforeExitListener" - ); - const beforeExitListener = beforeExitListenerModule.default; - - beforeExitListener.set(listener); - beforeExitListener.invoke(); - - const secondImport = await import( - "../../../src/Runtime/BeforeExitListener" - ); - const secondBeforeExitListener = secondImport.default; - - secondBeforeExitListener.invoke(); - count.should.be.equal(2); - }); -}); diff --git a/test/unit/Runtime/CallbackContext.test.ts b/test/unit/Runtime/CallbackContext.test.ts deleted file mode 100644 index c650b5fc..00000000 --- a/test/unit/Runtime/CallbackContext.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -import { IncomingHttpHeaders } from "http"; -import BeforeExitListener from "../../../src/Runtime/BeforeExitListener"; -import { IRuntimeClient } from "../../../src/RuntimeClient"; -import { - InvocationResponse, - CallbackFunction, - ICallbackContext, -} from "../../../src/Common"; -import { build as buildCallBackContext } from "../../../src/Runtime/CallbackContext"; - -require("should"); - -class RuntimeClientStub implements IRuntimeClient { - lastId?: string; - lastError?: any; - lastResponse?: string; - - nextInvocation(): Promise { - return Promise.resolve({ - bodyJson: "{ 'this': 'is a test' }", - headers: {} as IncomingHttpHeaders, - }); - } - postInvocationError(error: unknown, id: string, callback: () => void): void { - this.lastId = id; - this.lastError = error; - callback(); - } - - postInvocationResponse( - response: unknown, - id: string, - callback: () => void - ): void { - this.lastId = id; - this.lastResponse = JSON.stringify(response); - callback(); - } -} - -describe("Executing the callback", () => { - let scheduledNextCalled = false; - const scheduleNext = () => { - scheduledNextCalled = true; - }; - - const dummyExecutionId = "some id"; - let callback: CallbackFunction; - let context: ICallbackContext; - let client: RuntimeClientStub; - - beforeEach(() => { - scheduledNextCalled = false; - client = new RuntimeClientStub(); - [callback, context] = buildCallBackContext( - client, - dummyExecutionId, - scheduleNext - ); - }); - - it("should call the client with the correct response.", async () => { - callback(null, "response"); - - scheduledNextCalled.should.be.false(); - client.lastResponse?.should.equal('"response"'); - client.lastId?.should.equal(dummyExecutionId); - client.lastError?.should.be.null(); - - BeforeExitListener.invoke(); - scheduledNextCalled.should.be.true(); - }); - - it("should not allow the callback to be executed more than once.", async () => { - callback(null, "response"); - callback(null, "Second time"); - - client.lastResponse?.should.equal('"response"'); - }); - - it("should immediatelly schedule the next invocation when setting the callbackWaitsForEmptyEventLoop to false.", async () => { - context.callbackWaitsForEmptyEventLoop = false; - callback(null, "response when not waiting"); - - client.lastResponse?.should.equal('"response when not waiting"'); - scheduledNextCalled.should.be.true(); - }); - - it("should call the client with correct error when the error is defined.", () => { - const myError = new Error("This is an error"); - - callback(myError); - - client.lastResponse?.should.be.null(); - client.lastError?.should.equal(myError); - }); - - it("should not wrap an error string into a generic Error.", () => { - callback("This is an error"); - - client.lastResponse?.should.be.null(); - client.lastError?.should.equal("This is an error"); - }); -}); diff --git a/test/unit/Runtime/InvokeContext.test.ts b/test/unit/Runtime/InvokeContext.test.ts deleted file mode 100644 index b0aa5bff..00000000 --- a/test/unit/Runtime/InvokeContext.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -require("should"); -import utilModule from "util"; - -const sleep = utilModule.promisify(setTimeout); - -import InvokeContext from "../../../src/Runtime/InvokeContext"; - -describe("Getting remaining invoke time", () => { - it("should reduce by at least elapsed time", async () => { - const ctx = new InvokeContext({ - "lambda-runtime-deadline-ms": (Date.now() + 1000).toString(), - }); - - const timeout = 100 * 1.05; // 5% margin of error - const before = ctx.headerData.getRemainingTimeInMillis(); - await sleep(timeout); - const after = ctx.headerData.getRemainingTimeInMillis(); - (before - after).should.greaterThanOrEqual(100); - }); - - it("should return NaN when the deadline is not defined?", async () => { - const ctx = new InvokeContext({}); - const remaining = ctx.headerData.getRemainingTimeInMillis(); - - remaining.should.be.NaN(); - }); - - it("should be within range.", () => { - const ctx = new InvokeContext({ - "lambda-runtime-deadline-ms": (Date.now() + 1000).toString(), - }); - - const remainingTime = ctx.headerData.getRemainingTimeInMillis(); - - remainingTime.should.greaterThan(0); - remainingTime.should.lessThanOrEqual(1000); - }); -}); diff --git a/test/unit/RuntimeClient/RuntimeClient.test.ts b/test/unit/RuntimeClient/RuntimeClient.test.ts deleted file mode 100644 index 9d046c38..00000000 --- a/test/unit/RuntimeClient/RuntimeClient.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -require("should"); -import RuntimeClient from "../../../src/RuntimeClient"; -import * as runtimeErrors from "../../../src/Errors"; -import { StubHttp } from "../utils/StubHttp"; -import { NoOpNativeHttp } from "../utils/NoOpNativeHttp"; - -class EvilError extends Error { - get name(): string { - throw "gotcha"; - } -} - -const EXPECTED_ERROR_HEADER = "Lambda-Runtime-Function-Error-Type"; - -describe("building error requests with the RuntimeClient", () => { - const stubHttp = new StubHttp(); - const client = new RuntimeClient( - "notUsed:1337", - stubHttp, - new NoOpNativeHttp() - ); - - const errors: Array<[Error, string]> = [ - [new Error("generic failure"), "Error"], - [new runtimeErrors.ImportModuleError(), "Runtime.ImportModuleError"], - [new runtimeErrors.HandlerNotFound(), "Runtime.HandlerNotFound"], - [new runtimeErrors.MalformedHandlerName(), "Runtime.MalformedHandlerName"], - [new runtimeErrors.UserCodeSyntaxError(), "Runtime.UserCodeSyntaxError"], - [({ data: "some random object" } as unknown) as Error, "object"], - [new EvilError(), "handled"], - ]; - - describe("the error header in postInitError", () => { - errors.forEach(([error, name]) => { - it(`should be ${name} for ${error.constructor.name}`, () => { - client.postInitError(error, () => { - // No op - }); - stubHttp.lastUsedOptions.should.have - .property("headers") - .have.property(EXPECTED_ERROR_HEADER, name); - }); - }); - }); -}); diff --git a/test/unit/StreamingContextTest.js b/test/unit/StreamingContextTest.js new file mode 100644 index 00000000..833ac8f7 --- /dev/null +++ b/test/unit/StreamingContextTest.js @@ -0,0 +1,123 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +require('should'); +const StreamingContext = require('lambda-runtime/StreamingContext.js'); +const { PassThrough } = require('stream'); +const BeforeExitListener = require('lambda-runtime/BeforeExitListener.js'); + +class MockRapidClient { + constructor() { + this.sentErrors = []; + this.responseStream = new PassThrough(); + this.responseStream.fail = (err, callback) => { + this.sentErrors.push({ err }); + callback(); + }; + } + + getStreamForInvocationResponse() { + return { request: this.responseStream, responseDone: undefined }; + } +} + +describe('StreamingContext', () => { + it('can set callbackWaitsForEmptyEventLoop', () => { + const ctx = StreamingContext.build(); + + ctx.callbackWaitsForEmptyEventLoop = true; + ctx.callbackWaitsForEmptyEventLoop.should.be.equal(true); + + ctx.callbackWaitsForEmptyEventLoop = false; + ctx.callbackWaitsForEmptyEventLoop.should.be.equal(false); + }); + + it('can create stream', () => { + const id = '12-3-4-56'; + const client = new MockRapidClient(); + const ctx = StreamingContext.build( + client, + id, + () => {}, + JSON.stringify({}), + ); + const stream = ctx.createStream(); + should(stream).not.be.empty(); + }); + + it('cannot create stream more than once', () => { + const id = '12-3-4-56'; + const client = new MockRapidClient(); + const ctx = StreamingContext.build( + client, + id, + () => {}, + JSON.stringify({}), + ); + const stream = ctx.createStream(); + should(stream).not.be.empty(); + + for (let i = 0; i < 5; i++) { + should(() => ctx.createStream()).throw({ + message: + 'Cannot create stream for the same StreamingContext more than once.', + }); + } + }); + + [true, false].forEach((callbackWaitsForEmptyEventLoop) => + [ + { + error: new Error('too much sun'), + expected: 'too much sun', + }, + { + error: 'too much sun', + expected: 'too much sun', + }, + ].forEach((v) => + it(`can call next after fail (callbackWaitsForEmptyEventLoop: ${callbackWaitsForEmptyEventLoop}, error: ${typeof v.error})`, () => { + // This test will print "Invoke Error" to stderr which is to be expected. + + let nextCalled = 0; + const ID = '12-3-4-56'; + const client = new MockRapidClient(); + const ctx = StreamingContext.build( + client, + ID, + () => nextCalled++, + JSON.stringify({}), + ); + ctx.callbackWaitsForEmptyEventLoop = callbackWaitsForEmptyEventLoop; + const { scheduleNext, fail } = ctx.createStream(); + + fail(v.error, scheduleNext); + client.responseStream.fail(v.error, scheduleNext); + + const verify = () => { + nextCalled.should.be.equal(1); + + console.log('client.sentErrors', client.sentErrors); + console.log('client.invocationErrors', client.invocationErrors); + + client.sentErrors.length.should.be.equal(1); + if (typeof v.error === 'string') { + client.sentErrors[0].err.should.be.equal(v.expected); + } else { + client.sentErrors[0].err.message.should.be.equal(v.expected); + } + }; + + if (v) { + BeforeExitListener.invoke(); + setImmediate(() => verify()); + } else { + verify(); + } + }), + ), + ); +}); diff --git a/test/unit/UserFunctionTest.js b/test/unit/UserFunctionTest.js new file mode 100644 index 00000000..1916866f --- /dev/null +++ b/test/unit/UserFunctionTest.js @@ -0,0 +1,431 @@ +/** + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ + +'use strict'; + +require('should'); +const path = require('path'); +const { + HandlerNotFound, + ImportModuleError, + MalformedHandlerName, + UserCodeSyntaxError, +} = require('lambda-runtime/Errors.js'); +const UserFunction = require('lambda-runtime/UserFunction.js'); + +const TEST_ROOT = path.join(__dirname, '../'); +const HANDLERS_ROOT = path.join(TEST_ROOT, 'handlers'); + +describe('UserFunction.load method', () => { + const echoTestMessage = 'This is a echo test'; + it('should successfully load a user function', async () => { + const handler = await UserFunction.load(HANDLERS_ROOT, 'core.echo'); + const response = await handler(echoTestMessage); + + response.should.equal(echoTestMessage); + }); + + it('should successfully load a user function nested in an object', async () => { + const handler = await UserFunction.load( + HANDLERS_ROOT, + 'nestedHandler.nested.somethingComplex.handler', + ); + const response = await handler(); + + response.should.equal('something interesting'); + }); + + it('should successfully load a user function with a path to the module', async () => { + const handler = await UserFunction.load( + TEST_ROOT, + 'handlers/nestedHandler.nested.somethingComplex.handler', + ); + const response = await handler(); + + response.should.equal('something interesting'); + }); + + it("should throw a MalformedHandlerName error if the handler string contains '..'", () => { + UserFunction.load( + HANDLERS_ROOT, + 'malformed..handler', + ).should.be.rejectedWith(MalformedHandlerName); + }); + + it('should throw a MalformedHandlerName error if the handler string does not contain a dot', () => { + UserFunction.load(HANDLERS_ROOT, 'malformedHandler').should.be.rejectedWith( + MalformedHandlerName, + ); + }); + + it('should throw a MalformedHandlerName error if the path to the handler does not exists and malformed handler', () => { + UserFunction.load( + path.join(HANDLERS_ROOT, 'non/existent/path'), + 'malformedHandler', + ).should.be.rejectedWith(MalformedHandlerName); + }); + + it('should throw a ImportModuleError error if the module does not exists', () => { + UserFunction.load(HANDLERS_ROOT, 'noModule.echo').should.be.rejectedWith( + ImportModuleError, + ); + }); + + it('should throw a HandlerNotFound error if the handler does not exists', () => { + UserFunction.load( + HANDLERS_ROOT, + 'nestedHandler.nested.somethingComplex.nonHandler', + ).should.be.rejectedWith(HandlerNotFound); + }); + + it('should throw a HandlerNotFound error if the handler is not a function', () => { + UserFunction.load( + HANDLERS_ROOT, + 'core.noFunctionHandler', + ).should.be.rejectedWith(HandlerNotFound); + }); + + it('should successfully load a user function in an ES module in a file with .mjs extension', async () => { + const handler = await UserFunction.load(HANDLERS_ROOT, 'esModule.echo'); + const response = await handler(echoTestMessage); + + response.should.equal(echoTestMessage); + }); + + it('should successfully load a user function CommonJS module in a file with .cjs extension', async () => { + const handler = await UserFunction.load(HANDLERS_ROOT, 'cjsModule.echo'); + const response = await handler(echoTestMessage); + + response.should.equal(echoTestMessage); + }); + + it('should default to load the cjs module without extension', async () => { + // There are multiple files named precendence with different extensions + // and the .js file should have precedence over all but the current implementation gives + // priority to files without extension. + const handler = await UserFunction.load( + HANDLERS_ROOT, + 'precedence.handler', + ); + const response = await handler(); + + // Currently files without extension have higher precedence over .js files + response.should.equal("I don't have a .js file suffix"); + }); + + it('should default to load the .js file over the .mjs module', async () => { + // The .js file should be loaded instead of the .mjs file + const handler = await UserFunction.load( + HANDLERS_ROOT, + 'precedenceJsVsMjs.handler', + ); + const response = await handler(); + + response.should.equal('I do have a .js file suffix'); + }); + + it('should default to load the .mjs file over the .cjs module', async () => { + // The .mjs file should be loaded instead of the .cjs file + const handler = await UserFunction.load( + HANDLERS_ROOT, + 'precedenceMjsVsCjs.handler', + ); + const response = await handler(); + + response.should.equal('I do have a .mjs file suffix'); + }); + + it('should support init', async () => { + // The asyncInit module has a top level await on a timer to set a flag + // If at the time of invocation, the flag is not set, the handler will throw an Error + const handler = await UserFunction.load(HANDLERS_ROOT, 'asyncInit.handler'); + const response = await handler(); + + response.should.equal('Hi'); + }); + + it('should support init in .js files in packages using the module type', async () => { + // The asyncInit module has a top level await on a timer to set a flag + // If at the time of invocation, the flag is not set, the handler will throw an Error + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'async_init_package'), + 'index.handler', + ); + const response = await handler(); + + response.should.equal('Hi'); + }); + + it('should support init in .js files in packages using the module type, nested', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'async_init_package/nested'), + 'index.handler', + ); + handler().should.be.resolvedWith(42); + }); + + it('should support init in .js files in packages using the module type, nested even more', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'async_init_package/nested/even/more'), + 'index.handler', + ); + handler().should.be.equal(42); + }); + + it('should support init in .js files in packages using the module type, nested even more + moduleRoot', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'async_init_package/nested'), + 'even/more/index.handler', + ); + handler().should.be.equal(42); + }); + + it('should use commonjs when package.json cannot be read', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'async_init_type_not_module'), + 'index.ret42', + ); + handler().should.be.equal(42); + }); + + it('should use commonjs when node_modules is reached before package.json', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'async_init_with_node_modules'), + 'node_modules/index.ret42', + ); + handler().should.be.equal(42); + }); + + it('should bubble up rejections occurred during init as errors', async () => { + try { + await UserFunction.load(HANDLERS_ROOT, 'asyncInitRejection.handler'); + + should.fail('The rejection did not bubble up!'); + } catch (error) { + error.should.be.instanceof(Error); + error.name.should.equal('AsyncInitRejectionException'); + error.message.should.equal('Oh noes! something bad happened'); + } + }); + + it('should not load a CommonJS module if the package has the module type defined', () => { + UserFunction.load( + path.join(HANDLERS_ROOT, 'async_init_package'), + 'cjsModuleInEsmPackage.echo', + ).should.be.rejectedWith(/exports is not defined in ES module scope/); + }); + + it('should throw a ImportModuleError error if the module does not exists', () => { + UserFunction.load(HANDLERS_ROOT, 'noModule.echo').should.be.rejectedWith( + ImportModuleError, + ); + }); + + it("should successfully load a user function exported as 'default'", async () => { + const handler = await UserFunction.load( + HANDLERS_ROOT, + 'defaultHandler.default', + ); + const response = handler(); + + response.should.be.equal(42); + }); + + it("should successfully load a user function exported as 'default', esm", async () => { + const handler = await UserFunction.load( + HANDLERS_ROOT, + 'defaultHandlerESM.default', + ); + const response = handler(); + + response.should.be.equal(42); + }); + + it('should successfully load a user function that uses different import styles, esm', async () => { + const handler = await UserFunction.load( + HANDLERS_ROOT, + 'esModuleImports.echo', + ); + const response = handler('moon'); + + response.should.be.resolvedWith('moon'); + }); + + it('should successfully load a CJS handler from extensionless file (no package.json)', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'extensionless'), + 'index.handler', + ); + const response = await handler('test event'); + + response.should.equal('Hello from extensionless CJS'); + }); + + xit('should fail to load ESM syntax from extensionless file (no package.json)', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'extensionless'), + 'esm-extensionless.handler', + ).should.be.rejectedWith(UserCodeSyntaxError); + }); + + it('should load CJS handler from extensionless file with type:commonjs', async () => { + // package.json is ignored in the case of extensionless + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg', 'type-cjs'), + 'cjs.handler', + ); + const response = await handler('test event'); + + response.should.equal('Hello from extensionless CJS'); + }); + + xit('should fail to load ESM handler from extensionless file with type:commonjs', async () => { + // package.json is ignored in the case of extensionless + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg', 'type-cjs'), + 'esm.handler', + ).should.be.rejectedWith(UserCodeSyntaxError); + }); + + it('should load CJS handler from extensionless file with type:module', async () => { + // package.json is ignored in the case of extensionless + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg', 'type-esm'), + 'cjs.handler', + ); + const response = await handler('test event'); + + response.should.equal('Hello from extensionless CJS'); + }); + + xit('should fail to load ESM handler from extensionless file with type:module', async () => { + // package.json is ignored in the case of extensionless + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg', 'type-esm'), + 'esm.handler', + ).should.be.rejectedWith(UserCodeSyntaxError); + }); + + it('should load CJS handler from JS file with type:commonjs', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg', 'type-cjs'), + 'cjsModule.handler', + ); + const response = await handler('test event'); + + response.should.equal('Hello from CJS.js'); + }); + + it('should fail to load ESM handler from JS file with type:commonjs', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg', 'type-cjs'), + 'esmModule.handler', + ).should.be.rejectedWith(UserCodeSyntaxError); + }); + + it('should load ESM handler from JS file with type:module', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg', 'type-esm'), + 'esmModule.handler', + ); + const response = await handler('test event'); + + response.should.equal('Hello from ESM.js'); + }); + + it('should fail to load CJS handler from JS file with type:module', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg', 'type-esm'), + 'cjsModule.handler', + ).should.be.rejectedWith( + ReferenceError, + /module is not defined in ES module scope/, + ); + }); + + xit('should fail to load ESM handler from JS file without type context', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg-less'), + 'esmModule.handler', + ).should.be.rejectedWith(UserCodeSyntaxError); + }); + + it('should fail to load CJS handler from MJS file without type context', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg-less'), + 'cjsInMjs.handler', + ).should.be.rejectedWith( + ReferenceError, + /module is not defined in ES module scope/, + ); + }); + + it('should fail to load ESM handler from CJS file without type context', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg-less'), + 'esmInCjs.handler', + ).should.be.rejectedWith(UserCodeSyntaxError); + }); + + it('should fail to load mixed context handler from JS file without type context', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg-less'), + 'cjsAndMjs.handler', + ).should.be.rejectedWith(UserCodeSyntaxError); + }); + + it('should successfully load ESM handler importing from CJS', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg-less'), + 'esmImportCjs.handler', + ); + + const response = await handler(); + response.should.equal('Hello from CJS!'); + }); + + it('should fail when CJS tries to import from ESM using static import', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg-less'), + 'cjsImportESM.handler', + ).should.be.rejectedWith(UserCodeSyntaxError); + }); + + it('should successfully load CJS handler importing from CJS', async () => { + const handler = await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg-less'), + 'cjsImportCjs.handler', + ); + + const response = await handler(); + response.should.equal('Hello from CJS!'); + }); + + it('should fail when using require in .mjs', async () => { + await UserFunction.load( + path.join(HANDLERS_ROOT, 'pkg-less'), + 'esmRequireCjs.handler', + ).should.be.rejectedWith( + ReferenceError, + /require is not defined in ES module scope/, + ); + }); +}); + +describe('type guards HandlerFunction', () => { + it('should compile the code', () => { + const func = () => {}; + if (UserFunction.isHandlerFunction(func)) { + func(); + } + }); + + it('should return true if function', () => { + UserFunction.isHandlerFunction(() => {}).should.be.true(); + }); + + it('should return false if not function', () => { + UserFunction.isHandlerFunction('MyHandler').should.be.false(); + }); +}); diff --git a/test/unit/WarningForCallbackHandlersTest.js b/test/unit/WarningForCallbackHandlersTest.js new file mode 100644 index 00000000..82398390 --- /dev/null +++ b/test/unit/WarningForCallbackHandlersTest.js @@ -0,0 +1,68 @@ +/* +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0 +*/ + +'use strict'; + +require('should'); + +let { captureStream, consoleSnapshot } = require('./LoggingGlobals'); + +let { + checkForDeprecatedCallback, +} = require('../../src/WarningForCallbackHandlers.js'); + +let LogPatch = require('lambda-runtime/LogPatch'); +const UserFunction = require('lambda-runtime/UserFunction.js'); + +const path = require('path'); +const TEST_ROOT = path.join(__dirname, '../'); +const HANDLERS_ROOT = path.join(TEST_ROOT, 'handlers'); + +describe('Formatted Error Logging', () => { + let restoreConsole = consoleSnapshot(); + let capturedStdout = captureStream(process.stdout); + + beforeEach( + 'delete env var', + () => delete process.env.AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING, + ); + beforeEach('capture stdout', () => capturedStdout.hook()); + beforeEach('apply console patch', () => LogPatch.patchConsole()); + afterEach('remove console patch', () => restoreConsole()); + afterEach('unhook stdout', () => capturedStdout.unhook()); + + const expectedString = + 'AWS Lambda plans to remove support for callback-based function handlers'; + + const tests = [ + { args: [false, 'isAsyncCallback.handler'], expected: true }, + { args: [true, 'isAsyncCallback.handler'], expected: false }, + { args: [false, 'isAsync.handlerAsync'], expected: false }, + { args: [true, 'isAsync.handlerAsync'], expected: false }, + { args: [false, 'defaultHandler.default'], expected: false }, + { args: [true, 'defaultHandler.default'], expected: false }, + ]; + + tests.forEach(({ args, expected }) => { + const shouldDeclareEnv = args[0]; + const handler = args[1]; + it(`When AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING=${shouldDeclareEnv} expecting ${ + expected ? 'no ' : '' + }warning logs for handler ${handler}`, async () => { + if (shouldDeclareEnv) { + process.env.AWS_LAMBDA_NODEJS_DISABLE_CALLBACK_WARNING = 1; + } + const handlerFunc = await UserFunction.load(HANDLERS_ROOT, handler); + const metadata = UserFunction.getHandlerMetadata(handlerFunc); + + checkForDeprecatedCallback(metadata); + if (expected) { + capturedStdout.captured().should.containEql(expectedString); + } else { + capturedStdout.captured().should.not.containEql(expectedString); + } + }); + }); +}); \ No newline at end of file diff --git a/test/unit/package.json b/test/unit/package.json new file mode 100644 index 00000000..599108ae --- /dev/null +++ b/test/unit/package.json @@ -0,0 +1,48 @@ +{ + "name": "_unit", + "version": "1.0.0", + "author": "AWS Lambda", + "license": "Apache-2.0", + "eslintConfig": { + "extends": [ + "plugin:prettier/recommended" + ], + "env": { + "node": true, + "mocha": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 2020 + }, + "rules": { + "strict": [ + "error", + "global" + ], + "indent": [ + "error", + 2 + ], + "camelcase": "error", + "no-console": "off", + "no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_" + } + ] + } + }, + "eslintIgnore": [ + "syntax_error.js", + "node_modules", + "async_init_package" + ], + "prettier": { + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true + } +} diff --git a/test/unit/tsconfig.json b/test/unit/tsconfig.json deleted file mode 100644 index 2136ca2f..00000000 --- a/test/unit/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig-base.json", - "references": [ - { "path": "../../src" } - ], - "compilerOptions": { - "types": [ - "node", - "mocha" - ] - } -} \ No newline at end of file diff --git a/test/unit/utils/FakeTelemetryTarget.ts b/test/unit/utils/FakeTelemetryTarget.ts deleted file mode 100644 index 700a381a..00000000 --- a/test/unit/utils/FakeTelemetryTarget.ts +++ /dev/null @@ -1,100 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -import * as os from "os"; -import * as fs from "fs"; -import * as path from "path"; -import * as assert from "assert"; - -const _LOG_IDENTIFIER = Buffer.from("a55a0001", "hex"); - -/** - * A fake implementation of the multilne logging protocol. - * Read and write log frames to a temp file and provide an asserting helper for - * reading individual log statements from the file. - */ -export default class FakeTelemetryTarget { - readTarget: number; - writeTarget: number; - - constructor() { - this.readTarget = 0; - this.writeTarget = 0; - } - - openFile(): void { - const tempTelemetryDir = fs.mkdtempSync( - path.join(os.tmpdir(), "LambdyBYOLNodeJs12xTelemetry-") - ); - this.writeTarget = fs.openSync(path.join(tempTelemetryDir, "log"), "as+"); - this.readTarget = fs.openSync(path.join(tempTelemetryDir, "log"), "rs+"); - console.log( - "Generate new telemetry file", - tempTelemetryDir, - "with file descriptor", - this.readTarget - ); - } - - closeFile(): void { - console.log(`Close telemetry filedescriptor ${this.readTarget}`); - fs.closeSync(this.readTarget); - fs.closeSync(this.writeTarget); - this.readTarget = 0; - this.writeTarget = 0; - } - - updateEnv(): void { - process.env["_LAMBDA_TELEMETRY_LOG_FD"] = this.writeTarget.toString(); - } - - /** - * Read a single line from the telemetry file. - * Explodes when: - * - no line is present - * - the prefix is malformed - * - there aren't enough bytes - */ - readLine(): string { - const readLength = () => { - const logPrefix = Buffer.alloc(8); - const actualReadBytes = fs.readSync( - this.readTarget, - logPrefix, - 0, - logPrefix.length, - null - ); - assert.strictEqual( - actualReadBytes, - logPrefix.length, - `Expected actualReadBytes[${actualReadBytes}] = ${logPrefix.length}` - ); - assert.strictEqual( - logPrefix.lastIndexOf(_LOG_IDENTIFIER), - 0, - `log prefix ${logPrefix.toString( - "hex" - )} should start with ${_LOG_IDENTIFIER.toString("hex")}` - ); - return logPrefix.readInt32BE(4); - }; - - const lineLength = readLength(); - const lineBytes = Buffer.alloc(lineLength); - const actualLineSize = fs.readSync( - this.readTarget, - lineBytes, - 0, - lineBytes.length, - null - ); - assert.strictEqual( - actualLineSize, - lineBytes.length, - "The log line must match the length specified in the frame header" - ); - return lineBytes.toString("utf8"); - } -} diff --git a/test/unit/utils/LogPatch.test.ts b/test/unit/utils/LogPatch.test.ts deleted file mode 100644 index d78e2f1f..00000000 --- a/test/unit/utils/LogPatch.test.ts +++ /dev/null @@ -1,229 +0,0 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -import should from "should"; -import LogPatch from "../../../src/utils/LogPatch"; -import * as Errors from "../../../src/Errors"; - -import { captureStream, consoleSnapshot } from "./LoggingGlobals"; -import FakeTelemetryTarget from "./FakeTelemetryTarget"; - -describe("Apply the default console log patch", () => { - const restoreConsole = consoleSnapshot(); - const capturedStdout = captureStream(process.stdout); - - beforeEach("capture stdout", () => capturedStdout.hook()); - beforeEach("apply console patch", () => LogPatch.patchConsole()); - afterEach("remove console patch", () => restoreConsole()); - afterEach("unhook stdout", () => capturedStdout.unhook()); - - it("should have four tab-separated fields on a normal line", () => { - console.log("anything"); - capturedStdout.captured().should.match(/.*\t.*\t.*\t.*\n/); - }); - - it("should have five tab-separated fields when logging an error", () => { - console.error("message", Errors.toFormatted(new Error("garbage"))); - capturedStdout.captured().should.match(/.*\t.*\t.*\t.*\t.*\n/); - }); - - describe("When the global requestId is set", () => { - const EXPECTED_ID = "some fake request id"; - - beforeEach("set the request id", () => { - LogPatch.setCurrentRequestId(EXPECTED_ID); - }); - afterEach("unset the request id", () => { - LogPatch.setCurrentRequestId(undefined); - }); - - it("should include the requestId as the second field", () => { - console.info("something"); - capturedStdout - .captured() - .should.match(new RegExp(`.*\t${EXPECTED_ID}\t.*\t.*\n`)); - }); - }); - - it("should include the level field as the third field", () => { - console.warn("content"); - capturedStdout.captured().should.match(new RegExp(`.*\t.*\tWARN\t.*\n`)); - }); - - it("should include the message as the fourth field", () => { - const message = "my turbo message"; - console.trace(message); - capturedStdout - .captured() - .should.match(new RegExp(`.*\t.*\t.*\t${message}\n`)); - }); - - describe("Each console.* method should include a level value", () => { - it("should use INFO for console.log", () => { - console.log("hello"); - capturedStdout.captured().should.containEql("INFO"); - }); - - it("should use INFO for console.info", () => { - console.info("hello"); - capturedStdout.captured().should.containEql("INFO"); - }); - - it("should use WARN for console.warn", () => { - console.warn("hello"); - capturedStdout.captured().should.containEql("WARN"); - }); - - it("should use ERROR for console.error", () => { - console.error("hello"); - capturedStdout.captured().should.containEql("ERROR"); - }); - - it("should use TRACE for console.trace", () => { - console.trace("hello"); - capturedStdout.captured().should.containEql("TRACE"); - }); - - it("should use FATAL for console.fatal", () => { - (console as any).fatal("hello"); - capturedStdout.captured().should.containEql("FATAL"); - }); - }); - - it("should log an error as json", () => { - const expected = new Errors.ExtendedError("some error"); - expected.code = 1234; - expected.custom = "my custom field"; - - console.error("message", Errors.toFormatted(expected)); - - const errorString = capturedStdout.captured().split("\t")[4]; - const recoveredError = JSON.parse(errorString); - - recoveredError.should.have.property("errorType", expected.name); - recoveredError.should.have.property("errorMessage", expected.message); - recoveredError.should.have.property("stack", expected.stack?.split("\n")); - recoveredError.should.have.property("code", expected.code); - recoveredError.should.have.property("custom", expected.custom); - }); -}); - -describe("The multiline log patch", () => { - const restoreConsole = consoleSnapshot(); - const telemetryTarget = new FakeTelemetryTarget(); - - beforeEach("create a new telemetry file and patch the console", () => { - telemetryTarget.openFile(); - telemetryTarget.updateEnv(); - LogPatch.patchConsole(); - }); - afterEach("close the telemetry file and unpatch the console", () => { - restoreConsole(); - telemetryTarget.closeFile(); - }); - - it("should clear the telemetry env var", () => { - should.not.exist(process.env["_LAMBDA_TELEMETRY_LOG_FD"]); - }); - - it("should write a line", () => { - console.log("a line"); - telemetryTarget.readLine().should.containEql("a line"); - }); - - it("should have four tab-separated fields on a normal line", () => { - console.log("anything"); - telemetryTarget.readLine().should.match(/.*\t.*\t.*\t.*/); - }); - - it("should end with a newline", () => { - console.log("lol"); - telemetryTarget.readLine().should.match(/.*\n$/); - }); - - it("should have five tab-separated fields when logging an error", () => { - console.error("message", Errors.toFormatted(new Error("garbage"))); - telemetryTarget.readLine().should.match(/.*\t.*\t.*\t.*\t.*/); - }); - - describe("When the global requestId is set", () => { - const EXPECTED_ID = "some fake request id"; - - beforeEach("set the request id", () => { - LogPatch.setCurrentRequestId(EXPECTED_ID); - }); - afterEach("unset the request id", () => { - LogPatch.setCurrentRequestId(EXPECTED_ID); - }); - - it("should include the requestId as the second field", () => { - console.info("something"); - telemetryTarget - .readLine() - .should.match(new RegExp(`.*\t${EXPECTED_ID}\t.*\t.*`)); - }); - }); - - it("should include the level field as the third field", () => { - console.warn("content"); - telemetryTarget.readLine().should.match(new RegExp(`.*\t.*\tWARN\t.*`)); - }); - - it("should include the message as the fourth field", () => { - const message = "my turbo message"; - console.trace(message); - telemetryTarget - .readLine() - .should.match(new RegExp(`.*\t.*\t.*\t${message}`)); - }); - - describe("Each console.* method should include a level value", () => { - it("should use INFO for console.log", () => { - console.log("hello"); - telemetryTarget.readLine().should.containEql("INFO"); - }); - - it("should use INFO for console.info", () => { - console.info("hello"); - telemetryTarget.readLine().should.containEql("INFO"); - }); - - it("should use WARN for console.warn", () => { - console.warn("hello"); - telemetryTarget.readLine().should.containEql("WARN"); - }); - - it("should use ERROR for console.error", () => { - console.error("hello"); - telemetryTarget.readLine().should.containEql("ERROR"); - }); - - it("should use TRACE for console.trace", () => { - console.trace("hello"); - telemetryTarget.readLine().should.containEql("TRACE"); - }); - - it("should use FATAL for console.fatal", () => { - (console as any).fatal("hello"); - telemetryTarget.readLine().should.containEql("FATAL"); - }); - }); - - it("should log an error as json", () => { - const expected = new Errors.ExtendedError("some error"); - expected.code = 1234; - expected.custom = "my custom field"; - - console.error("message", Errors.toFormatted(expected)); - - const errorString = telemetryTarget.readLine().split("\t")[4]; - const recoveredError = JSON.parse(errorString); - - recoveredError.should.have.property("errorType", expected.name); - recoveredError.should.have.property("errorMessage", expected.message); - recoveredError.should.have.property("stack", expected.stack?.split("\n")); - recoveredError.should.have.property("code", expected.code); - recoveredError.should.have.property("custom", expected.custom); - }); -}); diff --git a/test/unit/utils/LoggingGlobals.ts b/test/unit/utils/LoggingGlobals.ts deleted file mode 100644 index 0d899435..00000000 --- a/test/unit/utils/LoggingGlobals.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* eslint-disable prefer-rest-params */ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; - -/** - * Testing logging in unit tests requires manipulating the global console and - * stdout objects. - * This module provides methods for safely capturing and restoring these - * objects under test. - */ - -export const consoleSnapshot = (): (() => void) => { - const log = console.log; - const debug = console.debug; - const info = console.info; - const warn = console.warn; - const error = console.error; - const trace = console.trace; - const fatal = (console as any).fatal; - - return function restoreConsole() { - console.log = log; - console.debug = debug; - console.info = info; - console.warn = warn; - console.error = error; - console.trace = trace; - (console as any).fatal = fatal; - }; -}; - -interface CapturedStream { - hook: () => void; - unhook: () => any; - captured: () => string; -} - -/** - * Capture all of the writes to a given stream. - */ -export const captureStream = function captureStream( - stream: NodeJS.WritableStream -): CapturedStream { - const originalWrite: any = stream.write; - let buf = ""; - return { - hook: () => { - buf = ""; // reset the buffer - stream.write = function (chunk: any): boolean { - buf += chunk.toString(); - return originalWrite.apply(stream, arguments); - }; - }, - unhook: () => (stream.write = originalWrite), - captured: () => buf, - }; -}; diff --git a/test/unit/utils/NoOpNativeHttp.ts b/test/unit/utils/NoOpNativeHttp.ts deleted file mode 100644 index 659aec2e..00000000 --- a/test/unit/utils/NoOpNativeHttp.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -import { NativeClient, InvocationResponse } from "../../../src/Common"; - -export class NoOpNativeHttp implements NativeClient { - done(): void { - /*NoOp*/ - } - error(): void { - /*NoOp*/ - } - next(): Promise { - return Promise.resolve(null as any); - } - initializeClient(_userAgent: string): void { - /*NoOp*/ - } -} diff --git a/test/unit/utils/StubHttp.ts b/test/unit/utils/StubHttp.ts deleted file mode 100644 index eb0b4939..00000000 --- a/test/unit/utils/StubHttp.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -import { RequestOptions, ClientRequest } from "http"; -import { URL } from "url"; - -/** - * Stub request object. - * Provides no-op definitions of the request functions used by the Runtime Interface Client. - */ -export const noOpRequest = Object.freeze({ - /* no op, return itself to allow continuations/chaining */ - on: () => noOpRequest, - /* no op, return itself to allow continuations/chaninig */ - end: () => noOpRequest, -}); - -export class StubHttp { - lastUsedOptions: RequestOptions | string | URL; - Agent: any; - - constructor() { - this.lastUsedOptions = {}; - this.Agent = class FakeAgent {}; - } - - request(options: RequestOptions | string | URL): ClientRequest { - this.lastUsedOptions = options; - return (noOpRequest as unknown) as ClientRequest; - } -} diff --git a/test/utils/StdoutReporter.ts b/test/util/StdoutReporter.test.js similarity index 68% rename from test/utils/StdoutReporter.ts rename to test/util/StdoutReporter.test.js index c59a0688..944ed92b 100644 --- a/test/utils/StdoutReporter.ts +++ b/test/util/StdoutReporter.test.js @@ -1,33 +1,28 @@ -/** Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. */ - -"use strict"; +/** + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ -import { MochaOptions, Runner, reporters } from "mocha"; +'use strict'; +const Mocha = require('mocha'); const { - EVENT_SUITE_BEGIN, - EVENT_SUITE_END, EVENT_RUN_BEGIN, EVENT_RUN_END, - EVENT_TEST_PASS, EVENT_TEST_FAIL, -} = Runner.constants; + EVENT_TEST_PASS, + EVENT_SUITE_BEGIN, + EVENT_SUITE_END, +} = Mocha.Runner.constants; /** * Custom reporter does not depend on any of the console.* functions, which * enables clean test output even when applying the lambda-runtime console * patch. */ -module.exports = class StdoutReporter extends reporters.Base { - private _alreadyWritten: boolean; - private _report: string; - private _indents: number; - - public constructor(runner: Runner, options: MochaOptions) { - super(runner, options); - +module.exports = class StdoutReporter { + constructor(runner) { this._alreadyWritten = false; - this._report = ""; + this._report = ''; this._indents = 0; const stats = runner.stats; @@ -46,27 +41,27 @@ module.exports = class StdoutReporter extends reporters.Base { .on(EVENT_TEST_FAIL, (test, err) => { this.log(`✗ ${test.title}`); this.increaseIndent(); - err.stack.split("\n").forEach((msg) => this.log(msg)); + err.stack.split('\n').forEach((msg) => this.log(msg)); this.decreaseIndent(); }) .once(EVENT_RUN_END, () => { this.log( - "Results " + + 'Results ' + stats.passes + - " passed out of " + + ' passed out of ' + (stats.passes + stats.failures) + - " total tests" + ' total tests', ); this.dumpReport(); }); // This is hella nice if Mocha crashes for some reason // (which turns out is easy to do if you fool around with console.log) - process.on("exit", () => this.dumpReport()); + process.on('exit', () => this.dumpReport()); } indent() { - return Array(this._indents).join(" "); + return Array(this._indents).join(' '); } increaseIndent() { diff --git a/tsconfig-base.json b/tsconfig-base.json deleted file mode 100644 index 485043f8..00000000 --- a/tsconfig-base.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - - // As recmmoneded in https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping#node-10 - "target": "es2018", - "module": "commonjs", - "lib": ["es2018"], - "moduleResolution": "node", - "declaration": true, - "declarationMap": true, - "inlineSourceMap": true, - "esModuleInterop": true, - - "strict": true /* Enable all strict type-checking options. */, - - /* Additional Checks */ - "noUnusedLocals": true /* Report errors on unused locals. */, - "noUnusedParameters": true /* Report errors on unused parameters. */, - "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, - "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, - - /* Debugging Options */ - "traceResolution": false /* Report module resolution log messages. */, - "listEmittedFiles": false /* Print names of generated files part of the compilation. */, - "listFiles": false /* Print names of files part of the compilation. */, - "pretty": true /* Stylize errors and messages using color and context. */, - - "typeRoots": ["node_modules/@types", "src/types", "lib/types"] - } -} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 516e347e..00000000 --- a/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "files": [], - "references": [ - { "path": "./src" }, - { "path": "./test/unit" }, - ] -} \ No newline at end of file