diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..2197cb7 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "master", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.changeset/fuzzy-dancers-unite.md b/.changeset/fuzzy-dancers-unite.md new file mode 100644 index 0000000..cb2f023 --- /dev/null +++ b/.changeset/fuzzy-dancers-unite.md @@ -0,0 +1,5 @@ +--- +'node-rest-client': minor +--- + +add family args (PR #204 Update: add family args) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..ee45b8e --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,22 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node +{ + "name": "Node.js & TypeScript", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm" + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "yarn install", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.docker/Dockerfile b/.docker/Dockerfile new file mode 100644 index 0000000..c6d55e4 --- /dev/null +++ b/.docker/Dockerfile @@ -0,0 +1,118 @@ +FROM alpine:3.17 + +ENV NODE_VERSION 18.18.0 + +RUN addgroup -g 1000 node \ + && adduser -u 1000 -G node -s /bin/sh -D node \ + && apk add --no-cache \ + libstdc++ \ + && apk add --no-cache --virtual .build-deps \ + curl \ + && ARCH= && alpineArch="$(apk --print-arch)" \ + && case "${alpineArch##*-}" in \ + x86_64) \ + ARCH='x64' \ + CHECKSUM="1159f06f17f7c2e582c77e4602249b440bd1daab667694063f1d61fb621aa65c" \ + ;; \ + *) ;; \ + esac \ + && if [ -n "${CHECKSUM}" ]; then \ + set -eu; \ + curl -fsSLO --compressed "https://unofficial-builds.nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz"; \ + echo "$CHECKSUM node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" | sha256sum -c - \ + && tar -xJf "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \ + && ln -s /usr/local/bin/node /usr/local/bin/nodejs; \ + else \ + echo "Building from source" \ + # backup build + && apk add --no-cache --virtual .build-deps-full \ + binutils-gold \ + g++ \ + gcc \ + gnupg \ + libgcc \ + linux-headers \ + make \ + python3 \ + # use pre-existing gpg directory, see https://github.com/nodejs/docker-node/pull/1895#issuecomment-1550389150 + && export GNUPGHOME="$(mktemp -d)" \ + # gpg keys listed at https://github.com/nodejs/node#release-keys + && for key in \ + 4ED778F539E3634C779C87C6D7062848A1AB005C \ + 141F07595B7B3FFE74309A937405533BE57C7D57 \ + 74F12602B6F1C4E913FAA37AD3A89613643B6201 \ + DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7 \ + 61FC681DFB92A079F1685E77973F295594EC4689 \ + 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \ + C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ + 890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 \ + C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \ + 108F52B48DB57BB0CC439B2997B01419BD92F80A \ + A363A499291CBBC940DD62E41F10027AF002F8B0 \ + ; do \ + gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \ + done \ + && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION.tar.xz" \ + && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ + && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ + && gpgconf --kill all \ + && rm -rf "$GNUPGHOME" \ + && grep " node-v$NODE_VERSION.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ + && tar -xf "node-v$NODE_VERSION.tar.xz" \ + && cd "node-v$NODE_VERSION" \ + && ./configure \ + && make -j$(getconf _NPROCESSORS_ONLN) V= \ + && make install \ + && apk del .build-deps-full \ + && cd .. \ + && rm -Rf "node-v$NODE_VERSION" \ + && rm "node-v$NODE_VERSION.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt; \ + fi \ + && rm -f "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" \ + && apk del .build-deps \ + # smoke tests + && node --version \ + && npm --version + +ENV YARN_VERSION 1.22.19 + +RUN apk add --no-cache --virtual .build-deps-yarn curl gnupg tar \ + # use pre-existing gpg directory, see https://github.com/nodejs/docker-node/pull/1895#issuecomment-1550389150 + && export GNUPGHOME="$(mktemp -d)" \ + && for key in \ + 6A010C5166006599AA17F08146C2130DFD2497F5 \ + ; do \ + gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \ + done \ + && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \ + && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc" \ + && gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \ + && gpgconf --kill all \ + && rm -rf "$GNUPGHOME" \ + && mkdir -p /opt \ + && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \ + && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \ + && ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \ + && rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \ + && apk del .build-deps-yarn \ + # smoke test + && yarn --version + + +ARG USERNAME="aacerox" +ARG GITHUB_TOKEN="" + +# add git and clone project +RUN apk add --no-cache git \ + && git config --global credential.helper store \ + && echo "https://${USERNAME}:${GITHUB_TOKEN}@github.com" > ~/.git-credentials \ + && mkdir /opt/node-rest-client + +VOLUME /opt/node-rest-client + +COPY docker-entrypoint.sh /usr/local/bin/ +ENTRYPOINT ["docker-entrypoint.sh"] + +CMD [ "node" ] diff --git a/.docker/build-nrc.sh b/.docker/build-nrc.sh new file mode 100644 index 0000000..c0b5c8b --- /dev/null +++ b/.docker/build-nrc.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker build --build-arg GITHUB_TOKEN=$1 -t node:nrc . \ No newline at end of file diff --git a/.docker/docker-entrypoint.sh b/.docker/docker-entrypoint.sh new file mode 100644 index 0000000..1b3116e --- /dev/null +++ b/.docker/docker-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +# Run command with node if the first argument contains a "-" or is not a system command. The last +# part inside the "{}" is a workaround for the following bug in ash/dash: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264 +if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ] || { [ -f "${1}" ] && ! [ -x "${1}" ]; }; then + set -- node "$@" +fi + +exec "$@" diff --git a/.docker/run-nrc.sh b/.docker/run-nrc.sh new file mode 100644 index 0000000..87914d6 --- /dev/null +++ b/.docker/run-nrc.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker run --name nrc-dev-container --rm -v $(pwd)/..:/opt/node-rest-client -it node:nrc /bin/sh \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..e7de7ff --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,15 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": "google", + "overrides": [ + ], + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "rules": { + } +} diff --git a/.github/workflows/nrc-job-apply-version.yml b/.github/workflows/nrc-job-apply-version.yml new file mode 100644 index 0000000..8dac101 --- /dev/null +++ b/.github/workflows/nrc-job-apply-version.yml @@ -0,0 +1,57 @@ +on: + workflow_call: + inputs: + isRelease: + description: flag a release invocation + type: boolean + default: false + version: + description: version to apply to package.json files + type: string + required: true +jobs: + apply-version: + runs-on: ubuntu-latest + steps: + - id: checkout + name: checkout project + uses: actions/checkout@v3 + + - id: installNode + name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'npm' + + # generate changelog if its a release + - id: generateReleaseChangelog + name: create release changelog + if: ${{ inputs.isRelease }} + run: echo "generate change log" + + # apply version to package.json files and create a git tag + - id: applyVersion + name: apply version to package.json files + env: + VERSION: ${{ inputs.version }} + IS_RELEASE: ${{ inputs.isRelease }} + run: | + export RELEASE_COMMENT="" + + if [ "$IS_RELEASE" == "true" ]; then + RELEASE_COMMENT="release" + fi + + npm version -m "apply $RELEASE_COMMENT version $VERSION" + + # create release PR + - id: createReleasePR + name: create release PR + if: ${{ inputs.isRelease }} + run: echo "create release PR" + + + + + \ No newline at end of file diff --git a/.github/workflows/nrc-job-build-test.yml b/.github/workflows/nrc-job-build-test.yml new file mode 100644 index 0000000..4931534 --- /dev/null +++ b/.github/workflows/nrc-job-build-test.yml @@ -0,0 +1,23 @@ +on: + workflow_call: +jobs: + build-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'npm' + # clean install + - run: npm ci + name: NRC Install + # build + - run: npm run build --if-present + name: NRC Build + # test + - run: npm test + name: NRC Test + + diff --git a/.github/workflows/nrc-job-generate-version.yml b/.github/workflows/nrc-job-generate-version.yml new file mode 100644 index 0000000..e21a521 --- /dev/null +++ b/.github/workflows/nrc-job-generate-version.yml @@ -0,0 +1,27 @@ +on: + workflow_call: + outputs: + version: + description: version calculated by git version + value: ${{ jobs.generate-version.outputs.semVer }} +jobs: + generate-version: + runs-on: ubuntu-latest + outputs: + semVer: ${{ steps.generateVersion.outputs.semVer }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + # install git version + - id: installVersion + name: Install GitVersion + uses: gittools/actions/gitversion/setup@v0 + with: + versionSpec: '5.x' + preferLatestVersion: true + # calculate git version + - id: generateVersion # id to later be referenced + name: calculate semver + uses: gittools/actions/gitversion/execute@v0 + \ No newline at end of file diff --git a/.github/workflows/nrc-job-release.yml b/.github/workflows/nrc-job-release.yml new file mode 100644 index 0000000..e63b80c --- /dev/null +++ b/.github/workflows/nrc-job-release.yml @@ -0,0 +1,47 @@ +on: + workflow_call: +jobs: + release: + runs-on: ubuntu-latest + if: ${{ github.repository == 'aacerox/node-rest-client' }} + steps: + # checkout repo + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + fetch-tags: true + # read latest tag + - id: readLatestTag + name: read latest tag + run: echo "latestTag=$(git describe --tags --abbrev=0)" >> "$GITHUB_OUTPUT" + # setup node.js + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'npm' + # install repo dependencies + - id: cleanInstallRepo + name: clean install repo + run: npm ci + # run changeset action + # - when push from normal PR: the 'version' command is executed. A new release branch and PR + # is created if it doesn't exists and if it does exists the commit is added to release branch + # + # - when push from release PR: the 'publish' command is executed and artifact are published to npm + - id: changesetPR + name: Changeset release + uses: changesets/action@v1 + env: + NRC_RELEASE_MSG: "node-rest-client release ${{ steps.readLatestTag.outputs.latestTag }}" + GITHUB_TOKEN: ${{ secrets.NRC_GITHUB_TOKEN }} + with: + version: npm run version:packages + publish: npm run publish:packages + commit: "chore(release): ${{ env.NRC_RELEASE_MSG }}" + title: "${{ env.NRC_RELEASE_MSG }}" + + + + + diff --git a/.github/workflows/nrc-workflow-ci.yml b/.github/workflows/nrc-workflow-ci.yml new file mode 100644 index 0000000..f3851e9 --- /dev/null +++ b/.github/workflows/nrc-workflow-ci.yml @@ -0,0 +1,24 @@ +name: Node-Rest-Client CI +on: + push: + branches: + - master + - 'release/**' +# just one workflow active, for the same branch +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + # test + test: + uses: ./.github/workflows/nrc-job-build-test.yml + + # changeset release + release: + uses: ./.github/workflows/nrc-job-release.yml + + + + + + + \ No newline at end of file diff --git a/.github/workflows/nrc-workflow-pr.yml b/.github/workflows/nrc-workflow-pr.yml new file mode 100644 index 0000000..0f3ffd0 --- /dev/null +++ b/.github/workflows/nrc-workflow-pr.yml @@ -0,0 +1,9 @@ +name: Node-Rest-Client PR +on: + pull_request: + branches: + - master +jobs: + build-test: + uses: ./.github/workflows/nrc-job-build-test.yml + \ No newline at end of file diff --git a/.github/workflows/nrc-workflow-release.yml b/.github/workflows/nrc-workflow-release.yml new file mode 100644 index 0000000..8153d22 --- /dev/null +++ b/.github/workflows/nrc-workflow-release.yml @@ -0,0 +1,57 @@ +name: Node-Rest-Client Release +on: + push: + branches: + - feat/general-upgrade + workflow_dispatch: +jobs: + create-release-branch: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + fetch-tags: true + + + + # - id: # + # name: configure git + # run: | + # # setup the username and email. I tend to use 'GitHub Actions Bot' with no email by default + # git --version + # git config user.name "GitHub Actions Bot" + # git config user.email "<>" + # git status + # git tag + # git describe + + - id: readLatestTag + name: read latest tag + run: echo "latestTag=$(git describe --tags --abbrev=0)" >> "$GITHUB_OUTPUT" + + - id: createReleaseBranch + name: create release branch + env: + RELEASE_TAG: ${{ steps.readLatestTag.outputs.latestTag }} + run: | + export BRANCH_NAME="release/$RELEASE_TAG" + git checkout -b $BRANCH_NAME + git push --set-upstream origin release/$RELEASE_TAG + + - id: cleanInstallRepo + name: clean install repo + run: npm ci + + - id: changesetPR + name: Create Release Pull Request + uses: changesets/action@v1 + env: + NRC_RELEASE_MSG: "node-rest-client release ${{ steps.readLatestTag.outputs.latestTag }}" + GITHUB_TOKEN: ${{ secrets.NRC_GITHUB_TOKEN }} + with: + version: npm run version:packages + commit: "chore(release): ${{ env.NRC_RELEASE_MSG }}" + title: "${{ env.NRC_RELEASE_MSG }}" + + \ No newline at end of file diff --git a/.gitignore b/.gitignore index 055c0fe..3088616 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - +dist/* test/man-test.js test/spec/test.js @@ -14,5 +14,7 @@ test/manual-test.js .project mocha-eclipse.js -node-rest-client.sublime-project -node-rest-client.sublime-workspace \ No newline at end of file +*.sublime-project +*.sublime-workspace +*.code-workspace +.vscode/* diff --git a/.mocharc.cjs b/.mocharc.cjs new file mode 100644 index 0000000..6dc6c6c --- /dev/null +++ b/.mocharc.cjs @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = { + require: 'should', + reporter: 'spec', + spec: ['test/specs/*.mjs'], // the positional arguments! + ui: 'bdd', + recursive: true +}; \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..e97ea1b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "tabWidth": 2, + "useTabs": false, + "singleQuote": true +} diff --git a/blacklist b/blacklist new file mode 100644 index 0000000..e69de29 diff --git a/fixup b/fixup new file mode 100644 index 0000000..f80e9c5 --- /dev/null +++ b/fixup @@ -0,0 +1,19 @@ +#!/bin/bash +# +# Add package.json files to cjs/mjs subtrees +# + +cat >dist/cjs/package.json <dist/mjs/package.json < { + return httpMethod(url, args, callback); + }; + } + + /** + * returns a new HTTP method promise + * @author aacerox + * + * @param {*} url + * @param {*} method + * @return { promise} + */ + #getHttpPromiseFn(url, method) { + const httpMethod = this[method.toLowerCase()]; + + return (args = {}, callback) => + new Promise((successFn, errorFn) => { + try { + successFn(httpMethod(url, args, callback)); + } catch (err) { + errorFn(err); + } + }); + } + + /** + * returns a new IOFacade object to access response parsers + * and request serializers + * @author aacerox + * + * @param {*} parserManager + * @param {*} serializerManager + * @return { IOFacade } + */ + #createIOFacade(parserManager, serializerManager) { + const self = this; + return (function(parserManager, serializerManager) { + // error execution context + const errorContext = (parserFn) => + function(...args) { + try { + // eslint-disable-next-line no-invalid-this + return parserFn.apply(this, args); + } catch (err) { + self.emit('error', err); + } + }; + + const result = {parsers: {}, serializers: {}}; + + // parsers facade + result.parsers.add = errorContext(parserManager.add).bind(parserManager); + + result.parsers.remove = errorContext(parserManager.remove).bind( + parserManager, + ); + + result.parsers.find = errorContext(parserManager.find).bind( + parserManager, + ); + + result.parsers.getAll = errorContext(parserManager.getAll).bind( + parserManager, + ); + + result.parsers.getDefault = errorContext(parserManager.getDefault).bind( + parserManager, + ); + + result.parsers.clean = errorContext(parserManager.clean).bind( + parserManager, + ); + + // serializers facade + result.serializers.add = errorContext(serializerManager.add).bind( + serializerManager, + ); + + result.serializers.remove = errorContext(serializerManager.remove).bind( + serializerManager, + ); + + result.serializers.find = errorContext(serializerManager.find).bind( + serializerManager, + ); + + result.serializers.getAll = errorContext(serializerManager.getAll).bind( + serializerManager, + ); + + result.serializers.getDefault = errorContext( + serializerManager.getDefault, + ).bind(serializerManager); + + result.serializers.clean = errorContext(serializerManager.clean).bind( + serializerManager, + ); + + return result; + })(parserManager, serializerManager); + } +}; diff --git a/lib/NrcClientRequest.js b/lib/NrcClientRequest.js new file mode 100644 index 0000000..329c793 --- /dev/null +++ b/lib/NrcClientRequest.js @@ -0,0 +1,33 @@ +import events from 'events'; + + +/** + * Client Request to be passed to NrcConnectManager and returned + * for each REST method invocation + * @author aacerox + * + * @export + * @class ClientRequest + * @typedef {ClientRequest} + * @extends {events.EventEmitter} + */ +export default class ClientRequest extends events.EventEmitter { + /** + * finalize current http request + * @author aacerox + */ + end() { + if (this._httpRequest) { + this._httpRequest.end(); + } + } + /** + * set new http request + * @author aacerox + * + * @param {*} req + */ + setHttpRequest(req) { + this._httpRequest = req; + } +} diff --git a/lib/NrcConnectManager.js b/lib/NrcConnectManager.js new file mode 100644 index 0000000..21d0507 --- /dev/null +++ b/lib/NrcConnectManager.js @@ -0,0 +1,400 @@ +'use strict'; +import followRedirect from 'follow-redirects'; +import zlib from 'zlib'; +import debug from './NrcDebugger.js'; +import stream from 'stream'; + + +const {http, https} = followRedirect; + +/** + * Manage proxy and non-proxy underlying connections + * @author aacerox + * + * @export + * @class NrcConnectManager + * @typedef {NrcConnectManager} + */ +export class NrcConnectManager { + /** + * response parser manager + * @author aacerox + * + * @type {*} + */ + #parserManager; + /** + * nrc instance managed by connect manager + * @author aacerox + * + * @type {*} + */ + #client; + + /** + * if true the manager will manage HTTP methods using promises + * if false will manage HTTP methods with function callbacks + * + * By default is false + * + * @date 8/9/2023 - 5:30:01 PM + * + * @type {*} + */ + #usePromises; + + /** + * Creates an instance of NrcConnectManager. + * @author aacerox + * + * @constructor + * @param {*} client + * @param {*} parserManager + * @param {*} usePromises + */ + constructor(client, parserManager, usePromises = false) { + this.#parserManager = parserManager; + this.#client = client; + this.#usePromises = usePromises; + } + + /** + * connect using configured proxy + * @author aacerox + * + * @param {*} options + * @param {*} callback + */ + proxy(options, callback) { + debug('proxy options', options.proxy); + + // creare a new proxy tunnel, and use to connect to API URL + const proxyTunnel = http.request(options.proxy); + const self = this; + + proxyTunnel.on('connect', (res, socket, head) => { + debug('proxy connected', socket); + + // set tunnel socket in request options, that's the tunnel + // itself + options.socket = socket; + + const buffer = []; + const protocol = options.protocol == 'http' ? http : https; + const clientRequest = options.clientRequest; + const requestConfig = options.requestConfig; + const responseConfig = options.responseConfig; + + self.#configureOptions(options); + + // add request options to request returned to calling method + clientRequest.options = options; + + // configure proxy request + const request = protocol.request(options, (res) => { + // configure response + self.#configureResponse(res, responseConfig, clientRequest); + + // concurrent data chunk handler + res.on('data', (chunk) => buffer.push(Buffer.from(chunk))); + res.on('end', () => this.#handleEnd(res, buffer, callback)); + + // handler response errors + res.on('error', (err) => { + if ( + clientRequest !== undefined && + typeof clientRequest === 'object' + ) { + // add request as property of error + err.request = clientRequest; + err.response = res; + // request error handler + clientRequest.emit('error', err); + } else { + // general error handler + client.emit('error', err); + } + }); + }); + + // configure request and add it to clientRequest + // and add it to request returned + self.#configureRequest(request, requestConfig, clientRequest); + clientRequest.setHttpRequest(request); + + self.#writeRequest(options.data, request); + + // handle request errors and handle them by request or general + // error handler + request.on('error', function(err) { + if (clientRequest !== undefined && typeof clientRequest === 'object') { + // add request as property of error + err.request = clientRequest; + + // request error handler + clientRequest.emit('error', err); + } else { + // general error handler + client.emit('error', err); + } + }); + }); + + // proxy tunnel error are only handled by general error handler + proxyTunnel.on('error', (error) => client.emit('error', error)); + proxyTunnel.end(); + } + + /** + * direct connection to target (do not use proxy) + * @author aacerox + * + * @param {*} options + * @param {*} callback + */ + normal(options, callback) { + const buffer = []; + const protocol = options.protocol === 'http' ? http : https; + const clientRequest = options.clientRequest; + const requestConfig = options.requestConfig; + const responseConfig = options.responseConfig; + const self = this; + + this.#configureOptions(options); + + // add request options to request returned to calling method + clientRequest.options = options; + + const request = protocol.request(options, function(res) { + // configure response + self.#configureResponse(res, responseConfig, clientRequest); + + // concurrent data chunk handler + res.on('data', (chunk) => buffer.push(Buffer.from(chunk))); + res.on('end', () => self.#handleEnd(res, buffer, callback)); + + // handler response errors + res.on('error', (err) => { + if (clientRequest !== undefined && typeof clientRequest === 'object') { + // add request as property of error + err.request = clientRequest; + err.response = res; + // request error handler + clientRequest.emit('error', err); + } else { + // general error handler + client.emit('error', err); + } + }); + }); + + // configure request and add it to clientRequest + // and add it to request returned + this.#configureRequest(request, requestConfig, clientRequest); + debug('clientRequest', clientRequest); + + clientRequest.setHttpRequest(request); + + debug('options data', options.data); + + + this.#writeRequest(options.data, request); + + // handle request errors and handle them by request or general + // error handler + request.on('error', function(err) { + if (clientRequest !== undefined && typeof clientRequest === 'object') { + // add request as property of error + err.request = clientRequest; + + // request error handler + clientRequest.emit('error', err); + } else { + // general error handler + client.emit('error', err); + } + }); + } + + + /** + * Description placeholder + * @date 10/19/2023 - 7:06:36 PM + * + * @param {*} data + * @param {*} request + */ + #writeRequest(data, request) { + if (data) { + if (data instanceof stream) { + // close request when stream ends + data.pipe(request); + data.on('end', ()=>{ + request.end(); + data.close(); + }); + } else { + // write POST/PUT data to request body; + // find valid serializer to be used to serialize request data, + // first one found + // is the one to be used.if none found for match condition, + // default serializer is used + request.write(data); + request.end(); + } + } else { + // no data, end request + request.end(); + } + } + + /** + * prepare request using global or method config + * @author aacerox + * + * @param {*} req + * @param {*} config + * @param {*} clientRequest + */ + #configureRequest(req, config, clientRequest) { + if (config.timeout) { + req.setTimeout(config.timeout, () => + clientRequest.emit('requestTimeout', req), + ); + } + + if (config.noDelay) { + req.setNoDelay(config.noDelay); + } + + if (config.keepAlive) { + req.setSocketKeepAlive(config.noDelay, config.keepAliveDelay || 0); + } + } + + /** + * prepare response using global or method config + * @author aacerox + * + * @param {*} res + * @param {*} config + * @param {*} clientRequest + */ + #configureResponse(res, config, clientRequest) { + if (config.timeout) { + res.setTimeout(config.timeout, () => { + clientRequest.emit('responseTimeout', res); + res.close(); + }); + } + } + + /** + * configure connect manager according to passed options + * @author aacerox + * + * @param {*} options + */ + #configureOptions(options) { + const followRedirectsProps = [ + 'followRedirects', + 'maxRedirects', + 'maxBodyLength', + ]; + + // add follows-redirects config + followRedirectsProps.forEach((redirectProp) => { + if (options.requestConfig.hasOwnProperty(redirectProp)) { + options[redirectProp] = options.requestConfig[redirectProp]; + } + }); + + // remove "protocol" and "clientRequest" option from options, + // cos is not allowed by http/https node objects + delete options.protocol; + delete options.clientRequest; + delete options.requestConfig; + delete options.responseConfig; + debug('options pre connect', options); + } + + /** + * handle requests + * @author aacerox + * + * @param {*} res + * @param {*} buffer + * @param {*} callback + */ + #handleEnd(res, buffer, callback) { + const content = res.headers['content-type']; + const encoding = res.headers['content-encoding']; + + debug('content-type: ', content); + debug('content-encoding: ', encoding); + + if (encoding !== undefined && encoding.indexOf('gzip') >= 0) { + debug('gunzip'); + zlib.gunzip(Buffer.concat(buffer), (er, gunzipped) => { + this.#handleResponse(res, gunzipped, callback); + }); + } else if (encoding !== undefined && encoding.indexOf('deflate') >= 0) { + debug('inflate'); + zlib.inflate(Buffer.concat(buffer), (er, inflated) => + this.#handleResponse(res, inflated, callback), + ); + } else { + debug('not compressed'); + this.#handleResponse(res, Buffer.concat(buffer), callback); + } + } + + /** + * handle responses + * @author aacerox + * + * @param {*} res + * @param {*} data + * @param {*} callback + */ + #handleResponse(res, data, callback) { + // find valid parser to be used with response content type, first one + // found + const parserCallbackFn = this.#usePromises ? + (parsedData) => callback({data: parsedData, response: res}) : + (parsedData) => callback(parsedData, res); + + this.#parserManager + .get(res) + .parse(data, + this.#clientEmitterWrapper(this.#client), parserCallbackFn); + } + + /** + * client event emitter wrapper + * @author aacerox + * + * @param {*} client + * @return {*} + */ + #clientEmitterWrapper(client) { + return (type, event) => client.emit(type, event); + } + + /** + * prepare write HTTP method data + * @author aacerox + * + * @param {*} data + * @return {*} + */ + #prepareData(data) { + let result; + if (data instanceof Buffer || typeof data !== 'object') { + result = data; + } else { + result = JSON.stringify(data); + } + return result; + } +} diff --git a/lib/NrcDebugger.js b/lib/NrcDebugger.js new file mode 100644 index 0000000..31b5597 --- /dev/null +++ b/lib/NrcDebugger.js @@ -0,0 +1,53 @@ +'use strict'; + +import debugManager from 'debug'; + +/** + * main debug manager + * @author aacerox + * + * @type {*} + */ +const nodeDebug = debugManager('NRC'); + + +/** + * main debug function + * @author aacerox + * + * @param {...{}} args + */ +export default function debugFn(...args) { + if (!process.env.DEBUG) return; + + /** + * returns debug function callers name to be logged on debug trace + * @author aacerox + * + * @return {*} + */ + function callerName() { + try { + throw new Error(); + } catch (e) { + try { + return e.stack.split('at ')[3].split(' ')[0]; + } catch (e) { + return ''; + } + } + } + + + const now = new Date(); + // eslint-disable-next-line max-len + const header = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} ${callerName()} - `; + const innerArgs = Array.prototype.slice.call(args); + + innerArgs.splice(0, 0, header); + + + nodeDebug.apply(console, innerArgs); +}; + + diff --git a/lib/NrcIoManager.js b/lib/NrcIoManager.js new file mode 100644 index 0000000..cc6d5ac --- /dev/null +++ b/lib/NrcIoManager.js @@ -0,0 +1,566 @@ +'use strict'; + +import urlParser from 'url'; +import NrcClientRequest from './NrcClientRequest.js'; +import events from 'events'; +import debug from './NrcDebugger.js'; +import stream from 'stream'; + +// declare ioManager constants +const CONSTANTS = { + HEADER_CONTENT_LENGTH: 'Content-Length', +}; + +/** + * Manage the creation and configuration of HTTP methods + * @author aacerox + * + * @export + * @class NrcIoManager + * @typedef {NrcIoManager} + */ +export default class NrcIoManager extends events.EventEmitter { + /** + * nrc connect manager instance + * @date 8/9/2023 - 5:46:33 PM + * + * @type {*} + */ + #connectManager; + + /** + * nrc instance + * @author aacerox + * + * @type {*} + */ + #client; + + /** + * nrc instance request serializers + * @date 8/9/2023 - 5:47:16 PM + * + * @type {*} + */ + #serializerManager; + + /** + * nrc instance response parsers + * @date 8/9/2023 - 5:47:20 PM + * + * @type {*} + */ + #parserManager; + + /** + * Creates an instance of NrcIoManager. + * @author aacerox + * + * @constructor + * @param {*} client + * @param {*} connectManager + * @param {*} serializerManager + * @param {*} parserManager + */ + constructor(client, connectManager, serializerManager, parserManager) { + super(); + this.#client = client; + this.#connectManager = connectManager; + this.#serializerManager = serializerManager; + this.#parserManager = parserManager; + } + + /** + * create an HTTP method by using promises or function callbacks + * @author aacerox + * + * @param {*} methodName + * @param {*} config + * @param {*} usePromises + * @return {*} + */ + createHttpMethod(methodName, config, usePromises) { + const self = this; + if (usePromises) { + return (url, args) => + new Promise((successFn, errorFn) => { + try { + const clientRequest = new NrcClientRequest(); + self.#connect( + config, + methodName.toUpperCase(), + url, + args, + successFn, + clientRequest, + ); + return clientRequest; + } catch (err) { + errorFn(err); + } + }); + } else { + return (url, args, callback) => { + const clientRequest = new NrcClientRequest(); + self.#connect( + config, + methodName.toUpperCase(), + url, + args, + callback, + clientRequest, + ); + return clientRequest; + }; + } + } + + /** + * add passed mimetypes to response parsers + * @author aacerox + * + * @param {*} mimetypes + * @deprecated + */ + mergeMimeTypes(mimetypes) { + // this function is left for backward compatibility, but will be + // deleted in future releases + let parser = null; + // merge mime-types passed as options to parsers + if (mimetypes && typeof mimetypes === 'object') { + try { + if ( + mimetypes.json && + mimetypes.json instanceof Array && + mimetypes.json.length > 0 + ) { + parser = this.#parserManager.find('JSON'); + parser.contentTypes = mimetypes.json; + } else if ( + mimetypes.xml && + mimetypes.xml instanceof Array && + mimetypes.xml.length > 0 + ) { + parser = this.#parserManager.find('XML'); + parser.contentTypes = mimetypes.xml; + } + } catch (err) { + this.#client.emit( + 'error', + `cannot assign custom content types to parser, cause: ${err}`, + ); + } + } + } + + /** + * Add default HTTPS port to host if not present + * @author aacerox + * + * @param {*} url + * @return {*} + */ + #createProxyPath(url) { + let result = url.host; + // check url protocol to set path in request options + if (url.protocol === 'https:') { + // port is set, leave it, otherwise use default https 443 + result = url.host.indexOf(':') == -1 ? url.hostname + ':443' : url.host; + } + return result; + } + + /** + * create proxy security and port-forwarding headers + * @author aacerox + * + * @param {*} config + * @param {*} url + * @return {Array} + */ + #createProxyHeaders(config, url) { + const result = {}; + // if proxy requires authentication, create Proxy-Authorization headers + if (config.proxy.user && config.proxy.password) { + result['Proxy-Authorization'] = + 'Basic ' + + Buffer.from( + [config.proxy.user, self.proxy.password].join(':'), + ).toString('base64'); + } + // no tunnel proxy connection, we add the host to the headers + if (!config.useProxyTunnel) { + result['host'] = url.host; + } + + return result; + } + + /** + * Create connection options for passed HTTP method + * according nrc global or method config + * @author aacerox + * + * @param {*} config + * @param {*} connectURL + * @param {*} connectMethod + * @return { ConnectOptions} + */ + #createConnectOptions(config, connectURL, connectMethod) { + debug('connect URL = ', connectURL); + const url = urlParser.parse(connectURL); + let result = {}; + const protocol = + url.protocol.indexOf(':') == -1 ? + url.protocol : + url.protocol.substring(0, url.protocol.indexOf(':')); + const defaultPort = protocol === 'http' ? 80 : 443; + + result = { + host: + url.host.indexOf(':') == -1 ? + url.host : + url.host.substring(0, url.host.indexOf(':')), + port: url.port === undefined ? defaultPort : url.port, + path: url.path, + protocol: protocol, + href: url.href, + }; + + if (config.useProxy) result.agent = false; // cannot use default + // agent in proxy mode + + if (config.options.user && config.options.password) { + result.auth = [config.options.user, config.options.password].join(':'); + } else if (config.options.user && !config.options.password) { + // some sites only needs user with no password to + // authenticate + result.auth = config.options.user + ':'; + } + + // configure proxy connection to establish a tunnel + if (config.useProxy) { + result.proxy = { + host: config.proxy.host, + port: config.proxy.port, + protocol: config.proxy.protocol, + // if proxy tunnel use 'CONNECT' method, else get method from request + method: config.useProxyTunnel ? 'CONNECT' : connectMethod, + // if proxy tunnel set proxy path else get request path + path: config.useProxyTunnel ? this.#createProxyPath(url) : connectURL, + // createProxyHeaders add correct headers depending of + // proxy connection type + headers: this.#createProxyHeaders(url), + }; + } + + if ( + config.options.connection && + typeof config.options.connection === 'object' + ) { + // eslint-disable-next-line guard-for-in + for (const option in config.options.connection) { + result[option] = config.options.connection[option]; + } + } + + // don't use tunnel to connect to proxy, direct request + // and delete proxy options + if (!config.useProxyTunnel) { + // eslint-disable-next-line guard-for-in + for (const proxyOption in result.proxy) { + result[proxyOption] = result.proxy[proxyOption]; + } + + delete result.proxy; + } + + // add general request and response config to connect options + + result.requestConfig = config.options.requestConfig || {}; + result.responseConfig = config.options.responseConfig || {}; + + return result; + } + + /** + * Description placeholder + * @author aacerox + * + * @param {*} connectURL + * @return {{}} + */ + #decodeQueryFromURL(connectURL) { + const url = new URL(connectURL); + const query = url.query.substring(1).split('&'); + let keyValue; + const result = {}; + + // create decoded args from key value elements in query+ + for (const element of query) { + keyValue = element.split('='); + result[keyValue[0]] = decodeURIComponent(keyValue[1]); + } + + return result; + } + /** + * Description placeholder + * @author aacerox + */ + /** + * Description placeholder + * @author aacerox + */ + /** + * Description placeholder + * @author aacerox + * + * @param {*} args + * @return {*} + */ + #serializeEncodeQueryFromArgs(args) { + /** + * Description placeholder + * @author aacerox + * + * @param {*} obj + * @param {*} parent + * @return {*} + */ + function serialize(obj, parent) { + const tokens = []; + let propertyName; + // iterate over all properties + for (propertyName in obj) { + // if object has property (it's not an array iteration) + if (obj.hasOwnProperty(propertyName)) { + // if property has parent, add nested reference + const parsedProperty = parent ? + parent + '[' + propertyName + ']' : + propertyName; + const propertyValue = obj[propertyName]; + + // if property has value and is object (we must iterate + // again, not final leaf) + // iterate over object property passing current parsed + // property as parent + // else add encoded parsed property and value to result + // array + tokens.push( + propertyValue !== null && typeof propertyValue === 'object' ? + serialize(propertyValue, parsedProperty) : + encodeURIComponent(parsedProperty) + + '=' + + encodeURIComponent(propertyValue), + ); + } + } + return tokens.join('&'); + } + + debug('args is', args); + // check args consistency + if (args && typeof args !== 'object') { + this.#client.emit( + 'error', + // eslint-disable-next-line max-len + `cannot serialize parameters: invalid type ${typeof args} should be an object type`, + ); + } + + return serialize(args); + } + + /** + * Description placeholder + * @author aacerox + * + * @param {*} args + * @param {*} url + * @return {*} + */ + #parsePathParameters(args, url) { + let result = url; + if (!args?.path) return url; + + // eslint-disable-next-line guard-for-in + for (const placeholder in args.path) { + const regex = new RegExp('\\$\\{' + placeholder + '\\}', 'i'); + result = result.replace(regex, args.path[placeholder]); + } + + return result; + } + + /** + * Description placeholder + * @author aacerox + * + * @param {*} connectOptions + * @param {*} methodOptions + */ + #overrideClientConfig(connectOptions, methodOptions) { + /** + * Description placeholder + * @author aacerox + * + * @param {*} reqResOption + * @return {boolean} + */ + function validateReqResOptions(reqResOption) { + return reqResOption && typeof reqResOption === 'object'; + } + // check if we have particular request or response config set on + // this method invocation + // and override general request/response config + if (validateReqResOptions(methodOptions.requestConfig)) { + Object.assign(connectOptions.requestConfig, methodOptions.requestConfig); + } + + if (validateReqResOptions(methodOptions.responseConfig)) { + Object.assign( + connectOptions.responseConfig, + methodOptions.responseConfig, + ); + } + } + + /** + * Description placeholder + * @author aacerox + * + * @param {*} config + * @param {*} method + * @param {*} url + * @param {*} args + * @param {*} callback + * @param {*} clientRequest + */ + #connect(config, method, url, args, callback, clientRequest) { + // wrapper for emit function on client + const clientEventEmitter = function(client) { + return function(type, event) { + client.emit(type, event); + }; + }; + + // check args type if we use it + if (callback && args && typeof args !== 'object') { + this.#client.emit('error', 'args should be and object'); + } + + // configure connect options based on url parameter parse + const options = this.#createConnectOptions( + config, + this.#parsePathParameters(args, url), + method, + ); + debug('options pre connect', options); + + options.method = method; + options.clientRequest = clientRequest; + options.headers = options.headers || {}; + + clientRequest.href = options.href; + + debug('args = ', args); + debug('args.data = ', args !== undefined ? args.data : undefined); + // no args passed + if (typeof args === 'function') { + callback = args; + // add Content-length to POST/PUT/DELETE/PATCH methods + if (method !== 'GET') { + options.headers[CONSTANTS.HEADER_CONTENT_LENGTH] = 0; + } + } else if (typeof args === 'object') { + // add headers and POST/PUT/DELETE/PATCH data to connect options + // to be passed + // with request, but without deleting other headers like + // non-tunnel proxy headers + if (args.headers) { + for (const headerName in args.headers) { + if (args.headers.hasOwnProperty(headerName)) { + options.headers[headerName] = args.headers[headerName]; + } + } + } + + // we have args, go and check if we have parameters + if (args.parameters && Object.keys(args.parameters).length > 0) { + // validate URL consistency, and fix it adding query + // parameter separation char + + // check if URL already has '?' path parameter separator + // char in any position that is not final + // if true throw error + const pathLength = options.path.length; + const pathParameterSepCharPos = options.path.indexOf('?'); + + if ( + pathParameterSepCharPos >= 0 && + pathParameterSepCharPos !== pathLength - 1 + ) { + this.#client.emit( + 'error', + // eslint-disable-next-line max-len + `parameters argument cannot be used if parameters are already defined in URL ${options.path}`, + ); + } + + options.path += options.path.charAt(pathLength - 1) === '?' ? '' : '?'; + // check if we have serializable parameter container, that + // must be serialized and encoded + // directly, as javascript object + options.path = options.path.concat( + this.#serializeEncodeQueryFromArgs(args.parameters), + ); + debug('options.path after request parameters = ', options.path); + } + + // override client config, by the moment just for request + // response config + this.#overrideClientConfig(options, args); + + // always set Content-length header if not set previously + // set Content length for some servers to work (nginx, apache) + + if (args.data instanceof stream) { + // if data is stream redirect to options to be used + options.data = args.data; + } else if ( + args.data !== undefined && + !options.headers.hasOwnProperty(CONSTANTS.HEADER_CONTENT_LENGTH) + ) { + this.#serializerManager + .get(options) + .serialize( + args.data, + clientEventEmitter(this.#client), + function(serializedData) { + options.data = serializedData; + options.headers[CONSTANTS.HEADER_CONTENT_LENGTH] = + Buffer.byteLength(options.data, 'utf8'); + }, + ); + } else { + options.headers[CONSTANTS.HEADER_CONTENT_LENGTH] = 0; + } + + // add family arg for fix DNS error, https://github.com/nodejs/node/issues/5436 + if (args.family === 4 || args.family === 6) { + options.family = args.family; + } + } + + debug('options post connect', options); + debug('FINAL client object ====>', config); + + if (config.useProxy && config.useProxyTunnel) { + this.#connectManager.proxy(options, callback); + } else { + // normal connection and direct proxy connections (no tunneling) + this.#connectManager.normal(options, callback); + } + } +} diff --git a/lib/node-rest-client.js b/lib/node-rest-client.js deleted file mode 100644 index 35fccf3..0000000 --- a/lib/node-rest-client.js +++ /dev/null @@ -1,745 +0,0 @@ -var http = require('follow-redirects').http, -https = require('follow-redirects').https, -urlParser = require('url'), -util = require("util"), -events = require("events"), -zlib = require("zlib"), -node_debug = require("debug")("NRC"); - -exports.Client = function (options){ - var self = this, - // parser response manager - parserManager = require("./nrc-parser-manager")(), - serializerManager = require("./nrc-serializer-manager")(), - // connection manager - connectManager = new ConnectManager(this, parserManager), - // io facade to parsers and serailiazers - ioFacade = function(parserManager, serializerManager){ - // error execution context - var errorContext = function(logic){ - return function(){ - try{ - return logic.apply(this, arguments); - }catch(err){ - self.emit('error',err); - } - }; - }, - result={"parsers":{}, "serializers":{}}; - - // parsers facade - result.parsers.add = errorContext(parserManager.add); - result.parsers.remove = errorContext(parserManager.remove); - result.parsers.find = errorContext(parserManager.find); - result.parsers.getAll = errorContext(parserManager.getAll); - result.parsers.getDefault = errorContext(parserManager.getDefault); - result.parsers.clean = errorContext(parserManager.clean); - - // serializers facade - result.serializers.add = errorContext(serializerManager.add); - result.serializers.remove = errorContext(serializerManager.remove); - result.serializers.find = errorContext(serializerManager.find); - result.serializers.getAll = errorContext(serializerManager.getAll); - result.serializers.getDefault = errorContext(serializerManager.getDefault); - result.serializers.clean = errorContext(serializerManager.clean); - - return result; - - }(parserManager,serializerManager), - // declare util constants - CONSTANTS={ - HEADER_CONTENT_LENGTH:"Content-Length" - }; - - - self.options = options || {}, - self.useProxy = (self.options.proxy || false)?true:false, - self.useProxyTunnel = (!self.useProxy || self.options.proxy.tunnel===undefined)?false:self.options.proxy.tunnel, - self.proxy = self.options.proxy, - self.connection = self.options.connection || {}, - self.mimetypes = self.options.mimetypes || {}, - self.requestConfig = self.options.requestConfig || {}, - self.responseConfig = self.options.responseConfig || {}; - - // namespaces for methods, parsers y serializers - this.methods={}; - this.parsers={}; - this.serializers={}; - - // Client Request to be passed to ConnectManager and returned - // for each REST method invocation - var ClientRequest =function(){ - events.EventEmitter.call(this); - }; - - - util.inherits(ClientRequest, events.EventEmitter); - - - ClientRequest.prototype.end = function(){ - if(this._httpRequest) { - this._httpRequest.end(); - } - }; - - ClientRequest.prototype.setHttpRequest=function(req){ - this._httpRequest = req; - }; - - - - var Util = { - createProxyPath:function(url){ - var result = url.host; - // check url protocol to set path in request options - if (url.protocol === "https:"){ - // port is set, leave it, otherwise use default https 443 - result = (url.host.indexOf(":") == -1?url.hostname + ":443":url.host); - } - - return result; - }, - createProxyHeaders:function(url){ - var result ={}; - // if proxy requires authentication, create Proxy-Authorization headers - if (self.proxy.user && self.proxy.password){ - result["Proxy-Authorization"] = "Basic " + new Buffer([self.proxy.user,self.proxy.password].join(":")).toString("base64"); - } - // no tunnel proxy connection, we add the host to the headers - if(!self.useProxyTunnel) - result["host"] = url.host; - - return result; - }, - createConnectOptions:function(connectURL, connectMethod){ - debug("connect URL = ", connectURL); - var url = urlParser.parse(connectURL), - path, - result={}, - protocol = url.protocol.indexOf(":") == -1?url.protocol:url.protocol.substring(0,url.protocol.indexOf(":")), - defaultPort = protocol === 'http'?80:443; - - result ={ - host: url.host.indexOf(":") == -1?url.host:url.host.substring(0,url.host.indexOf(":")), - port: url.port === undefined?defaultPort:url.port, - path: url.path, - protocol:protocol, - href:url.href - }; - - if (self.useProxy) result.agent = false; // cannot use default - // agent in proxy mode - - if (self.options.user && self.options.password){ - result.auth = [self.options.user,self.options.password].join(":"); - - } else if (self.options.user && !self.options.password){ - // some sites only needs user with no password to - // authenticate - result.auth = self.options.user + ":"; - } - - // configure proxy connection to establish a tunnel - if (self.useProxy){ - - result.proxy ={ - host: self.proxy.host, - port: self.proxy.port, - method: self.useProxyTunnel?'CONNECT':connectMethod,// if - // proxy - // tunnel - // use - // 'CONNECT' - // method, - // else - // get - // method - // from - // request, - path: self.useProxyTunnel?this.createProxyPath(url):connectURL, // if - // proxy - // tunnel - // set - // proxy - // path - // else - // get - // request - // path, - headers: this.createProxyHeaders(url) // createProxyHeaders - // add correct - // headers depending - // of proxy - // connection type - }; - } - - if(self.connection && typeof self.connection === 'object'){ - for(var option in self.connection){ - result[option] = self.connection[option]; - } - } - - // don't use tunnel to connect to proxy, direct request - // and delete proxy options - if (!self.useProxyTunnel){ - for (var proxyOption in result.proxy){ - result[proxyOption] = result.proxy[proxyOption]; - } - - delete result.proxy; - } - - // add general request and response config to connect options - - result.requestConfig = self.requestConfig; - result.responseConfig = self.responseConfig; - - - return result; - }, - decodeQueryFromURL: function(connectURL){ - var url = urlParser.parse(connectURL), - query = url.query.substring(1).split("&"), - keyValue, - result={}; - - // create decoded args from key value elements in query+ - for (var i=0;i= 0 && pathParameterSepCharPos!== pathLength -1 ) - self.emit('error','parameters argument cannot be used if parameters are already defined in URL ' + options.path); - - options.path +=(options.path.charAt(pathLength-1) === '?'?"":"?"); - // check if we have serializable parameter container, that - // must be serialized and encoded - // directly, as javascript object - options.path = options.path.concat(Util.serializeEncodeQueryFromArgs(args.parameters)); - debug("options.path after request parameters = ", options.path); - } - - // override client config, by the moment just for request - // response config - this.overrideClientConfig(options,args); - - // always set Content-length header if not set previously - // set Content lentgh for some servers to work (nginx, apache) - if (args.data !== undefined && !options.headers.hasOwnProperty(CONSTANTS.HEADER_CONTENT_LENGTH)){ - serializerManager.get(options).serialize(args.data, clientEmitterWrapper(self), function(serializedData){ - options.data = serializedData; - options.headers[CONSTANTS.HEADER_CONTENT_LENGTH] = Buffer.byteLength(options.data, 'utf8'); - }); - }else{ - options.headers[CONSTANTS.HEADER_CONTENT_LENGTH] = 0; - } - - - } - - - debug("options post connect",options); - debug("FINAL SELF object ====>", self); - - if (self.useProxy && self.useProxyTunnel){ - connectManager.proxy(options,callback); - }else{ - // normal connection and direct proxy connections (no tunneling) - connectManager.normal(options,callback); - } - }, - mergeMimeTypes:function(mimetypes){ - // this function is left for backward compatibility, but will be - // deleted in future releases - var parser = null; - // merge mime-types passed as options to parsers - if (mimetypes && typeof mimetypes === "object"){ - try{ - if (mimetypes.json && mimetypes.json instanceof Array && mimetypes.json.length > 0){ - parser = parserManager.find("JSON"); - parser.contentTypes = mimetypes.json; - }else if (mimetypes.xml && mimetypes.xml instanceof Array && mimetypes.xml.length > 0){ - parser = parserManager.find("XML"); - parser.contentTypes = mimetypes.xml; - } - }catch(err){ - self.emit('error', 'cannot assign custom content types to parser, cause: ' + err); - } - } - }, - createHttpMethod:function(methodName){ - return function(url, args, callback){ - var clientRequest = new ClientRequest(); - Util.connect(methodName.toUpperCase(), url, args, callback, clientRequest); - return clientRequest; - }; - } - }, - Method = function(url, method){ - var httpMethod = self[method.toLowerCase()]; - - return function(args,callback){ - var completeURL = url; - // no args - if (typeof args === 'function'){ - callback = args; - args = {}; - } - - return httpMethod(completeURL, args , callback); - }; - }; - - - - - this.get = Util.createHttpMethod("get"); - - this.post = Util.createHttpMethod("post"); - - this.put = Util.createHttpMethod("put"); - - this.delete = Util.createHttpMethod("delete"); - - this.patch = Util.createHttpMethod("patch"); - - - this.registerMethod = function(name, url, method){ - // create method in method registry with preconfigured REST invocation - // method - this.methods[name] = new Method(url,method); - }; - - this.unregisterMethod = function(name){ - delete this.methods[name]; - }; - - this.addCustomHttpMethod=function(methodName){ - self[methodName.toLowerCase()] = Util.createHttpMethod(methodName); - }; - - this.parsers = ioFacade.parsers; - - this.serializers = ioFacade.serializers; - - // merge mime types with connect manager - Util.mergeMimeTypes(self.mimetypes); - debug("ConnectManager", connectManager); - -}; - - -var ConnectManager = function(client, parserManager) { - - var client = client, - clientEmitterWrapper = function (client){ - var client = client; - return function(type, event){client.emit(type, event);}; - }; - - - - this.configureRequest = function(req, config, clientRequest){ - - if (config.timeout){ - req.setTimeout(config.timeout, function(){ - clientRequest.emit('requestTimeout',req); - }); - } - - - if(config.noDelay) - req.setNoDelay(config.noDelay); - - if(config.keepAlive) - req.setSocketKeepAlive(config.noDelay,config.keepAliveDelay || 0); - - }; - - this.configureResponse = function(res,config, clientRequest){ - if (config.timeout){ - res.setTimeout(config.timeout, function(){ - clientRequest.emit('responseTimeout',res); - res.close(); - }); - } - }; - - this.configureOptions = function(options){ - var followRedirectsProps =["followRedirects", "maxRedirects"]; - function configureProps(propsArray, optionsElement){ - for (var index in propsArray){ - if (optionsElement.hasOwnProperty(propsArray[index])) - options[propsArray[index]] = optionsElement[propsArray[index]]; - } - } - - //add follows-redirects config - configureProps(followRedirectsProps, options.requestConfig); - - - // remove "protocol" and "clientRequest" option from options, - // cos is not allowed by http/hppts node objects - delete options.protocol; - delete options.clientRequest; - delete options.requestConfig; - delete options.responseConfig; - debug("options pre connect", options); - }; - - this.handleEnd = function(res,buffer,callback){ - - var self = this, - content = res.headers["content-type"], - encoding = res.headers["content-encoding"]; - - debug("content-type: ", content); - debug("content-encoding: ",encoding); - - if(encoding !== undefined && encoding.indexOf("gzip") >= 0){ - debug("gunzip"); - zlib.gunzip(Buffer.concat(buffer),function(er,gunzipped){ - self.handleResponse(res,gunzipped,callback); - }); - }else if(encoding !== undefined && encoding.indexOf("deflate") >= 0){ - debug("inflate"); - zlib.inflate(Buffer.concat(buffer),function(er,inflated){ - self.handleResponse(res,inflated,callback); - }); - }else { - debug("not compressed"); - self.handleResponse(res,Buffer.concat(buffer),callback); - } - }; - - this.handleResponse = function(res,data,callback){ - // find valid parser to be used with response content type, first one - // found - parserManager.get(res).parse(data, clientEmitterWrapper(client), function(parsedData){ - callback(parsedData,res); - }); - }; - - this.prepareData = function(data){ - var result; - if ((data instanceof Buffer) || (typeof data !== 'object')){ - result = data; - }else{ - result = JSON.stringify(data); - } - return result; - }; - - this.proxy = function(options, callback){ - - debug("proxy options",options.proxy); - - // creare a new proxy tunnel, and use to connect to API URL - var proxyTunnel = http.request(options.proxy), - self = this; - - - proxyTunnel.on('connect',function(res, socket, head){ - debug("proxy connected",socket); - - // set tunnel socket in request options, that's the tunnel - // itself - options.socket = socket; - - var buffer=[], - protocol = (options.protocol =="http")?http:https, - clientRequest = options.clientRequest, - requestConfig = options.requestConfig, - responseConfig = options.responseConfig; - - self.configureOptions(options); - - // add request options to request returned to calling method - clientRequest.options = options; - - var request = protocol.request(options, function(res){ - // configure response - self.configureResponse(res,responseConfig, clientRequest); - - // concurrent data chunk handler - res.on('data',function(chunk){ - buffer.push(Buffer.from(chunk)); - }); - - res.on('end',function(){ - self.handleEnd(res,buffer,callback); - }); - - - // handler response errors - res.on('error',function(err){ - if (clientRequest !== undefined && typeof clientRequest === 'object'){ - // add request as property of error - err.request = clientRequest; - err.response = res; - // request error handler - clientRequest.emit('error',err); - }else{ - // general error handler - client.emit('error',err); - } - }); - }); - - - - // configure request and add it to clientRequest - // and add it to request returned - self.configureRequest(request,requestConfig, clientRequest); - clientRequest.setHttpRequest(request); - - - // write POST/PUT data to request body; - // find valid serializer to be used to serialize request data, - // first one found - // is the one to be used.if none found for match condition, - // default serializer is used - - if(options.data)request.write(options.data); - - request.end(); - - - // handle request errors and handle them by request or general - // error handler - request.on('error',function(err){ - if (clientRequest !== undefined && typeof clientRequest === 'object'){ - // add request as property of error - err.request = clientRequest; - - // request error handler - clientRequest.emit('error',err); - }else{ - // general error handler - client.emit('error',err); - } - }); - }); - - // proxy tunnel error are only handled by general error handler - proxyTunnel.on('error',function(e){ - client.emit('error',e); - }); - - proxyTunnel.end(); - - }; - - this.normal = function(options, callback){ - - var buffer = [], - protocol = (options.protocol === "http")?http:https, - clientRequest = options.clientRequest, - requestConfig = options.requestConfig, - responseConfig = options.responseConfig, - self = this; - - self.configureOptions(options); - - // add request options to request returned to calling method - clientRequest.options = options; - - var request = protocol.request(options, function(res){ - // configure response - self.configureResponse(res,responseConfig, clientRequest); - - // concurrent data chunk handler - res.on('data',function(chunk){ - buffer.push(Buffer.from(chunk)); - }); - - res.on('end',function(){ - - self.handleEnd(res,buffer,callback); - - }); - - // handler response errors - res.on('error',function(err){ - if (clientRequest !== undefined && typeof clientRequest === 'object'){ - // add request as property of error - err.request = clientRequest; - err.response = res; - // request error handler - clientRequest.emit('error',err); - }else{ - // general error handler - client.emit('error',err); - } - }); - }); - - // configure request and add it to clientRequest - // and add it to request returned - self.configureRequest(request,requestConfig, clientRequest); - debug("clientRequest",clientRequest); - - clientRequest.setHttpRequest(request); - - debug("options data", options.data); - // write POST/PUT data to request body; - // find valid serializer to be used to serialize request data, - // first one found - // is the one to be used.if none found for match condition, - // default serializer is used - if(options.data)request.write(options.data); - request.end(); // end request when data is written - - // handle request errors and handle them by request or general - // error handler - request.on('error',function(err){ - if (clientRequest !== undefined && typeof clientRequest === 'object'){ - // add request as property of error - err.request = clientRequest; - - // request error handler - clientRequest.emit('error',err); - }else{ - // general error handler - client.emit('error',err); - } - }); - }; - }; - - - // event handlers for client and ConnectManager - util.inherits(exports.Client, events.EventEmitter); - - - var debug = function(){ - if (!process.env.DEBUG) return; - - var now = new Date(), - header =now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + " [NRC CLIENT]" + arguments.callee.caller.name + " -> ", - args = Array.prototype.slice.call(arguments); - args.splice(0,0,header); - node_debug.apply(console,args); - - - }; diff --git a/lib/nrc-parser-manager.js b/lib/nrc-parser-manager.js index 3281083..0819d18 100644 --- a/lib/nrc-parser-manager.js +++ b/lib/nrc-parser-manager.js @@ -1,156 +1,265 @@ -var ParserManager = function(){ - var registry={}, defaultParser = null; - - var _private={ - "validate":function(parser){ - - function validateProperties(parser, props){ - var result = true; - for (var propIndex in props){ - var propType = props[propIndex].split(":"); - if (!parser.hasOwnProperty([propType[0]]) || typeof parser[propType[0]] !== propType[1]){ - result = false; - break; - } - } - - return result; - } - - - result = validateProperties(parser,["name:string","parse:function","isDefault:boolean"]); - - // valid parser, check if its not default response parser, to validate non - // default parser props - if (result && !parser.isDefault) - result = validateProperties(parser,["match:function"]); - - - return result; - } - }; - - this.add = function(parser){ - if (!_private.validate(parser)) - throw "parser cannot be added: invalid parser definition"; - - if (parser.isDefault){ - defaultParser = parser; - }else{ - registry[parser.name] = parser; - } - }; - - this.remove = function(parserName){ - var result = registry[parserName]; - if (!result) - throw "cannot remove parser: " + parserName +" doesn't exists"; - - delete registry[parserName]; - }; - - this.clean = function(){ - registry={}; - }; - - this.find = function(parserName){ - var result = registry[parserName]; - if (!result) - throw "cannot find parser: " + parserName + " doesn't exists "; - - return result; - }; - - this.getDefault = function(){ - return defaultParser; - }; - - this.get = function(response){ - var result = null; - for (var parserName in registry){ - if (registry[parserName].match(response)){ - result = registry[parserName]; - break; - } - } - // if parser not found return default parser, else parser found - return (result === null)?defaultParser:result; - }; - - this.getAll=function(){ - var result=[]; - for (var parserName in registry){ - result.push(registry[parserName]); - } - return result; - } -}; +'use strict'; +import xmlParser from 'xml2js'; -module.exports = function(){ +/** + * node-rest-client response parser manager + * + * @class ParserManager + * @typedef {ParserManager} + */ +class ParserManager { + /** + * parsers registry + * + * @type {Map} + */ + #registry = new Map(); + /** + * default parser to be used when no other parser match + * + * @type {} + */ + #defaultParser; -var parserManager = new ParserManager(); + /** + * add a new parser + * + * @param {*} parser + */ + add(parser) { + if (!this.#validate(parser)) { + throw new Error('parser cannot be added: invalid parser definition'); + } -var BaseParser = { - "isDefault":false, - "match":function(response){ - var result = false, - contentType = response.headers["content-type"] && response.headers["content-type"].replace(/ /g, ''); + if (parser.isDefault) { + this.#defaultParser = parser; + } else { + this.#registry.set(parser.name, parser); + } + } - if (!contentType) return result; + /** + * Remove an existing parser + * + * @param {*} parserName + */ + remove(parserName) { + if (!this.#registry.has(parserName)) { + throw new Error(`cannot remove parser: ${parserName} doesn't exists`); + } - for (var i=0; i value.match(response)) + .map(([key, value]) => value)[0]; + + // if parser not found return default parser, else parser found + return result || this.#defaultParser; + } + + /** + * Returns all parsers available in the registry (excluding default) + * + * @return {*} + */ + getAll() { + return Array.from(this.#registry.values()); + } + + /** + * Validate parser structure + * + * @param {*} parser + * @return {boolean} + */ + #validate(parser) { + /** + * Validate that parser properties match with expected + * + * @param {*} parser + * @param {*} props + * @return {boolean} + */ + function validateProperties(parser, props) { + let result = true; + // eslint-disable-next-line guard-for-in + for (const propIndex in props) { + const propType = props[propIndex].split(':'); + if ( + !parser.hasOwnProperty([propType[0]]) || + typeof parser[propType[0]] !== propType[1] + ) { + result = false; + break; + } + } + + return result; + } + + let result = validateProperties(parser, [ + 'name:string', + 'parse:function', + 'isDefault:boolean', + ]); + + // valid parser, check if its not default response parser, to validate non + // default parser props + if (result && !parser.isDefault) { + result = validateProperties(parser, ['match:function']); + } -//add default parser managers: JSON,XML and unknown content/type -parserManager.add(Object.assign({ - "name":"XML", - "options":{"explicitArray":false}, - "contentTypes":["application/xml","application/xml;charset=utf-8","text/xml","text/xml;charset=utf-8"], - "parseString":require('xml2js').parseString, - "parse":function(byteBuffer,nrcEventEmitter,parsedCallback){ - this.parseString(byteBuffer.toString(),this.options, function (err, result) { - parsedCallback(result); - }); - } -}, BaseParser)); - -parserManager.add(Object.assign({ - "name":"JSON", - "contentTypes":["application/json","application/json;charset=utf-8"], - "isValidData":function(data){ - return data !== undefined && (data.length !== undefined && data.length > 0); - }, - "parse":function(byteBuffer,nrcEventEmitter,parsedCallback){ - var jsonData, - data = byteBuffer.toString(); - - try { - jsonData = this.isValidData(data)?JSON.parse(data):data; - } catch (err) { + return result; + } +} + +/** + * Main parser manager function where the default and common parsers are load + * @date 4/25/2023 - 10:53:15 PM + * + * @export + * @return {ParserManager} + */ +const initializeParserManager =function() { + const parserManager = new ParserManager(); + + // common parser method and attributes + const BaseParser = { + isDefault: false, + match: function(response) { + let result = false; + const contentType = + response.headers['content-type']?.replace(/ /g, ''); + + if (!contentType) return result; + + for (const element of this.contentTypes) { + result = + element.trim().toLowerCase() === contentType.trim().toLowerCase(); + if (result) break; + } + + return result; + }, + }; + + // add default XML parser + parserManager.add( + Object.assign( + { + name: 'XML', + options: {explicitArray: false}, + contentTypes: [ + 'application/xml', + 'application/xml;charset=utf-8', + 'text/xml', + 'text/xml;charset=utf-8', + ], + parseString: xmlParser.parseString, + parse: function(byteBuffer, nrcEventEmitter, parsedCallback) { + this.parseString( + byteBuffer.toString(), + this.options, + function(err, result) { + parsedCallback(result); + }, + ); + }, + }, + BaseParser, + ), + ); + + // add default json parser + parserManager.add( + Object.assign( + { + name: 'JSON', + // eslint-disable-next-line max-len + contentTypes: [ + 'application/json', + 'application/json;charset=utf-8', + 'application/jsoncharset=utf-8', + ], + isValidData: (data) => { + return ( + // eslint-disable-next-line max-len + data !== undefined && data.length !== undefined && data.length > 0 + ); + }, + parse: function(byteBuffer, nrcEventEmitter, parsedCallback) { + let jsonData; + const data = byteBuffer.toString(); + + try { + jsonData = this.isValidData(data) ? JSON.parse(data) : data; + } catch (err) { // Something went wrong when parsing json. This can happen // for many reasons, including a bad implementation on the // server. - nrcEventEmitter('error','Error parsing response. response: [' +data + '], error: [' + err + ']'); - } - parsedCallback(jsonData); - } - },BaseParser)); + nrcEventEmitter( + 'error', + // eslint-disable-next-line max-len + `Error parsing response. response: [${data}], error: [${err}]`, + ); + } + parsedCallback(jsonData); + }, + }, + BaseParser, + ), + ); + parserManager.add({ + name: 'DEFAULT', + isDefault: true, + parse: (byteBuffer, nrcEventEmitter, parsedCallback) => + parsedCallback(byteBuffer), + }); -parserManager.add({ - "name":"DEFAULT", - "isDefault":true, - "parse":function(byteBuffer,nrcEventEmitter,parsedCallback){ - parsedCallback(byteBuffer); - } -}); + return parserManager; +}; -return parserManager; -} +export default initializeParserManager; diff --git a/lib/nrc-serializer-manager.js b/lib/nrc-serializer-manager.js index 9707802..ea666af 100644 --- a/lib/nrc-serializer-manager.js +++ b/lib/nrc-serializer-manager.js @@ -1,185 +1,305 @@ -var xmlserializer = require('xml2js'); - -var SerializerManager = function(){ - var registry={}, defaultSerializer = null; - - var _private={ - "validate":function(serializer){ - - function validateProperties(serializer, props){ - var result = true; - for (var propIndex in props){ - var propType = props[propIndex].split(":"); - if (!serializer.hasOwnProperty([propType[0]]) || typeof serializer[propType[0]] !== propType[1]){ - result = false; - break; - } - } - - return result; - } - - - result = validateProperties(serializer,["name:string","serialize:function","isDefault:boolean"]); - - // valid serializer, check if its not default request serializer, to validate non - // default serializer props - if (result && !serializer.isDefault) - result = validateProperties(serializer,["match:function"]); - - - return result; - } - }; - - this.add = function(serializer){ - if (!_private.validate(serializer)) - throw "serializer cannot be added: invalid serializer definition"; - - if (serializer.isDefault){ - defaultSerializer = serializer; - }else{ - registry[serializer.name] = serializer; - } - }; - - this.remove = function(serializerName){ - var result = registry[serializerName]; - if (!result) - throw "cannot remove serializer: " + serializerName +" doesn't exists"; - - delete registry[serializerName]; - }; - - this.find = function(serializerName){ - var result = registry[serializerName]; - if (!result) - throw "cannot find serializer: " + serializerName +" doesn't exists"; - - return result; - }; - - - this.clean = function(){ - registry={}; - }; - - this.get = function(request){ - var result = null; - for (var serializerName in registry){ - if (registry[serializerName].match(request)){ - result = registry[serializerName]; - break; - } - } - // if serializer not found return default serializer, else serializer found - return (result === null)?defaultSerializer:result; - }; - - this.getAll=function(){ - var result = []; - for (var serializerName in registry){ - result.push(registry[serializerName]); - } - return result; - }; - - this.getDefault = function(){ - return defaultSerializer; - }; -}; - - - - -module.exports = function(){ - -var serializerManager = new SerializerManager(); +import XmlSerializer from 'xml2js'; + +/** + * request Serializer manager for node-rest-client + * @date 4/26/2023 - 12:45:40 PM + * + * @class SerializerManager + * @typedef {SerializerManager} + */ +class SerializerManager { + /** + * serializers registry + * @date 4/26/2023 - 12:45:40 PM + * + * @type {*} + */ + #registry = new Map(); + /** + * default serializer used when no match serializer found for reponse + * @date 4/26/2023 - 12:45:40 PM + * + * @type {*} + */ + #defaultSerializer; + + /** + * add serializer to registry + * @date 4/26/2023 - 12:45:40 PM + * + * @param {*} serializer + */ + add(serializer) { + if (!this.#validate(serializer)) { + throw new Error( + 'serializer cannot be added: invalid serializer definition', + ); + } -var BaseSerializer ={ - "isDefault":false, - "match":function(request){ - var result = false, - contentType = request.headers["Content-Type"] && request.headers["Content-Type"].replace(/ /g, ''); + if (serializer.isDefault) { + this.#defaultSerializer = serializer; + } else { + this.#registry.set(serializer.name, serializer); + } + } + + /** + * Remove serializer from registry + * + * @param {*} serializerName + */ + remove(serializerName) { + this.#checkExists(serializerName); + + this.#registry.delete(serializerName); + } + + /** + * Find a serializer in the registry by its name + * + * @param {*} serializerName + * @return {*} + */ + find(serializerName) { + this.#checkExists(serializerName); + + return this.#registry.get(serializerName); + } + + /** + * Clean the serializers registry + */ + clean() { + this.#registry.clear(); + } + + /** + * Get the serializer that match with the response passed + * according to its match logic + * + * @param {*} request + * @return {*} + */ + get(request) { + const result = Array.from(this.#registry.entries()) + .filter(([key, value]) => value.match(request)) + .map(([key, value]) => value)[0]; + + // if parser not found return default parser, else parser found + return result || this.#defaultSerializer; + } + + + /** + * Return all available regular serializers + * @author aacerox + * + * @return {*} + */ + getAll() { + return Array.from(this.#registry.values()); + } + + /** + * Description placeholder + * @date 4/26/2023 - 12:45:40 PM + * + * @return {*} + */ + getDefault() { + return defaultSerializer; + } + + /** + * Description placeholder + * @date 4/26/2023 - 12:45:40 PM + * + * @param {*} serializerName + */ + #checkExists(serializerName) { + if (!this.#registry.has(serializerName)) { + throw new Error( + `cannot find serializer: ${serializerName} doesn't exists`, + ); + } + } + + /** + * Validate Serializer structure + * + * @param {*} serializer + * @return {boolean} + */ + #validate(serializer) { + /** + * Validate that serializer properties match with expected + * @author aacerox + * + * @param {*} serializer + * @param {*} props + * @return {boolean} + */ + function validateProperties(serializer, props) { + let result = true; + // eslint-disable-next-line guard-for-in + for (const propIndex in props) { + const propType = props[propIndex].split(':'); + if ( + !serializer.hasOwnProperty([propType[0]]) || + typeof serializer[propType[0]] !== propType[1] + ) { + result = false; + break; + } + } + + return result; + } - if (!contentType) return result; + let result = validateProperties(serializer, [ + 'name:string', + 'serialize:function', + 'isDefault:boolean', + ]); - for (var i=0; i=1.14.8", + "xml2js": ">=0.4.23" + }, + "devDependencies": { + "@changesets/cli": "^2.26.2", + "@types/jest": "^29.5.1", + "@types/node": "^20.2.3", + "eslint": "^8.39.0", + "eslint-config-google": "^0.14.0", + "mocha": "^10.2.0", + "rollup": "^4.22.5", + "rollup-plugin-polyfill-node": "^0.13.0", + "should": ">= 0.0.1", + "typescript": "^5.0.4" + }, + "engines": { + "node": "*" + } }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, - "requires": { - "color-convert": "^2.0.1" + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" } }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "node_modules/@babel/code-frame/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==", "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "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/@babel/code-frame/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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "node_modules/@babel/code-frame/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@babel/code-frame/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=0.8.0" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "requires": { - "fill-range": "^7.0.1" + "engines": { + "node": ">=4" } }, - "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 - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@babel/code-frame/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==", "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "dependencies": { - "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" - } - } + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "engines": { + "node": ">=6.9.0" } }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "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==", + "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==", "dev": true, - "requires": { - "color-name": "~1.1.4" + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "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 - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "requires": { - "ms": "0.7.1" + "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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" } }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "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": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "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/@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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "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/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, - "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 + "node_modules/@babel/runtime": { + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz", + "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.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/@changesets/apply-release-plan": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-6.1.4.tgz", + "integrity": "sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==", "dev": true, - "requires": { - "to-regex-range": "^5.0.1" + "dependencies": { + "@babel/runtime": "^7.20.1", + "@changesets/config": "^2.3.1", + "@changesets/get-version-range-type": "^0.3.2", + "@changesets/git": "^2.0.0", + "@changesets/types": "^5.2.1", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" } }, - "find-up": { + "node_modules/@changesets/apply-release-plan/node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "engines": { + "node": ">=8" } }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" + "node_modules/@changesets/assemble-release-plan": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.2.4.tgz", + "integrity": "sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@changesets/errors": "^0.1.4", + "@changesets/get-dependents-graph": "^1.3.6", + "@changesets/types": "^5.2.1", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "node_modules/@changesets/changelog-git": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.14.tgz", + "integrity": "sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==", + "dev": true, + "dependencies": { + "@changesets/types": "^5.2.1" + } }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/@changesets/cli": { + "version": "2.26.2", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.26.2.tgz", + "integrity": "sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==", "dev": true, - "optional": true + "dependencies": { + "@babel/runtime": "^7.20.1", + "@changesets/apply-release-plan": "^6.1.4", + "@changesets/assemble-release-plan": "^5.2.4", + "@changesets/changelog-git": "^0.1.14", + "@changesets/config": "^2.3.1", + "@changesets/errors": "^0.1.4", + "@changesets/get-dependents-graph": "^1.3.6", + "@changesets/get-release-plan": "^3.0.17", + "@changesets/git": "^2.0.0", + "@changesets/logger": "^0.0.5", + "@changesets/pre": "^1.0.14", + "@changesets/read": "^0.5.9", + "@changesets/types": "^5.2.1", + "@changesets/write": "^0.2.3", + "@manypkg/get-packages": "^1.1.3", + "@types/is-ci": "^3.0.0", + "@types/semver": "^7.5.0", + "ansi-colors": "^4.1.3", + "chalk": "^2.1.0", + "enquirer": "^2.3.0", + "external-editor": "^3.1.0", + "fs-extra": "^7.0.1", + "human-id": "^1.0.2", + "is-ci": "^3.0.1", + "meow": "^6.0.0", + "outdent": "^0.5.0", + "p-limit": "^2.2.0", + "preferred-pm": "^3.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^2.0.0", + "term-size": "^2.1.0", + "tty-table": "^4.1.5" + }, + "bin": { + "changeset": "bin.js" + } }, - "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 + "node_modules/@changesets/cli/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, + "engines": { + "node": ">=6" + } }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/@changesets/cli/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==", "dev": true, - "requires": { - "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" + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "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/@changesets/cli/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==", "dev": true, - "requires": { - "is-glob": "^4.0.1" + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "node_modules/@changesets/cli/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@changesets/cli/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "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 + "node_modules/@changesets/cli/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/@changesets/cli/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "engines": { + "node": ">=4" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "node_modules/@changesets/cli/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" + } }, - "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==", + "node_modules/@changesets/cli/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": { - "binary-extensions": "^2.0.0" + "engines": { + "node": ">=8" } }, - "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 + "node_modules/@changesets/cli/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, - "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 + "node_modules/@changesets/config": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-2.3.1.tgz", + "integrity": "sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.1.4", + "@changesets/get-dependents-graph": "^1.3.6", + "@changesets/logger": "^0.0.5", + "@changesets/types": "^5.2.1", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.2" + } }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/@changesets/errors": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.1.4.tgz", + "integrity": "sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==", "dev": true, - "requires": { - "is-extglob": "^2.1.1" + "dependencies": { + "extendable-error": "^0.1.5" } }, - "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 + "node_modules/@changesets/get-dependents-graph": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.6.tgz", + "integrity": "sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==", + "dev": true, + "dependencies": { + "@changesets/types": "^5.2.1", + "@manypkg/get-packages": "^1.1.3", + "chalk": "^2.1.0", + "fs-extra": "^7.0.1", + "semver": "^7.5.3" + } }, - "is-plain-obj": { - "version": "2.1.0", + "node_modules/@changesets/get-dependents-graph/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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/get-dependents-graph/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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/get-dependents-graph/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@changesets/get-dependents-graph/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@changesets/get-dependents-graph/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@changesets/get-dependents-graph/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/get-dependents-graph/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/get-release-plan": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.17.tgz", + "integrity": "sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@changesets/assemble-release-plan": "^5.2.4", + "@changesets/config": "^2.3.1", + "@changesets/pre": "^1.0.14", + "@changesets/read": "^0.5.9", + "@changesets/types": "^5.2.1", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.3.2.tgz", + "integrity": "sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==", + "dev": true + }, + "node_modules/@changesets/git": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-2.0.0.tgz", + "integrity": "sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@changesets/errors": "^0.1.4", + "@changesets/types": "^5.2.1", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.2", + "spawndamnit": "^2.0.0" + } + }, + "node_modules/@changesets/logger": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.0.5.tgz", + "integrity": "sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==", + "dev": true, + "dependencies": { + "chalk": "^2.1.0" + } + }, + "node_modules/@changesets/logger/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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/logger/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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/logger/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@changesets/logger/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@changesets/logger/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@changesets/logger/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/logger/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/parse": { + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.16.tgz", + "integrity": "sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==", + "dev": true, + "dependencies": { + "@changesets/types": "^5.2.1", + "js-yaml": "^3.13.1" + } + }, + "node_modules/@changesets/parse/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/@changesets/parse/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/@changesets/pre": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.14.tgz", + "integrity": "sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@changesets/errors": "^0.1.4", + "@changesets/types": "^5.2.1", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/read": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.5.9.tgz", + "integrity": "sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@changesets/git": "^2.0.0", + "@changesets/logger": "^0.0.5", + "@changesets/parse": "^0.3.16", + "@changesets/types": "^5.2.1", + "chalk": "^2.1.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0" + } + }, + "node_modules/@changesets/read/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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/read/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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/read/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@changesets/read/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@changesets/read/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@changesets/read/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/read/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@changesets/types": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-5.2.1.tgz", + "integrity": "sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==", + "dev": true + }, + "node_modules/@changesets/write": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.2.3.tgz", + "integrity": "sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.20.1", + "@changesets/types": "^5.2.1", + "fs-extra": "^7.0.1", + "human-id": "^1.0.2", + "prettier": "^2.7.1" + } + }, + "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": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "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": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "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": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + }, + "node_modules/@manypkg/find-root/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/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/find-root/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/@manypkg/find-root/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/@manypkg/find-root/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/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "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, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "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, + "engines": { + "node": ">= 8" + } + }, + "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, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/plugin-inject": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", + "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", + "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.5.tgz", + "integrity": "sha512-SU5cvamg0Eyu/F+kLeMXS7GoahL+OoizlclVFX3l5Ql6yNlywJJ0OuqTzUx0v+aHhPHEB/56CT06GQrRrGNYww==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.5.tgz", + "integrity": "sha512-S4pit5BP6E5R5C8S6tgU/drvgjtYW76FBuG6+ibG3tMvlD1h9LHVF9KmlmaUBQ8Obou7hEyS+0w+IR/VtxwNMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.5.tgz", + "integrity": "sha512-250ZGg4ipTL0TGvLlfACkIxS9+KLtIbn7BCZjsZj88zSg2Lvu3Xdw6dhAhfe/FjjXPVNCtcSp+WZjVsD3a/Zlw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.5.tgz", + "integrity": "sha512-D8brJEFg5D+QxFcW6jYANu+Rr9SlKtTenmsX5hOSzNYVrK5oLAEMTUgKWYJP+wdKyCdeSwnapLsn+OVRFycuQg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.5.tgz", + "integrity": "sha512-PNqXYmdNFyWNg0ma5LdY8wP+eQfdvyaBAojAXgO7/gs0Q/6TQJVXAXe8gwW9URjbS0YAammur0fynYGiWsKlXw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.5.tgz", + "integrity": "sha512-kSSCZOKz3HqlrEuwKd9TYv7vxPYD77vHSUvM2y0YaTGnFc8AdI5TTQRrM1yIp3tXCKrSL9A7JLoILjtad5t8pQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.5.tgz", + "integrity": "sha512-oTXQeJHRbOnwRnRffb6bmqmUugz0glXaPyspp4gbQOPVApdpRrY/j7KP3lr7M8kTfQTyrBUzFjj5EuHAhqH4/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.5.tgz", + "integrity": "sha512-qnOTIIs6tIGFKCHdhYitgC2XQ2X25InIbZFor5wh+mALH84qnFHvc+vmWUpyX97B0hNvwNUL4B+MB8vJvH65Fw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.5.tgz", + "integrity": "sha512-TMYu+DUdNlgBXING13rHSfUc3Ky5nLPbWs4bFnT+R6Vu3OvXkTkixvvBKk8uO4MT5Ab6lC3U7x8S8El2q5o56w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.5.tgz", + "integrity": "sha512-PTQq1Kz22ZRvuhr3uURH+U/Q/a0pbxJoICGSprNLAoBEkyD3Sh9qP5I0Asn0y0wejXQBbsVMRZRxlbGFD9OK4A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.5.tgz", + "integrity": "sha512-bR5nCojtpuMss6TDEmf/jnBnzlo+6n1UhgwqUvRoe4VIotC7FG1IKkyJbwsT7JDsF2jxR+NTnuOwiGv0hLyDoQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.5.tgz", + "integrity": "sha512-N0jPPhHjGShcB9/XXZQWuWBKZQnC1F36Ce3sDqWpujsGjDz/CQtOL9LgTrJ+rJC8MJeesMWrMWVLKKNR/tMOCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.5.tgz", + "integrity": "sha512-uBa2e28ohzNNwjr6Uxm4XyaA1M/8aTgfF2T7UIlElLaeXkgpmIJ2EitVNQxjO9xLLLy60YqAgKn/AqSpCUkE9g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.5.tgz", + "integrity": "sha512-RXT8S1HP8AFN/Kr3tg4fuYrNxZ/pZf1HemC5Tsddc6HzgGnJm0+Lh5rAHJkDuW3StI0ynNXukidROMXYl6ew8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.5.tgz", + "integrity": "sha512-ElTYOh50InL8kzyUD6XsnPit7jYCKrphmddKAe1/Ytt74apOxDq5YEcbsiKs0fR3vff3jEneMM+3I7jbqaMyBg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.5.tgz", + "integrity": "sha512-+lvL/4mQxSV8MukpkKyyvfwhH266COcWlXE/1qxwN08ajovta3459zrjLghYMgDerlzNwLAcFpvU+WWE5y6nAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-mnb1ngaGQPm6LFZaNdh3xPOoQMkrQb/KBPhPPN2p2Wk8XgeUqWj6xPnvyQ8rvcK/VFritVmQG8tvQuy7g+9/nQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.1.0" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.5", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz", + "integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/minimist": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.3.tgz", + "integrity": "sha512-ZYFzrvyWUNhaPomn80dsMNgMeXxNWZBdkuG/hWlUvXvbdUH8ZERNBGXnU87McuGcWDsyzX2aChCv/SVN348k3A==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.8.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", + "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", + "dev": true, + "dependencies": { + "undici-types": "~5.25.1" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz", + "integrity": "sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.28", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.28.tgz", + "integrity": "sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "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, + "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" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "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/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true + }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "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/breakword": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/breakword/-/breakword-1.0.6.tgz", + "integrity": "sha512-yjxDAYyK/pBvws9H4xKYpLDpYKEH6CzrBPAuXq3x18I+c/2MkVtT3qAr7Oloi6Dss9qNhPVueAAVU1CSeNDIXw==", + "dev": true, + "dependencies": { + "wcwidth": "^1.0.1" + } + }, + "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/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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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": "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/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/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/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.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" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "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/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "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/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "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/csv": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/csv/-/csv-5.5.3.tgz", + "integrity": "sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==", + "dev": true, + "dependencies": { + "csv-generate": "^3.4.3", + "csv-parse": "^4.16.3", + "csv-stringify": "^5.6.5", + "stream-transform": "^2.1.3" + }, + "engines": { + "node": ">= 0.1.90" + } + }, + "node_modules/csv-generate": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-3.4.3.tgz", + "integrity": "sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==", + "dev": true + }, + "node_modules/csv-parse": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz", + "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==", + "dev": true + }, + "node_modules/csv-stringify": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz", + "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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 + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", + "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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/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/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", + "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.51.0", + "@humanwhocodes/config-array": "^0.11.11", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "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.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "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" + } + }, + "node_modules/eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.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" + } + }, + "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.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "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/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" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "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/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "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-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/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/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": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "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, + "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-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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-yarn-workspace-root2": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", + "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", + "dev": true, + "dependencies": { + "micromatch": "^4.0.2", + "pkg-dir": "^4.2.0" + } + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": 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/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/human-id": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", + "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "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": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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" + } + }, + "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-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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": "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/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "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": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "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/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/load-yaml-file": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", + "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.13.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/load-yaml-file/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/load-yaml-file/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/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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/magic-string": { + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", + "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/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/meow/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/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/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.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixme": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/mixme/-/mixme-0.5.9.tgz", + "integrity": "sha512-VC5fg6ySUscaWUpI4gxCBTQMH2RdUpNrk+MsbpCYtIvf9SBJdiUey4qE7BXviJsJR4nDQxCZ+3yaYNW3guz/Pw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "dev": true, + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "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, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "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" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "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.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "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": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "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/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/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/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "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-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "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.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/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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" + }, + "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" + } + }, + "node_modules/preferred-pm": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.1.2.tgz", + "integrity": "sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0", + "find-yarn-workspace-root2": "1.2.16", + "path-exists": "^4.0.0", + "which-pm": "2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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.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" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "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/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/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/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/read-pkg-up/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/read-pkg-up/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/read-pkg-up/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/read-pkg-up/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/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/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/read-yaml-file/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/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "dev": true + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "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": { + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/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==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.5.tgz", + "integrity": "sha512-WoinX7GeQOFMGznEcWA1WrTQCd/tpEbMkc3nuMs9BT0CPjMdSjPMTVClwWd4pgSQwJdP65SK9mTCNvItlr5o7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.5", + "@rollup/rollup-android-arm64": "4.22.5", + "@rollup/rollup-darwin-arm64": "4.22.5", + "@rollup/rollup-darwin-x64": "4.22.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.5", + "@rollup/rollup-linux-arm-musleabihf": "4.22.5", + "@rollup/rollup-linux-arm64-gnu": "4.22.5", + "@rollup/rollup-linux-arm64-musl": "4.22.5", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.5", + "@rollup/rollup-linux-riscv64-gnu": "4.22.5", + "@rollup/rollup-linux-s390x-gnu": "4.22.5", + "@rollup/rollup-linux-x64-gnu": "4.22.5", + "@rollup/rollup-linux-x64-musl": "4.22.5", + "@rollup/rollup-win32-arm64-msvc": "4.22.5", + "@rollup/rollup-win32-ia32-msvc": "4.22.5", + "@rollup/rollup-win32-x64-msvc": "4.22.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-polyfill-node": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.13.0.tgz", + "integrity": "sha512-FYEvpCaD5jGtyBuBFcQImEGmTxDTPbiHjJdrYIp+mFIwgXiXabxvKUK7ZT9P31ozu2Tqm9llYQMRWsfvTMTAOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/plugin-inject": "^5.0.4" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "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-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "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/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "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": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "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==", + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", + "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": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", + "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/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true + }, + "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/smartwrap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/smartwrap/-/smartwrap-2.0.2.tgz", + "integrity": "sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==", + "dev": true, + "dependencies": { + "array.prototype.flat": "^1.2.3", + "breakword": "^1.0.5", + "grapheme-splitter": "^1.0.4", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1", + "yargs": "^15.1.0" + }, + "bin": { + "smartwrap": "src/terminal-adapter.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/smartwrap/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/smartwrap/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/smartwrap/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/smartwrap/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/smartwrap/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/smartwrap/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/smartwrap/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/smartwrap/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/smartwrap/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 }, - "isexe": { + "node_modules/smartwrap/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/smartwrap/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/spawndamnit": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-2.0.0.tgz", + "integrity": "sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==", + "dev": true, + "dependencies": { + "cross-spawn": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/spawndamnit/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/spawndamnit/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/spawndamnit/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawndamnit/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawndamnit/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/spawndamnit/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", "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==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", + "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stream-transform": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-2.1.3.tgz", + "integrity": "sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==", + "dev": true, + "dependencies": { + "mixme": "^0.5.1" + } + }, + "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==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "requires": { - "argparse": "^2.0.1" + "engines": { + "node": ">=4" } }, - "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==", + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "requires": { - "p-locate": "^5.0.0" + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "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==", + "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, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "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, - "requires": { - "brace-expansion": "^1.1.7" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "mocha": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", - "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "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.2.0", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "engines": { + "node": ">= 0.4" }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "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 - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" - }, - "nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", - "dev": true + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, - "requires": { - "wrappy": "1" + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" } }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "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": { - "yocto-queue": "^0.1.0" + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "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==", + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true, - "requires": { - "p-limit": "^3.0.2" + "engines": { + "node": ">=8" } }, - "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 - }, - "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=", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "node_modules/tty-table": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/tty-table/-/tty-table-4.2.2.tgz", + "integrity": "sha512-2gvCArMZLxgvpZ2NvQKdnYWIFLe7I/z5JClMuhrDXunmKgSZcQKcZRjN9XjAFiToMz2pUo1dEIXyrm0AwgV5Tw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "csv": "^5.5.3", + "kleur": "^4.1.5", + "smartwrap": "^2.0.2", + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.1", + "yargs": "^17.7.1" + }, + "bin": { + "tty-table": "adapters/terminal-adapter.js" + }, + "engines": { + "node": ">=8.0.0" + } }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/tty-table/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "requires": { - "safe-buffer": "^5.1.0" + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/tty-table/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "requires": { - "picomatch": "^2.2.1" + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, - "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 + "node_modules/tty-table/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "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==", - "dev": true + "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" + } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", "dev": true, - "requires": { - "randombytes": "^2.1.0" + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" } }, - "should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, - "requires": { - "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" + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, - "requires": { - "should-type": "^1.4.0" + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "requires": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } }, - "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==", + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "requires": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", "dev": true }, - "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==", + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "engines": { + "node": ">= 4.0.0" } }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "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": { - "ansi-regex": "^5.0.1" + "dependencies": { + "punycode": "^2.1.0" } }, - "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": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { - "has-flag": "^4.0.0" + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "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==", + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, - "requires": { - "is-number": "^7.0.0" + "dependencies": { + "defaults": "^1.0.3" } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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 + }, + "node_modules/which-pm": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz", + "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==", + "dev": true, + "dependencies": { + "load-yaml-file": "^0.2.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8.15" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, - "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" } }, - "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==", "dev": true }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "requires": { + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" } }, - "xmlbuilder": { + "node_modules/xmlbuilder": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } }, - "y18n": { + "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" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "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", @@ -720,31 +5702,46 @@ "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "yargs-parser": { + "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 + "dev": true, + "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" + }, + "engines": { + "node": ">=10" } }, - "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 + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 2ab6ed8..21350b0 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,48 @@ { "author": "Alejandro Alvarez Acero", "name": "node-rest-client", - "description": "node API REST client", + "description": "simple and lightweight node REST client", "version": "3.1.1", "repository": { "type": "git", "url": "https://github.com/aacerox/node-rest-client.git" }, - "main": "./lib/node-rest-client", + "main": "dist/cjs/NodeRestClient.js", + "module": "dist/mjs/NodeRestClient.js", + "types": "dist/mjs/NodeRestClient.d.ts", + "exports": { + ".": { + "import": "./dist/mjs/NodeRestClient.js", + "require": "./dist/cjs/NodeRestClient.js" + } + }, "dependencies": { - "xml2js": ">=0.4.23", "debug": "~4.3.3", - "follow-redirects": ">=1.14.7" + "follow-redirects": ">=1.14.8", + "xml2js": ">=0.4.23" }, "devDependencies": { - "mocha": "*", - "should": ">= 0.0.1" + "@changesets/cli": "^2.26.2", + "@types/jest": "^29.5.1", + "@types/node": "^20.2.3", + "eslint": "^8.39.0", + "eslint-config-google": "^0.14.0", + "mocha": "^10.2.0", + "rollup": "^4.22.5", + "rollup-plugin-polyfill-node": "^0.13.0", + "should": ">= 0.0.1", + "typescript": "^5.0.4" }, - "optionalDependencies": {}, "engines": { "node": "*" }, "scripts": { - "test": "mocha" + "build": "rm -fr dist/* && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && bash ./fixup", + "test": "npm run build && mocha --exit", + "rollup:mjs": "rollup -c", + "changeset": "changeset", + "publish:packages": "changeset publish", + "version:packages": "changeset version" }, "license": "MIT" } diff --git a/readme.md b/readme.md index be21c9f..f98123a 100644 --- a/readme.md +++ b/readme.md @@ -95,7 +95,7 @@ If no "Content-Type" header is set as client arg POST,PUT and PATCH methods will ### Passing args to registered methods -You can pass diferents args to registered methods, simplifying reuse: path replace parameters, query parameters, custom headers +You can pass different args to registered methods, simplifying reuse: path replace parameters, query parameters, custom headers ```javascript var Client = require('node-rest-client').Client; @@ -227,7 +227,7 @@ var args = { requestConfig: { timeout: 1000, //request timeout in milliseconds noDelay: true, //Enable/disable the Nagle algorithm - keepAlive: true, //Enable/disable keep-alive functionalityidle socket. + keepAlive: true, //Enable/disable keep-alive functionality idle socket. keepAliveDelay: 1000 //and optionally set the initial delay before the first keepalive probe is sent }, responseConfig: { @@ -470,7 +470,7 @@ client.parsers.find("XML").options= {"explicitArray":false, "ignoreAttrs":true}; ``` -- _**Default Parser**_: return responses as is, without any adittional processing. +- _**Default Parser**_: return responses as is, without any additional processing. #### Parser Management @@ -652,7 +652,7 @@ Client can manage serializers through the following serializers namespace method * `getDefault()`: return the default serializer used to process requests that doesn't match with any regular serializer. -* `clean()`: clean regular serializer registry. default serializer is not afected by this method. +* `clean()`: clean regular serializer registry. default serializer is not affected by this method. ```javascript @@ -781,7 +781,7 @@ var options = { requestConfig: { timeout: 1000, //request timeout in milliseconds noDelay: true, //Enable/disable the Nagle algorithm - keepAlive: true, //Enable/disable keep-alive functionalityidle socket. + keepAlive: true, //Enable/disable keep-alive functionality idle socket. keepAliveDelay: 1000 //and optionally set the initial delay before the first keepalive probe is sent }, responseConfig: { @@ -869,5 +869,4 @@ client.on('error', function (err) { }); ``` -**NOTE:** _Since version 0.8.0 node does not contain node-waf anymore. The node-zlib package which node-rest-client make use of, depends on node-waf.Fortunately since version 0.8.0 zlib is a core dependency of node, so since version 1.0 of node-rest-client the explicit dependency to "zlib" has been removed from package.json. therefore if you are using a version below 0.8.0 of node please use a versión below 1.0.0 of "node-rest-client". _ diff --git a/rollup.config.mjs b/rollup.config.mjs new file mode 100644 index 0000000..c6456c3 --- /dev/null +++ b/rollup.config.mjs @@ -0,0 +1,14 @@ +import nodePolyfills from 'rollup-plugin-polyfill-node'; + +export default { + input: './lib/NodeRestClient.js', + output: { + file: 'bundle.js', + format: 'iife', + }, + plugins: [ + nodePolyfills( /* options */ ), + ], +}; + + diff --git a/test.bat b/test.bat deleted file mode 100644 index 18de984..0000000 --- a/test.bat +++ /dev/null @@ -1 +0,0 @@ -npm test \ No newline at end of file diff --git a/test.sh b/test.sh deleted file mode 100644 index a593fa1..0000000 --- a/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -npm test \ No newline at end of file diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index e7ac864..0000000 --- a/test/mocha.opts +++ /dev/null @@ -1,4 +0,0 @@ ---require should ---reporter spec test/specs/*.js ---ui bdd ---recursive \ No newline at end of file diff --git a/test/resources/stream-file.txt b/test/resources/stream-file.txt new file mode 100644 index 0000000..22e50c7 --- /dev/null +++ b/test/resources/stream-file.txt @@ -0,0 +1,23 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris. +Nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor. +In reprehenderit in voluptate velit esse cillum dolore eu fugiat. +Nulla pariatur. Excepteur sint occaecat cupidatat non proident. +Sunt in culpa qui officia deserunt mollit anim id est laborum. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris. +Nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor. +In reprehenderit in voluptate velit esse cillum dolore eu fugiat. +Nulla pariatur. Excepteur sint occaecat cupidatat non proident. +Sunt in culpa qui officia deserunt mollit anim id est laborum. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris. +Nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor. +In reprehenderit in voluptate velit esse cillum dolore eu fugiat. +Nulla pariatur. Excepteur sint occaecat cupidatat non proident. +Sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/test/server/mock-server.js b/test/server/mock-server.js deleted file mode 100644 index a56e98e..0000000 --- a/test/server/mock-server.js +++ /dev/null @@ -1,210 +0,0 @@ -var http = require('http'), fs = require('fs'); - -var RouterOptions = { - "baseMessageDir" : "", - "JSONMessageFile" : './test/server/message.json', - "XMLMessageFile" : './test/server/message.xml' - -}; - -var RouteManager = { - "findRoute" : function(req, res) { - var handler = null; - for ( var route in this.routes) { - if (req.url.startsWith(route)) { - handler = this.routes[route]; - } - - } - if (!handler) - throw "cannot find route " + req.url; - handler.call(this, req, res); - }, - "routes" : { - "/json" : function(req, res) { - // this.sleep(5000); - var message = fs - .readFileSync(RouterOptions.JSONMessageFile, 'utf8'); - res.writeHead(200, { - 'Content-Type' : 'application/json', - 'test-header' : 'test' - }); - res.write(message.toString()); - res.end(); - }, - "/json/path" : function(req, res) { - // this.sleep(5000); - var message = { - "url" : req.url - }; - res.writeHead(200, { - 'Content-Type' : 'application/json', - 'test-header' : req.url - }); - res.write(JSON.stringify(message)); - res.end(); - }, - "/xml" : function(req, res) { - var message = fs.readFileSync(RouterOptions.XMLMessageFile, 'utf8'); - res.writeHead(200, { - 'Content-Type' : 'application/xml' - }); - res.write(message.toString()); - res.end(); - }, - "/120/json?arg1=hello&arg2=world" : function(req, res) { - if (!req.headers["test-header"]) - throw "no test-header found!!"; - res.setHeader("test-response-header", req.headers["test-header"]); - this.routes["/json"](req, res); - }, - "/json?post" : function(req, res) { - req.on('data', function(data) { - // console.log("[SERVER] data = ", data); - res.writeHead(200, { - 'Content-Type' : 'application/json' - }); - // res.writeHead(200, {'Content-Type': 'text/plain'}); - res.write(data.toString()); - res.end(); - }); - - }, - "/json/path/post" : function(req, res) { - req.on('data', function(data) { - var message = { - "url" : req.url - }; - // console.log("[SERVER] data = ", data); - res.writeHead(200, { - 'Content-Type' : 'application/json' - }); - // res.writeHead(200, {'Content-Type': 'text/plain'}); - message.postData = data.toString(); - res.write(JSON.stringify(message)); - res.end(); - }); - - }, - "/json/error" : function(req, res) { - // this.sleep(5000); - - - res.writeHead(500, {'Content-Type': 'text/plain'}); - res.end(); - - - }, - "/xml/path/post" : function(req, res) { - req.on('data', function(data) { - // console.log("[SERVER] data = ", data); - res.writeHead(200, { - 'Content-Type' : 'application/xml' - }); - // res.writeHead(200, {'Content-Type': 'text/plain'}); - res.write(data.toString()); - res.end(); - }); - - }, - "/json/empty" : function(req, res) { - res.writeHead(200, { - 'Content-Type' : 'application/json' - }); - res.end(); - }, - "/xml/empty" : function(req, res) { - res.writeHead(204, { - 'Content-Type' : 'application/xml' - }); - res.end(); - }, - "/json/contenttypewithspace" : function(req, res) { - var message = fs.readFileSync('./message.json', 'utf8'); - res.writeHead(200, { - 'Content-Type' : 'application/json; charset=utf-8' - }); - res.write(message.toString()); - res.end(); - }, - "/json/test/content/type" : function(req, res) { - var message = fs.readFileSync(RouterOptions.JSONMessageFile, 'utf8'); - res.writeHead(200, { - 'Content-Type' : 'test/json' - }); - res.write(message.toString()); - res.end(); - }, - "/xml/test/content/type" : function(req, res) { - var message = fs.readFileSync(RouterOptions.XMLMessageFile, 'utf8'); - res.writeHead(200, { - 'Content-Type' : 'test/xml' - }); - res.write(message.toString()); - res.end(); - }, - "/followRedirects":function(req, res){ - - var repeatOffset = req.url.indexOf("?"), - repeat = parseInt(req.url.substring(repeatOffset + 1),10), - location = ""; - - if (repeatOffset === 0){ - res.writeHead(301, { - 'Location':'http://localhost:4444/redirected' - }); - }else{ - if (repeat > 0){ - res.writeHead(301, { - 'Location':'http://localhost:4444/followRedirects?' + --repeat - }); - }else{ - res.writeHead(301, { - 'Location':'http://localhost:4444/redirected' - }); - } - - } - res.end(); - }, - "/redirected":function(req, res){ - var message={"redirected":++this.redirectCount}; - res.writeHead(200, { - 'Content-Type' : 'application/json; charset=utf-8' - }); - res.write(JSON.stringify(message)); - res.end(); - } - - }, - "sleep" : function(ms) { - - var stop = new Date().getTime(); - while (new Date().getTime() < stop + ms) { - ; - } - }, - "redirectCount":0, - "redirectLimit":10 - -}; - -// Create an HTTP server -this.server = http.createServer(function(req, res) { - // console.log("[SERVER] req.url", req.url); - RouteManager.findRoute(req, res); -}); - -exports.baseURL = "http://localhost:4444"; - -exports.listen = function() { - this.server.listen.apply(this.server, arguments); -}; - -exports.close = function(callback) { - this.server.close(callback); -}; - -exports.on = function(event, cb) { - this.server.on.apply(this.server, event, cb); -}; diff --git a/test/server/mock-server.mjs b/test/server/mock-server.mjs new file mode 100644 index 0000000..8c91217 --- /dev/null +++ b/test/server/mock-server.mjs @@ -0,0 +1,208 @@ +import http from 'http'; +import fs from 'fs'; + +const RouterOptions = { + 'baseMessageDir': '', + 'JSONMessageFile': './test/server/message.json', + 'XMLMessageFile': './test/server/message.xml', + +}; + +const RouteManager = { + 'findRoute': function(req, res) { + let handler = null; + for ( const route in this.routes) { + if (req.url.startsWith(route)) { + handler = this.routes[route]; + } + } + if (!handler) { + throw new Error('cannot find route ' + req.url); + }; + handler.call(this, req, res); + }, + 'routes': { + '/json': function(req, res) { + const message = fs + .readFileSync(RouterOptions.JSONMessageFile, 'utf8'); + res.writeHead(200, { + 'Content-Type': 'application/json', + 'test-header': 'test', + }); + res.write(message.toString()); + res.end(); + }, + '/json/path': function(req, res) { + const message = { + 'url': req.url, + }; + res.writeHead(200, { + 'Content-Type': 'application/json', + 'test-header': req.url, + }); + res.write(JSON.stringify(message)); + res.end(); + }, + '/xml': function(req, res) { + const message = fs.readFileSync(RouterOptions.XMLMessageFile, 'utf8'); + res.writeHead(200, { + 'Content-Type': 'application/xml', + }); + res.write(message.toString()); + res.end(); + }, + '/120/json?arg1=hello&arg2=world': function(req, res) { + if (!req.headers['test-header']) { + throw new Error('no test-header found!!'); + }; + res.setHeader('test-response-header', req.headers['test-header']); + this.routes['/json'](req, res); + }, + '/json?post': function(req, res) { + req.on('data', function(data) { + res.writeHead(200, { + 'Content-Type': 'application/json', + }); + res.write(data.toString()); + res.end(); + }); + }, + '/json/path/post': function(req, res) { + req.on('data', function(data) { + const message = { + 'url': req.url, + }; + + res.writeHead(200, { + 'Content-Type': 'application/json', + }); + + message.postData = data.toString(); + res.write(JSON.stringify(message)); + res.end(); + }); + }, + '/json/error': function(req, res) { + res.writeHead(500, {'Content-Type': 'text/plain'}); + res.end(); + }, + '/xml/path/post': function(req, res) { + req.on('data', function(data) { + res.writeHead(200, { + 'Content-Type': 'application/xml', + }); + res.write(data.toString()); + res.end(); + }); + }, + '/json/empty': function(req, res) { + res.writeHead(200, { + 'Content-Type': 'application/json', + }); + res.end(); + }, + '/xml/empty': function(req, res) { + res.writeHead(204, { + 'Content-Type': 'application/xml', + }); + res.end(); + }, + '/json/contenttypewithspace': function(req, res) { + const message = fs.readFileSync('./message.json', 'utf8'); + res.writeHead(200, { + 'Content-Type': 'application/json charset=utf-8', + }); + res.write(message.toString()); + res.end(); + }, + '/json/test/content/type': function(req, res) { + const message = fs.readFileSync(RouterOptions.JSONMessageFile, 'utf8'); + res.writeHead(200, { + 'Content-Type': 'test/json', + }); + res.write(message.toString()); + res.end(); + }, + '/xml/test/content/type': function(req, res) { + const message = fs.readFileSync(RouterOptions.XMLMessageFile, 'utf8'); + res.writeHead(200, { + 'Content-Type': 'test/xml', + }); + res.write(message.toString()); + res.end(); + }, + '/followRedirects': function(req, res) { + const repeatOffset = req.url.indexOf('?'); + let repeat = parseInt(req.url.substring(repeatOffset + 1), 10); + + + if (repeatOffset === 0) { + res.writeHead(301, { + 'Location': 'http://localhost:4444/redirected', + }); + } else { + if (repeat > 0) { + res.writeHead(301, { + 'Location': 'http://localhost:4444/followRedirects?' + --repeat, + }); + } else { + res.writeHead(301, { + 'Location': 'http://localhost:4444/redirected', + }); + } + } + res.end(); + }, + '/redirected': function(req, res) { + const message={'redirected': ++this.redirectCount}; + res.writeHead(200, { + 'Content-Type': 'application/json charset=utf-8', + }); + res.write(JSON.stringify(message)); + res.end(); + }, + '/stream': function(req, res) { + let requestBody = ''; + + req.on('data', (chunk) => requestBody +=chunk); + + req.on('end', function(data) { + res.writeHead(200, { + 'Content-Type': 'text/plain', + }); + res.write(requestBody); + res.end(); + }); + }, + + }, + 'sleep': function(ms) { + const stop = new Date().getTime(); + while (new Date().getTime() < stop + ms) { + // noop + } + }, + 'redirectCount': 0, + 'redirectLimit': 10, + +}; + +// Create an HTTP server +const server = http.createServer(function(req, res) { + RouteManager.findRoute(req, res); +}); + +const mockServer = { + baseURL: 'http://localhost:4444', + listen: function(...args) { + server.listen(...args); + }, + close: function(callback) { + server.close(callback); + }, + on: function(event, cb) { + server.on.apply(server, event, cb); + }, +}; + +export default mockServer; diff --git a/test/specs/TestErrorHandlers.js b/test/specs/TestErrorHandlers.js deleted file mode 100644 index 1606dfe..0000000 --- a/test/specs/TestErrorHandlers.js +++ /dev/null @@ -1,54 +0,0 @@ -var server =require("../server/mock-server"), -Client=require("../../lib/node-rest-client").Client; - -describe('Error Handlers', function () { - - this.timeout(150000); - - before(function () { - server.listen(4444); - console.log("server started on port 4444"); - }); - - describe("Client Error Hanlers",function(){ - - - it("handle error with client handler", function(done){ - var client = new Client(); - client.on('error', function(err){ - done(); - }); - client.get(server.baseURL + "/json/error", function(data, response){ - client.emit('error', response.status); - }); - - }); - - - - - }); - -describe("#Request Error Handlers",function(){ - - it("handle error with request handler", function(done){ - var client = new Client(); - - var req =client.get(server.baseURL + "/json/error", function(data, response){ - req.emit('error', response.status); - }); - - req.on('error',function(err){ - done(); - }) - - }); - -}); - -after(function () { - server.close(); - console.log("server stopped"); -}); - -}); \ No newline at end of file diff --git a/test/specs/TestErrorHandlers.mjs b/test/specs/TestErrorHandlers.mjs new file mode 100644 index 0000000..5ecd9f8 --- /dev/null +++ b/test/specs/TestErrorHandlers.mjs @@ -0,0 +1,45 @@ +import server from '../server/mock-server.mjs'; +import Client from '../../dist/mjs/NodeRestClient.js'; + + +describe('Error Handlers', function() { + // eslint-disable-next-line no-invalid-this + this.timeout(150000); + + before(function() { + server.listen(4444); + console.log('server started on port 4444'); + }); + + describe('Client Error Handlers', function() { + it('handle error with client handler', function(done) { + const client = new Client(); + client.on('error', function(err) { + done(); + }); + client.get(server.baseURL + '/json/error', function(data, response) { + client.emit('error', response.status); + }); + }); + }); + + describe('#Request Error Handlers', function() { + it('handle error with request handler', function(done) { + const client = new Client(); + + const req =client.get(server.baseURL + '/json/error', + function(data, response) { + req.emit('error', response.status); + }); + + req.on('error', function(err) { + done(); + }); + }); + }); + + after(function() { + server.close(); + console.log('server stopped'); + }); +}); diff --git a/test/specs/TestFollowsRedirect.js b/test/specs/TestFollowsRedirect.js deleted file mode 100644 index 2e16bff..0000000 --- a/test/specs/TestFollowsRedirect.js +++ /dev/null @@ -1,70 +0,0 @@ -var server =require("../server/mock-server"), -Client=require("../../lib/node-rest-client").Client; - -describe('Follows Redirects', function () { - - this.timeout(150000); - - before(function () { - server.listen(4444); - console.log("server started on port 4444"); - }); - - - describe("#Follows Redirects",function(){ - - it("follows Redirect", function(done){ - var client = new Client(); - - client.post(server.baseURL + "/followRedirects", function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - data.redirected.should.equal(1); - done(); - }); - - }); - - it("disable follows Redirect", function(done){ - var client = new Client(); - var args ={ - requestConfig:{followRedirects:false} - }; - - client.post(server.baseURL + "/followRedirects",args, function(data, response){ - response.statusCode.should.be.equal(301); - done(); - }); - - }); - - - - it("set max redirects", function(done){ - var client = new Client(); - var args ={ - requestConfig:{maxRedirects:3} - }; - - - - var req = client.post(server.baseURL + "/followRedirects?5",args, function(data, response){ - response.statusCode.should.be.equal(301); - - }); - - req.on('error', function(err){ - err.message.should.be.equal("Max redirects exceeded.") - done(); - }); - - }); - }); - - - -after(function () { - server.close(); - console.log("server stopped"); -}); -}); \ No newline at end of file diff --git a/test/specs/TestFollowsRedirect.mjs b/test/specs/TestFollowsRedirect.mjs new file mode 100644 index 0000000..82f5d29 --- /dev/null +++ b/test/specs/TestFollowsRedirect.mjs @@ -0,0 +1,69 @@ +import server from '../server/mock-server.mjs'; +import Client from '../../dist/mjs/NodeRestClient.js'; + +describe('Follows Redirects', function() { + // eslint-disable-next-line no-invalid-this + this.timeout(150000); + + before(function() { + server.listen(4444); + console.log('server started on port 4444'); + }); + + describe('#Follows Redirects', function() { + it('follows Redirect', function(done) { + const client = new Client(); + + client.post( + server.baseURL + '/followRedirects', + function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.redirected.should.equal(1); + done(); + }, + ); + }); + + it('disable follows Redirect', function(done) { + const client = new Client(); + const args = { + requestConfig: {followRedirects: false}, + }; + + client.post( + server.baseURL + '/followRedirects', + args, + function(data, response) { + response.statusCode.should.be.equal(301); + done(); + }, + ); + }); + + it('set max redirects', function(done) { + const client = new Client(); + const args = { + requestConfig: {maxRedirects: 3}, + }; + + const req = client.post( + server.baseURL + '/followRedirects?5', + args, + function(data, response) { + response.statusCode.should.be.equal(301); + }, + ); + + req.on('error', function(err) { + err.message.should.be.equal('Maximum number of redirects exceeded'); + done(); + }); + }); + }); + + after(function() { + server.close(); + console.log('server stopped'); + }); +}); diff --git a/test/specs/TestGETMethod.js b/test/specs/TestGETMethod.js deleted file mode 100644 index e6a1fd4..0000000 --- a/test/specs/TestGETMethod.js +++ /dev/null @@ -1,232 +0,0 @@ -var server =require("../server/mock-server"), -Client=require("../../lib/node-rest-client").Client; - -describe('GET Method', function () { - - this.timeout(150000); - - before(function () { - server.listen(4444); - console.log("server started on port 4444"); - }); - - describe("#JSON",function(){ - - it("GET request with no args", function(done){ - var client = new Client(); - client.get(server.baseURL + "/json", function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - done(); - }); - }); - - it("GET request with path variable substitution", function(done){ - var client = new Client(); - var args ={ - path:{testNumber:123, testString:"test"} - }; - client.get(server.baseURL + "/json/path/${testNumber}/${testString}",args, function(data, response){ - - data.should.not.equal(null); - data.should.type("object"); - data.url.should.equal("/json/path/123/test"); - done(); - }); - }); - - - it("GET request with parameters", function(done){ - var client = new Client(); - var args ={ - parameters:{testNumber:123, testString:"test"} - }; - client.get(server.baseURL + "/json/path/query",args, function(data, response){ - - data.should.not.equal(null); - data.should.type("object"); - data.url.should.equal("/json/path/query?testNumber=123&testString=test"); - done(); - }); - }); - - it("GET request with registered method and no args", function(done){ - var client = new Client(); - - - client.registerMethod("testMethod",server.baseURL + "/json","GET"); - - client.methods.testMethod( function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - done(); - }); - }); - - - - it("GET request with registered method and path variable substitution", function(done){ - var client = new Client(); - var args ={ - path:{testNumber:123, testString:"test"} - }; - - client.registerMethod("testMethod",server.baseURL + "/json/path/${testNumber}/${testString}","GET"); - - client.methods.testMethod(args, function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - data.url.should.equal("/json/path/123/test"); - done(); - }); - }); - - - it("GET request with registered method and parameters", function(done){ - var client = new Client(); - var args ={ - parameters:{testNumber:123, testString:"test"} - }; - - client.registerMethod("testMethod",server.baseURL + "/json/path/query","GET"); - - client.methods.testMethod(args, function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - data.url.should.equal("/json/path/query?testNumber=123&testString=test"); - - done(); - }); - }); - - it("GET request with incompatible parameters URL", function(done){ - var client = new Client(); - var args ={ - parameters:{testNumber:123, testString:"test"} - }; - - client.on('error', function(err){ - err.should.startWith("parameters argument cannot be used if parameters are already defined in URL"); - done(); - }); - - client.get(server.baseURL + "/json/path/query?testNumber=123&testString=test", args, function(data, response){ - //noop - }).should.throw(); - - }); - - it("GET request with invalid args type", function(done){ - var client = new Client(); - var args = "123"; - - client.on('error', function(err){ - err.should.startWith("args should be and object"); - done(); - }); - - - - client.get(server.baseURL + "/json/path/query",args, function(data, response){ - //noop - }).should.throw(); - - }); - - - it("GET request with invalid parameters type", function(done){ - var client = new Client(); - var args ={ - parameters:"{test='123'}" - }; - - client.on('error', function(err){ - err.should.startWith("cannot serialize"); - done(); - }); - - - - client.get(server.baseURL + "/json/path/query",args, function(data, response){ - //noop - }).should.throw(); - - }); - - it("GET request with registered method and incompatible parameters URL", function(done){ - var client = new Client(); - var args ={ - parameters:{testNumber:123, testString:"test"} - }; - - client.on('error', function(err){ - err.should.startWith("parameters argument cannot be used if parameters are already defined in URL"); - done(); - }); - - client.registerMethod("testMethod",server.baseURL + "/json/path/query?testNumber=123&testString=test","GET"); - - client.methods.testMethod(args, function(data, response){ - //noop - }).should.throw(); - - }); - - it("GET request with registered method and invalid args type", function(done){ - var client = new Client(); - var args ="123"; - - client.on('error', function(err){ - err.should.startWith("args should be and object"); - done(); - }); - - client.registerMethod("testMethod",server.baseURL + "/json/path/query","GET"); - - client.methods.testMethod(args, function(data, response){ - //noop - }).should.throw(); - - }); - - - it("GET request with registered method and invalid parameters type", function(done){ - var client = new Client(); - var args ={ - parameters:"{test='123'}" - }; - - client.on('error', function(err){ - err.should.startWith("cannot serialize"); - done(); - }); - - client.registerMethod("testMethod",server.baseURL + "/json/path/query","GET"); - - client.methods.testMethod(args, function(data, response){ - //noop - }).should.throw(); - - }); - }); - - -describe("#XML",function(){ - - it("GET request with no args", function(done){ - var client = new Client(); - client.get(server.baseURL + "/xml", function(data, response){ - console.log("data es ", data); - data.should.not.equal(null); - data.should.type("object"); - done(); - }); - }); - -}); - -after(function () { - server.close(); - console.log("server stopped"); -}); -}); \ No newline at end of file diff --git a/test/specs/TestGETMethod.mjs b/test/specs/TestGETMethod.mjs new file mode 100644 index 0000000..d07b2dc --- /dev/null +++ b/test/specs/TestGETMethod.mjs @@ -0,0 +1,221 @@ +/* eslint-disable max-len */ +import server from '../server/mock-server.mjs'; +import Client from '../../dist/mjs/NodeRestClient.js'; + +describe('GET Method', function() { + // eslint-disable-next-line no-invalid-this + this.timeout(150000); + + before(function() { + server.listen(4444); + console.log('server started on port 4444'); + }); + + describe('#JSON', function() { + it('GET request with no args', function(done) { + const client = new Client(); + client.get(server.baseURL + '/json', function(data, response) { + response.should.not.equal(null); + data.should.not.equal(null); + data.should.type('object'); + done(); + }); + }); + + it('GET request with path variable substitution', function(done) { + const client = new Client(); + const args ={ + path: {testNumber: 123, testString: 'test'}, + }; + client.get(server.baseURL + '/json/path/${testNumber}/${testString}', args, function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.url.should.equal('/json/path/123/test'); + done(); + }); + }); + + + it('GET request with parameters', function(done) { + const client = new Client(); + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + }; + client.get(server.baseURL + '/json/path/query', args, function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.url.should.equal('/json/path/query?testNumber=123&testString=test'); + done(); + }); + }); + + it('GET request with registered method and no args', function(done) { + const client = new Client(); + + + client.registerMethod('testMethod', server.baseURL + '/json', 'GET'); + + client.methods.testMethod( function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + done(); + }); + }); + + + it('GET request with registered method and path variable substitution', function(done) { + const client = new Client(); + const args ={ + path: {testNumber: 123, testString: 'test'}, + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/${testNumber}/${testString}', 'GET'); + + client.methods.testMethod(args, function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.url.should.equal('/json/path/123/test'); + done(); + }); + }); + + + it('GET request with registered method and parameters', function(done) { + const client = new Client(); + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/query', 'GET'); + + client.methods.testMethod(args, function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.url.should.equal('/json/path/query?testNumber=123&testString=test'); + + done(); + }); + }); + + it('GET request with incompatible parameters URL', function(done) { + const client = new Client(); + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + }; + + client.on('error', function(err) { + err.should.startWith('parameters argument cannot be used if parameters are already defined in URL'); + done(); + }); + + client.get(server.baseURL + '/json/path/query?testNumber=123&testString=test', args, function(data, response) { + // noop + }).should.throw(); + }); + + it('GET request with invalid args type', function(done) { + const client = new Client(); + const args = '123'; + + client.on('error', function(err) { + err.should.startWith('args should be and object'); + done(); + }); + + + client.get(server.baseURL + '/json/path/query', args, function(data, response) { + // noop + }).should.throw(); + }); + + + it('GET request with invalid parameters type', function(done) { + const client = new Client(); + const args ={ + parameters: '{test=\'123\'}', + }; + + client.on('error', function(err) { + err.should.startWith('cannot serialize'); + done(); + }); + + + client.get(server.baseURL + '/json/path/query', + args, function(data, response) { + // noop + }).should.throw(); + }); + + it('GET request with registered method and incompatible parameters URL', function(done) { + const client = new Client(); + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + }; + + client.on('error', function(err) { + err.should.startWith('parameters argument cannot be used if parameters are already defined in URL'); + done(); + }); + + client.registerMethod('testMethod', server.baseURL + '/json/path/query?testNumber=123&testString=test', 'GET'); + + client.methods.testMethod(args, function(data, response) { + // noop + }).should.throw(); + }); + + it('GET request with registered method and invalid args type', function(done) { + const client = new Client(); + const args ='123'; + + client.on('error', function(err) { + err.should.startWith('args should be and object'); + done(); + }); + + client.registerMethod('testMethod', server.baseURL + '/json/path/query', 'GET'); + + client.methods.testMethod(args, function(data, response) { + // noop + }).should.throw(); + }); + + + it('GET request with registered method and invalid parameters type', function(done) { + const client = new Client(); + const args ={ + parameters: '{test=\'123\'}', + }; + + client.on('error', function(err) { + err.should.startWith('cannot serialize'); + done(); + }); + + client.registerMethod('testMethod', server.baseURL + '/json/path/query', 'GET'); + + client.methods.testMethod(args, function(data, response) { + // noop + }).should.throw(); + }); + }); + + + describe('#XML', function() { + it('GET request with no args', function(done) { + const client = new Client(); + client.get(server.baseURL + '/xml', function(data, response) { + console.log('data es ', data); + data.should.not.equal(null); + data.should.type('object'); + done(); + }); + }); + }); + + after(function() { + server.close(); + console.log('server stopped'); + }); +}); diff --git a/test/specs/TestGETMethodPromised.mjs b/test/specs/TestGETMethodPromised.mjs new file mode 100644 index 0000000..be77eac --- /dev/null +++ b/test/specs/TestGETMethodPromised.mjs @@ -0,0 +1,219 @@ +/* eslint-disable max-len */ +import server from '../server/mock-server.mjs'; +import Client from '../../dist/mjs/NodeRestClient.js'; + +let client; + +describe('GET Promise Method', function() { + // eslint-disable-next-line no-invalid-this + this.timeout(150000); + + const assertPromiseResult = (result) => { + result.should.not.equal(null); + result.response.should.not.equal(null); + result.data.should.not.equal(null); + result.data.should.type('object'); + }; + + before(function() { + client = new Client({usePromises: true}); + server.listen(4444); + console.log('server started on port 4444'); + }); + + describe('#JSON Promise', () => { + it('GET Promise request with no args', () => { + return client.get(server.baseURL + '/json').then((result) => { + assertPromiseResult(result); + }); + }); + + it('GET Promise request with path variable substitution', () => { + const args ={ + path: {testNumber: 123, testString: 'test'}, + }; + return client.get(server.baseURL + '/json/path/${testNumber}/${testString}', args).then((result) => { + assertPromiseResult(result); + + result.data.url.should.equal('/json/path/123/test'); + }); + }); + + + it('GET Promise request with parameters', () => { + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + }; + return client + .get(server.baseURL + '/json/path/query', args) + .then((result) => { + assertPromiseResult(result); + + result.data.url.should.equal( + '/json/path/query?testNumber=123&testString=test', + ); + }); + }); + + it('GET Promise request with registered method and no args', () => { + client.registerMethod('testMethod', server.baseURL + '/json', 'GET'); + + return client.methods.testMethod().then((result) => { + assertPromiseResult(result); + }); + }); + + + it('GET Promise request with registered method and path variable substitution', () => { + const args ={ + path: {testNumber: 123, testString: 'test'}, + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/${testNumber}/${testString}', 'GET'); + + return client.methods.testMethod(args).then((result) => { + assertPromiseResult(result); + + result.data.url.should.equal('/json/path/123/test'); + }); + }); + + + it('GET Promise request with registered method and parameters', () => { + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/query', 'GET'); + + return client.methods.testMethod(args).then((result) => { + assertPromiseResult(result); + + result.data.url.should.equal( + '/json/path/query?testNumber=123&testString=test', + ); + }); + }); + + it('GET Promise request with incompatible parameters URL', () => { + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + }; + + client + .get( + server.baseURL + '/json/path/query?testNumber=123&testString=test', + args, + ) + .then((result) => { + // noop + }) + .catch((err)=> { + err.should.startWith( + 'parameters argument cannot be used if parameters are already defined in URL', + ); + }); + }); + + it('GET Promise request with invalid args type', () => { + const args = '123'; + + + client + .get(server.baseURL + '/json/path/query', args) + .then((result) => { + // noop + }) + .catch((err) => { + err.should.startWith('args should be and object'); + }); + }); + + + it('GET Promise request with invalid parameters type', () => { + const args ={ + parameters: '{test=\'123\'}', + }; + + client.on('error', function(err) { + err.should.startWith('cannot serialize'); + }); + + + client.get(server.baseURL + '/json/path/query', + args) + .then((result) => { + // noop + }) + .catch((err) => { + err.should.startWith('cannot serialize'); + }); + }); + + it('GET Promise request with registered method and incompatible parameters URL', () => { + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/query?testNumber=123&testString=test', 'GET'); + + client.methods.testMethod(args) + .then((result) => { + // noop + }) + .catch((err) => { + err.should.startWith( + 'parameters argument cannot be used if parameters are already defined in URL', + ); + }); + }); + + it('GET Promise request with registered method and invalid args type', () => { + const args ='123'; + + client.registerMethod('testMethod', server.baseURL + '/json/path/query', 'GET'); + + client.methods + .testMethod(args) + .then((result) => { + // noop + }) + .catch((err) => { + err.should.startWith('args should be and object'); + }); + }); + + + it('GET Promise request with registered method and invalid parameters type', () => { + const args ={ + parameters: '{test=\'123\'}', + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/query', 'GET'); + + client.methods + .testMethod(args) + .then((result) => { + // noop + }) + .catch((err) => { + err.should.startWith('cannot serialize'); + }); + }); + }); + + + describe('#XML', function() { + it('GET Promise request with no args', function() { + return client.get(server.baseURL + '/xml').then((result) => { + console.log('data es ', result.data); + assertPromiseResult(result); + }); + }); + }); + + after(function() { + server.close(); + console.log('server stopped'); + }); +}); diff --git a/test/specs/TestPOSTMethod.js b/test/specs/TestPOSTMethod.js deleted file mode 100644 index 9268840..0000000 --- a/test/specs/TestPOSTMethod.js +++ /dev/null @@ -1,241 +0,0 @@ -var server =require("../server/mock-server"), -Client=require("../../lib/node-rest-client").Client; - -describe('POST Method', function () { - - this.timeout(150000); - - before(function () { - server.listen(4444); - console.log("server started on port 4444"); - }); - - describe("#JSON",function(){ - - it("POST request with path variable substitution", function(done){ - var client = new Client(); - var args ={ - path:{testNumber:123, testString:"test"}, - data:'{"dataNumber":123, "dataString":"test"}' - - }; - client.post(server.baseURL + "/json/path/post/${testNumber}/${testString}",args, function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - data.url.should.equal("/json/path/post/123/test"); - data.postData.should.equal('{"dataNumber":123, "dataString":"test"}'); - done(); - }); - }); - - - it("POST request with parameters", function(done){ - var client = new Client(); - var args ={ - parameters:{testNumber:123, testString:"test"}, - data:'{"dataNumber":123,"dataString":"test"}' - }; - client.post(server.baseURL + "/json/path/post/query",args, function(data, response){ - - data.should.not.equal(null); - data.should.type("object"); - data.url.should.equal("/json/path/post/query?testNumber=123&testString=test"); - data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); - done(); - }); - }); - - it("POST request with registered method and no args", function(done){ - var client = new Client(); - - - client.registerMethod("testMethod",server.baseURL + "/json","POST"); - - client.methods.testMethod( function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - done(); - }); - }); - - - - it("POST request with registered method and path variable substitution", function(done){ - var client = new Client(); - var args ={ - path:{testNumber:123, testString:"test"}, - data:'{"dataNumber":123,"dataString":"test"}' - }; - - client.registerMethod("testMethod",server.baseURL + "/json/path/post/${testNumber}/${testString}","POST"); - - client.methods.testMethod(args, function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - data.url.should.equal("/json/path/post/123/test"); - data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); - done(); - }); - }); - - - it("POST request with registered method and parameters", function(done){ - var client = new Client(); - var args ={ - parameters:{testNumber:123, testString:"test"}, - data:'{"dataNumber":123,"dataString":"test"}' - }; - - client.registerMethod("testMethod",server.baseURL + "/json/path/post/query","POST"); - - client.methods.testMethod(args, function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - data.url.should.equal("/json/path/post/query?testNumber=123&testString=test"); - data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); - done(); - }); - }); - - it("POST request with incompatible parameters URL", function(done){ - var client = new Client(); - var args ={ - parameters:{testNumber:123, testString:"test"}, - data:{dataNumber:123, dataString:"test"} - }; - - client.on('error', function(err){ - err.should.startWith("parameters argument cannot be used if parameters are already defined in URL"); - done(); - }); - - client.post(server.baseURL + "/json/path/post/query?testNumber=123&testString=test", args, function(data, response){ - // noop - }).should.throw(); - - }); - - it("POST request with invalid args type", function(done){ - var client = new Client(); - var args = "123"; - - client.on('error', function(err){ - err.should.startWith("args should be and object"); - done(); - }); - - - - client.post(server.baseURL + "/json/path/post/query",args, function(data, response){ - // noop - }).should.throw(); - - }); - - - it("POST request with invalid parameters type", function(done){ - var client = new Client(); - var args ={ - parameters:"{test='123'}" - }; - - client.on('error', function(err){ - err.should.startWith("cannot serialize"); - done(); - }); - - - - client.post(server.baseURL + "/json/path/post/query",args, function(data, response){ - // noop - }).should.throw(); - - }); - - it("POST request with registered method and incompatible parameters URL", function(done){ - var client = new Client(); - var args ={ - parameters:{testNumber:123, testString:"test"}, - data:{dataNumber:123, dataString:"test"} - }; - - client.on('error', function(err){ - err.should.startWith("parameters argument cannot be used if parameters are already defined in URL"); - done(); - }); - - client.registerMethod("testMethod",server.baseURL + "/json/path/post/query?testNumber=123&testString=test","POST"); - - client.methods.testMethod(args, function(data, response){ - // noop - }).should.throw(); - - }); - - it("POST request with registered method and invalid args type", function(done){ - var client = new Client(); - var args ="123"; - - client.on('error', function(err){ - err.should.startWith("args should be and object"); - done(); - }); - - client.registerMethod("testMethod",server.baseURL + "/json/path/post/query","POST"); - - client.methods.testMethod(args, function(data, response){ - // noop - }).should.throw(); - - }); - - - it("POST request with registered method and invalid parameters type", function(done){ - var client = new Client(); - var args ={ - parameters:"{test='123'}" - }; - - client.on('error', function(err){ - err.should.startWith("cannot serialize"); - done(); - }); - - client.registerMethod("testMethod",server.baseURL + "/json/path/post/query","POST"); - - client.methods.testMethod(args, function(data, response){ - // noop - }).should.throw(); - - }); - }); - -describe("#XML",function(){ - - it("POST request with parameters", function(done){ - var client = new Client(); - var args ={ - data:"123123" - }; - client.post(server.baseURL + "/xml/path/post/query",args, function(data, response){ - data.should.type("object"); - data.testData.should.be.ok; - data.testData.testNumber.should.be.ok; - data.testData.testString.should.be.ok; - data.testData.testNumber.should.be.a.Number; - data.testData.testString.should.be.a.String; - data.testData.testNumber.should.be.equal("123"); - data.testData.testString.should.be.equal("123"); - - - done(); - }); - }); - -}); - -after(function () { - server.close(); - console.log("server stopped"); -}); -}); \ No newline at end of file diff --git a/test/specs/TestPOSTMethod.mjs b/test/specs/TestPOSTMethod.mjs new file mode 100644 index 0000000..24a4a57 --- /dev/null +++ b/test/specs/TestPOSTMethod.mjs @@ -0,0 +1,259 @@ +/* eslint-disable max-len */ +import server from '../server/mock-server.mjs'; +import Client from '../../dist/mjs/NodeRestClient.js'; +import {createReadStream, readFileSync} from 'fs'; + + +describe('POST Method', function() { + // eslint-disable-next-line no-invalid-this + this.timeout(150000); + + before(function() { + server.listen(4444); + console.log('server started on port 4444'); + }); + + + describe('#JSON', function() { + it('POST request with path variable substitution', function(done) { + const client = new Client(); + const args ={ + path: {testNumber: 123, testString: 'test'}, + data: '{"dataNumber":123, "dataString":"test"}', + + }; + + client.post( server.baseURL + '/json/path/post/${testNumber}/${testString}', + args, + function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.url.should.equal('/json/path/post/123/test'); + data.postData.should.equal('{"dataNumber":123, "dataString":"test"}'); + done(); + }); + }); + + + it('POST request with parameters', function(done) { + const client = new Client(); + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + data: '{"dataNumber":123,"dataString":"test"}', + }; + client.post(server.baseURL + '/json/path/post/query', + args, + function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.url.should.equal('/json/path/post/query?testNumber=123&testString=test'); + data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); + done(); + }); + }); + + it('POST request with registered method and no args', function(done) { + const client = new Client(); + + + client.registerMethod('testMethod', server.baseURL + '/json', 'POST'); + + client.methods.testMethod( function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + done(); + }); + }); + + + it('POST request with registered method and path variable substitution', function(done) { + const client = new Client(); + const args ={ + path: {testNumber: 123, testString: 'test'}, + data: '{"dataNumber":123,"dataString":"test"}', + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/${testNumber}/${testString}', 'POST'); + + client.methods.testMethod(args, function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.url.should.equal('/json/path/post/123/test'); + data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); + done(); + }); + }); + + + it('POST request with registered method and parameters', function(done) { + const client = new Client(); + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + data: '{"dataNumber":123,"dataString":"test"}', + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/query', 'POST'); + + client.methods.testMethod(args, function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.url.should.equal('/json/path/post/query?testNumber=123&testString=test'); + data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); + done(); + }); + }); + + it('POST request with incompatible parameters URL', function(done) { + const client = new Client(); + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + data: {dataNumber: 123, dataString: 'test'}, + }; + + client.on('error', function(err) { + err.should.startWith('parameters argument cannot be used if parameters are already defined in URL'); + done(); + }); + + client.post(server.baseURL + '/json/path/post/query?testNumber=123&testString=test', args, function(data, response) { + // noop + }).should.throw(); + }); + + it('POST request with invalid args type', function(done) { + const client = new Client(); + const args = '123'; + + client.on('error', function(err) { + err.should.startWith('args should be and object'); + done(); + }); + + + client.post(server.baseURL + '/json/path/post/query', args, function(data, response) { + // noop + }).should.throw(); + }); + + + it('POST request with invalid parameters type', function(done) { + const client = new Client(); + const args ={ + parameters: '{test=\'123\'}', + }; + + client.on('error', function(err) { + err.should.startWith('cannot serialize'); + done(); + }); + + + client.post(server.baseURL + '/json/path/post/query', args, function(data, response) { + // noop + }).should.throw(); + }); + + it('POST request with registered method and incompatible parameters URL', function(done) { + const client = new Client(); + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + data: {dataNumber: 123, dataString: 'test'}, + }; + + client.on('error', function(err) { + err.should.startWith('parameters argument cannot be used if parameters are already defined in URL'); + done(); + }); + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/query?testNumber=123&testString=test', 'POST'); + + client.methods.testMethod(args, function(data, response) { + // noop + }).should.throw(); + }); + + it('POST request with registered method and invalid args type', function(done) { + const client = new Client(); + const args ='123'; + + client.on('error', function(err) { + err.should.startWith('args should be and object'); + done(); + }); + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/query', 'POST'); + + client.methods.testMethod(args, function(data, response) { + // noop + }).should.throw(); + }); + + + it('POST request with registered method and invalid parameters type', function(done) { + const client = new Client(); + const args ={ + parameters: '{test=\'123\'}', + }; + + client.on('error', function(err) { + err.should.startWith('cannot serialize'); + done(); + }); + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/query', 'POST'); + + client.methods.testMethod(args, function(data, response) { + // noop + }).should.throw(); + }); + }); + + describe('#XML', function() { + it('POST request with parameters', function(done) { + const client = new Client(); + const args ={ + data: '123123', + }; + client.post(server.baseURL + '/xml/path/post/query', args, function(data, response) { + data.should.type('object'); + data.testData.should.be.ok; + data.testData.testNumber.should.be.ok; + data.testData.testString.should.be.ok; + data.testData.testNumber.should.be.a.Number; + data.testData.testString.should.be.a.String; + data.testData.testNumber.should.be.equal('123'); + data.testData.testString.should.be.equal('123'); + + + done(); + }); + }); + }); + + describe('#STREAM', function() { + it('POST request with file read stream', function(done) { + const client = new Client(); + + // create read stream from file + const testFilePath = './test/resources/stream-file.txt'; + const sourceData = readFileSync(testFilePath); + const sourceStream = createReadStream(testFilePath); + + + client.post( + server.baseURL + '/stream', + {data: sourceStream}, + function(data, response) { + response.statusCode.should.be.equal(200); + data.toString().should.equal(sourceData.toString()); + done(); + }, + ); + }); + }); + + after(function() { + server.close(); + console.log('server stopped'); + }); +}); diff --git a/test/specs/TestPOSTMethodPromised.mjs b/test/specs/TestPOSTMethodPromised.mjs new file mode 100644 index 0000000..62e046b --- /dev/null +++ b/test/specs/TestPOSTMethodPromised.mjs @@ -0,0 +1,207 @@ +/* eslint-disable max-len */ +import server from '../server/mock-server.mjs'; +import Client from '../../dist/mjs/NodeRestClient.js'; + +let client; + +describe('POST Promise Method', function() { + // eslint-disable-next-line no-invalid-this + this.timeout(150000); + + const assertPromiseResult = (result) => { + result.should.not.equal(null); + result.response.should.not.equal(null); + result.data.should.not.equal(null); + result.data.should.type('object'); + }; + + before(function() { + client = new Client({usePromises: true}); + server.listen(4444); + console.log('server started on port 4444'); + }); + + describe('#JSON', function() { + it('POST promise request with path variable substitution', () => { + const args ={ + path: {testNumber: 123, testString: 'test'}, + data: '{"dataNumber":123, "dataString":"test"}', + + }; + + return client.post( server.baseURL + '/json/path/post/${testNumber}/${testString}', + args).then( (result) => { + assertPromiseResult(result); + result.data.url.should.equal('/json/path/post/123/test'); + result.data.postData.should.equal( + '{"dataNumber":123, "dataString":"test"}', + ); + }); + }); + + + it('POST Promise request with parameters', () => { + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + data: '{"dataNumber":123,"dataString":"test"}', + }; + return client.post(server.baseURL + '/json/path/post/query', + args).then( + (result) => { + assertPromiseResult(result); + result.data.url.should.equal('/json/path/post/query?testNumber=123&testString=test'); + result.data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); + }); + }); + + it('POST Promise request with registered method and no args', () => { + client.registerMethod('testMethod', server.baseURL + '/json', 'POST'); + + return client.methods.testMethod().then((result) => assertPromiseResult(result)); + }); + + + it('POST Promise request with registered method and path variable substitution', () => { + const args ={ + path: {testNumber: 123, testString: 'test'}, + data: '{"dataNumber":123,"dataString":"test"}', + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/${testNumber}/${testString}', 'POST'); + + return client.methods.testMethod(args).then((result) =>{ + assertPromiseResult(result); + result.data.url.should.equal('/json/path/post/123/test'); + result.data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); + }); + }); + + + it('POST Promise request with registered method and parameters', () => { + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + data: '{"dataNumber":123,"dataString":"test"}', + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/query', 'POST'); + + return client.methods.testMethod(args).then((result) => { + assertPromiseResult(result); + result.data.url.should.equal('/json/path/post/query?testNumber=123&testString=test'); + result.data.postData.should.equal('{"dataNumber":123,"dataString":"test"}'); + }); + }); + + it('POST Promise request with incompatible parameters URL', () => { + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + data: {dataNumber: 123, dataString: 'test'}, + }; + + client + .post( + server.baseURL + + '/json/path/post/query?testNumber=123&testString=test', + args, + ) + .then((result) => { + // noop + }).catch((err) => + err.should.startWith('parameters argument cannot be used if parameters are already defined in URL')); + }); + + it('POST Promise request with invalid args type', () => { + const args = '123'; + + client + .post(server.baseURL + '/json/path/post/query', args) + .then((result) => { + // noop + }).catch((err) => err.should.startWith('args should be and object')); + }); + + + it('POST Promise request with invalid parameters type', () => { + const args ={ + parameters: '{test=\'123\'}', + }; + + client.on('error', function(err) { + done(); + }); + + + client + .post(server.baseURL + '/json/path/post/query', args) + .then((result) => { + // noop + }).catch((err) => err.should.startWith('cannot serialize')); + }); + + it('POST Promise request with registered method and incompatible parameters URL', () => { + const args ={ + parameters: {testNumber: 123, testString: 'test'}, + data: {dataNumber: 123, dataString: 'test'}, + }; + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/query?testNumber=123&testString=test', 'POST'); + client.methods + .testMethod(args) + .then((result) => { + // noop + }).catch((err) => err.should.startWith('parameters argument cannot be used if parameters are already defined in URL')); + }); + + it('POST Promise request with registered method and invalid args type', () => { + const args ='123'; + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/query', 'POST'); + + client.methods + .testMethod(args) + .then((result) => { + // noop + }) + .catch((err) => err.should.startWith('args should be and object')); + }); + + + it('POST Promise request with registered method and invalid parameters type', () => { + const args ={ + parameters: '{test=\'123\'}', + }; + + + client.registerMethod('testMethod', server.baseURL + '/json/path/post/query', 'POST'); + + client.methods + .testMethod(args) + .then((result) => { + // noop + }).catch((err) => err.should.startWith('cannot serialize')); + }); + }); + + describe('POST Promise #XML', function() { + it('POST Promise request with parameters', () => { + const args ={ + data: '123123', + }; + return client.post(server.baseURL + '/xml/path/post/query', args).then((result) => { + result.data.should.type('object'); + result.data.testData.should.be.ok; + result.data.testData.testNumber.should.be.ok; + result.data.testData.testString.should.be.ok; + result.data.testData.testNumber.should.be.a.Number; + result.data.testData.testString.should.be.a.String; + result.data.testData.testNumber.should.be.equal('123'); + result.data.testData.testString.should.be.equal('123'); + }); + }); + }); + + after(function() { + server.close(); + console.log('server stopped'); + }); +}); diff --git a/test/specs/TestRIOFacade.js b/test/specs/TestRIOFacade.js deleted file mode 100644 index b7d6f5e..0000000 --- a/test/specs/TestRIOFacade.js +++ /dev/null @@ -1,317 +0,0 @@ -var server =require("../server/mock-server"), -Client=require("../../lib/node-rest-client").Client; - -describe('IO Facade', function () { - - this.timeout(150000); - - before(function () { - server.listen(4444); - console.log("server started on port 4444"); - }); - - describe("#Parsers",function(){ - - var testParser = {"name":"test-parser", - "isDefault":false, - "match":function(response){ - return response.headers["test-header"] === "test"; - }, - "parse":function(byteBuffer,nrcEventEmitter,parsedCallback){ - var message = JSON.parse(byteBuffer.toString()); - message.parsed = true; - parsedCallback(message); - } - }, - defaultTestParser = {"name":"default-test-parser", - "isDefault":true, - "parse":function(byteBuffer,nrcEventEmitter,parsedCallback){ - var message = JSON.parse(byteBuffer.toString()); - message.defaultParsed = true; - parsedCallback(message); - } - }; - - it("add invalid parser to client", function(done){ - var client = new Client(); - - client.on('error', function(err){ - err.should.startWith("parser cannot be added: invalid parser definition"); - done(); - }); - - client.parsers.add({"invalid":123, "parser":456}).should.throw(); - }); - - - it("add parser to client", function(done){ - var client = new Client(); - client.parsers.add(testParser); - var parser = client.parsers.find("test-parser"); - - parser.should.not.equal(null); - parser.should.type("object"); - done(); - }); - - - it("remove parser from client", function(done){ - var client = new Client(); - - client.on('error', function(err){ - err.should.startWith("cannot find parser: test-parser doesn't exists"); - done(); - }); - - client.parsers.add(testParser); - var parser = client.parsers.find("test-parser"); - - parser.should.not.equal(null); - parser.should.type("object"); - - client.parsers.remove("test-parser"); - client.parsers.find("test-parser"); - }); - - it("response match parser", function(done){ - var client = new Client(); - client.parsers.clean(); - client.parsers.add(testParser); - - client.get(server.baseURL + "/json", function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - data.should.have.property("parsed"); - data.parsed.should.be.a.Boolean; - data.parsed.should.be.true; - done(); - }); - - }); - - - it("add and use default parser", function(done){ - var client = new Client(); - client.parsers.clean(); - - client.parsers.add(testParser); - client.parsers.add(defaultTestParser); - // no parsers defined, default must be used - - client.get(server.baseURL + "/json/path?default-test", function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - data.should.have.property("defaultParsed"); - data.defaultParsed.should.be.a.Boolean; - data.defaultParsed.should.be.true; - done(); - }); - - }); - - - it("add custom types to args in JSON parser", function(done){ - var options={ - // customize mime types for json or xml connections - mimetypes: { - json: ["test/json"] - } - }; - var client = new Client(options); - - client.get(server.baseURL + "/json/test/content/type", function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - done(); - }); - - }); - - - it("add custom types to args in XML parser", function(done){ - var options={ - // customize mime types for json or xml connections - mimetypes: { - xml: ["test/xml"] - } - }; - var client = new Client(options); - - client.get(server.baseURL + "/xml/test/content/type", function(data, response){ - data.should.not.equal(null); - data.should.type("object"); - done(); - }); - - }); - - - it("get all regular parsers", function(done){ - - var client = new Client(); - var parsers = client.parsers.getAll(); - parsers.should.have.length(2); - done(); - - }); - - it("emit custom event from parser to client", function(done){ - var client = new Client(); - client.on('customEvent',function(event){ - event.should.be.equal("my custom event"); - done(); - }); - - - client.parsers.clean(); - client.parsers.add({ - "name":"example-parser", - "isDefault":false, - "match":function(request){return true; }, - "parse":function(byteBuffer,nrcEventEmitter,parsedCallback){ - nrcEventEmitter('customEvent','my custom event'); - // pass serialized data to client to be sent to remote API - parsedCallback(byteBuffer.toString()); - - } - }); - - var args ={data:"test data"} - - client.post(server.baseURL + "/json/path/post/query",args, function(data, response){}); - - }); - - }); - - -describe("#Serializers",function(){ - - var testSerializer = {"name":"test-serializer", - "isDefault":false, - "match":function(request){ - return request.headers["test-header"] === "test"; - }, - "serialize":function(data,nrcEventEmitter,serializedCallback){ - if (typeof data === 'object') - data.serialized = true; - serializedCallback(JSON.stringify(data)); - } - }, - defaultTestSerializer = {"name":"default-test-serializer", - "isDefault":true, - "serialize":function(data,nrcEventEmitter,serializedCallback){ - if (typeof data === 'object') - data.defaultParsed = true; - serializedCallback(data); - } - }; - - - it("add invalid serializer to client", function(done){ - var client = new Client(); - - client.on('error', function(err){ - err.should.startWith("serializer cannot be added: invalid serializer definition"); - done(); - }); - - client.serializers.add({"invalid":123, "serializer":456}).should.throw(); - }); - - - - it("add serializer to client", function(done){ - var client = new Client(); - client.serializers.add(testSerializer); - var serializer = client.serializers.find("test-serializer"); - - serializer.should.not.equal(null); - serializer.should.type("object"); - done(); - }); - - - it("remove serializer from client", function(done){ - var client = new Client(); - - client.on('error', function(err){ - err.should.startWith("cannot find serializer: test-serializer doesn't exists"); - done(); - }); - - client.serializers.add(testSerializer); - var serializer = client.serializers.find("test-serializer"); - - serializer.should.not.equal(null); - serializer.should.type("object"); - - client.serializers.remove("test-serializer"); - client.serializers.find("test-serializer"); - }); - - - it("request match serializer", function(done){ - var client = new Client(), - args={ - headers:{"test-header":"test"}, - data:{"testNumber":123, "testString":"abc"} - }; - - client.serializers.clean(); - client.serializers.add(testSerializer); - - var request = client.post(server.baseURL + "/json/path/post",args, function(data, response){ - data.postData.should.not.equal(null); - data.postData.should.type("object"); - data.postData.should.have.property("serialized"); - data.postData.serialized.should.be.a.Boolean; - data.postData.serialized.should.be.true; - }); - - done(); - - }); - - it("get all regular serializers", function(done){ - - var client = new Client(); - var serializers = client.serializers.getAll(); - serializers.should.have.length(3); - done(); - - }); - - it("emit custom event from serializer to client", function(done){ - var client = new Client(); - client.on('customEvent',function(event){ - event.should.be.equal("my custom event"); - done(); - }); - - - client.serializers.clean(); - client.serializers.add({ - "name":"example-serializer", - "isDefault":false, - "match":function(request){return true; }, - "serialize":function(data,nrcEventEmitter,serializedCallback){ - nrcEventEmitter('customEvent','my custom event'); - // pass serialized data to client to be sent to remote API - serializedCallback(data.toString()); - - } - }); - - var args ={data:"test data"} - - client.post(server.baseURL + "/json/path/post/query",args, function(data, response){}); - - }); - -}); - -after(function () { - server.close(); -}); -}); \ No newline at end of file diff --git a/test/specs/TestRIOFacade.mjs b/test/specs/TestRIOFacade.mjs new file mode 100644 index 0000000..78f78f1 --- /dev/null +++ b/test/specs/TestRIOFacade.mjs @@ -0,0 +1,300 @@ +/* eslint-disable max-len */ +import server from '../server/mock-server.mjs'; +import Client from '../../dist/mjs/NodeRestClient.js'; + +describe('IO Facade', function() { + // eslint-disable-next-line no-invalid-this + this.timeout(150000); + + before(function() { + server.listen(4444); + console.log('server started on port 4444'); + }); + + describe('#Parsers', function() { + const testParser = {'name': 'test-parser', + 'isDefault': false, + 'match': function(response) { + return response.headers['test-header'] === 'test'; + }, + 'parse': function(byteBuffer, nrcEventEmitter, parsedCallback) { + const message = JSON.parse(byteBuffer.toString()); + message.parsed = true; + parsedCallback(message); + }, + }; + const defaultTestParser = {'name': 'default-test-parser', + 'isDefault': true, + 'parse': function(byteBuffer, nrcEventEmitter, parsedCallback) { + const message = JSON.parse(byteBuffer.toString()); + message.defaultParsed = true; + parsedCallback(message); + }, + }; + + it('add invalid parser to client', function(done) { + const client = new Client(); + + client.on('error', function(err) { + err.message.should.startWith('parser cannot be added: invalid parser definition'); + done(); + }); + + client.parsers.add({'invalid': 123, 'parser': 456}).should.throw(); + }); + + + it('add parser to client', function(done) { + const client = new Client(); + client.parsers.add(testParser); + const parser = client.parsers.find('test-parser'); + + parser.should.not.equal(null); + parser.should.type('object'); + done(); + }); + + + it('remove parser from client', function(done) { + const client = new Client(); + + client.on('error', function(err) { + err.message.should.startWith('cannot find parser: test-parser doesn\'t exists'); + done(); + }); + + client.parsers.add(testParser); + const parser = client.parsers.find('test-parser'); + + parser.should.not.equal(null); + parser.should.type('object'); + + client.parsers.remove('test-parser'); + client.parsers.find('test-parser'); + }); + + it('response match parser', function(done) { + const client = new Client(); + client.parsers.clean(); + client.parsers.add(testParser); + + client.get(server.baseURL + '/json', function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.should.have.property('parsed'); + data.parsed.should.be.a.Boolean; + data.parsed.should.be.true; + done(); + }); + }); + + + it('add and use default parser', function(done) { + const client = new Client(); + client.parsers.clean(); + + client.parsers.add(testParser); + client.parsers.add(defaultTestParser); + // no parsers defined, default must be used + + client.get(server.baseURL + '/json/path?default-test', function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + data.should.have.property('defaultParsed'); + data.defaultParsed.should.be.a.Boolean; + data.defaultParsed.should.be.true; + done(); + }); + }); + + + it('add custom types to args in JSON parser', function(done) { + const options={ + // customize mime types for json or xml connections + mimetypes: { + json: ['test/json'], + }, + }; + const client = new Client(options); + + client.get(server.baseURL + '/json/test/content/type', function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + done(); + }); + }); + + + it('add custom types to args in XML parser', function(done) { + const options={ + // customize mime types for json or xml connections + mimetypes: { + xml: ['test/xml'], + }, + }; + const client = new Client(options); + + client.get(server.baseURL + '/xml/test/content/type', function(data, response) { + data.should.not.equal(null); + data.should.type('object'); + done(); + }); + }); + + + it('get all regular parsers', function(done) { + const client = new Client(); + const parsers = client.parsers.getAll(); + parsers.should.have.length(2); + done(); + }); + + it('emit custom event from parser to client', function(done) { + const client = new Client(); + client.on('customEvent', function(event) { + event.should.be.equal('my custom event'); + done(); + }); + + + client.parsers.clean(); + client.parsers.add({ + 'name': 'example-parser', + 'isDefault': false, + 'match': function(request) { + return true; + }, + 'parse': function(byteBuffer, nrcEventEmitter, parsedCallback) { + nrcEventEmitter('customEvent', 'my custom event'); + // pass serialized data to client to be sent to remote API + parsedCallback(byteBuffer.toString()); + }, + }); + + const args ={data: 'test data'}; + + client.post(server.baseURL + '/json/path/post/query', args, function(data, response) {}); + }); + }); + + + describe('#Serializers', function() { + const testSerializer = {'name': 'test-serializer', + 'isDefault': false, + 'match': function(request) { + return request.headers['test-header'] === 'test'; + }, + 'serialize': function(data, nrcEventEmitter, serializedCallback) { + if (typeof data === 'object') { + data.serialized = true; + } + serializedCallback(JSON.stringify(data)); + }, + }; + + + it('add invalid serializer to client', function(done) { + const client = new Client(); + + client.on('error', function(err) { + err.message.should.startWith('serializer cannot be added: invalid serializer definition'); + done(); + }); + + client.serializers.add({'invalid': 123, 'serializer': 456}).should.throw(); + }); + + + it('add serializer to client', function(done) { + const client = new Client(); + client.serializers.add(testSerializer); + const serializer = client.serializers.find('test-serializer'); + + serializer.should.not.equal(null); + serializer.should.type('object'); + done(); + }); + + + it('remove serializer from client', function(done) { + const client = new Client(); + + client.on('error', function(err) { + err.message.should.startWith('cannot find serializer: test-serializer doesn\'t exists'); + done(); + }); + + client.serializers.add(testSerializer); + const serializer = client.serializers.find('test-serializer'); + + serializer.should.not.equal(null); + serializer.should.type('object'); + + client.serializers.remove('test-serializer'); + client.serializers.find('test-serializer'); + }); + + + it('request match serializer', function(done) { + const client = new Client(); + const args={ + headers: {'test-header': 'test'}, + data: {'testNumber': 123, 'testString': 'abc'}, + }; + + client.serializers.clean(); + client.serializers.add(testSerializer); + + const request = client.post(server.baseURL + '/json/path/post', args, function(data, response) { + data.postData.should.not.equal(null); + data.postData.should.type('string'); + data.postData.includes('serialized').should.be.true(); + }); + + request.should.not.be.null(); + done(); + }); + + it('get all regular serializers', function(done) { + const client = new Client(); + const serializers = client.serializers.getAll(); + serializers.should.have.length(3); + done(); + }); + + it('emit custom event from serializer to client', function(done) { + const client = new Client(); + client.on('customEvent', function(event) { + event.should.be.equal('my custom event'); + done(); + }); + + + client.serializers.clean(); + client.serializers.add({ + 'name': 'example-serializer', + 'isDefault': false, + 'match': function(request) { + return true; + }, + 'serialize': function(data, nrcEventEmitter, serializedCallback) { + nrcEventEmitter('customEvent', 'my custom event'); + // pass serialized data to client to be sent to remote API + serializedCallback(data.toString()); + }, + }); + + const args ={data: 'test data'}; + + client.post(server.baseURL + '/json/path/post/query', args, function(data, response) {}); + }); + }); + + after(function() { + // server will respond with ECONNRESET if we do not wait here + setTimeout(() => { + server.close(); + console.log('server stopped'); + }, 1000 ); + }); +}); diff --git a/test/test-proxy.js b/test/test-proxy.js deleted file mode 100644 index 491db17..0000000 --- a/test/test-proxy.js +++ /dev/null @@ -1,91 +0,0 @@ -var http = require('http'); -var fs = require('fs'); - -var blacklist = []; -var iplist = []; - -fs.watchFile('./blacklist', function(c,p) { update_blacklist(); }); -fs.watchFile('./iplist', function(c,p) { update_iplist(); }); - -function update_blacklist() { - console.log("Updating blacklist."); - blacklist = fs.readFileSync('./blacklist', {encoding: 'utf-8'}).split('\n') - .filter(function(rx) { return rx.length }) - .map(function(rx) { return RegExp(rx) }); -} - -function update_iplist() { - console.log("Updating iplist."); - iplist = fs.readFileSync('./iplist', {encoding: 'utf-8'}).split('\n') - .filter(function(rx) { return rx.length }); -} - -function ip_allowed(ip) { - for (i in iplist) { - if (iplist[i] == ip) { - return true; - } - } - return false; -} - -function host_allowed(host) { - for (i in blacklist) { - if (blacklist[i].test(host)) { - return false; - } - } - return true; -} - -function deny(response, msg) { - response.writeHead(401); - response.write(msg); - response.end(); -} - -http.createServer(function(request, response) { - var ip = request.connection.remoteAddress; - if (!ip_allowed(ip)) { - msg = "IP " + ip + " is not allowed to use this proxy"; - deny(response, msg); - console.log(msg); - return; - } - - if (!host_allowed(request.url)) { - msg = "Host " + request.url + " has been denied by proxy configuration"; - deny(response, msg); - console.log(msg); - return; - } - - console.log(ip + ": " + request.method + " " + request.url); - var agent = new http.Agent({ host: request.headers['host'], port: 80, maxSockets: 1 }); - var proxy_request = http.request({ - host: request.headers['host'], - port: 80, - method: request.method, - path: request.url, - headers: request.headers, - agent: agent - }); - proxy_request.addListener('response', function(proxy_response) { - proxy_response.addListener('data', function(chunk) { - response.write(chunk, 'binary'); - }); - proxy_response.addListener('end', function() { - response.end(); - }); - response.writeHead(proxy_response.statusCode, proxy_response.headers); - }); - request.addListener('data', function(chunk) { - proxy_request.write(chunk, 'binary'); - }); - request.addListener('end', function() { - proxy_request.end(); - }); -}).listen(8080); - -update_blacklist(); -update_iplist(); \ No newline at end of file diff --git a/test/test-proxy.mjs b/test/test-proxy.mjs new file mode 100644 index 0000000..2971922 --- /dev/null +++ b/test/test-proxy.mjs @@ -0,0 +1,143 @@ +import http from 'http'; +import fs from 'fs'; + +/** + * Description placeholder + * @date 6/30/2023 - 1:26:51 PM + * + * @type {{}} + */ +let blacklist = []; +/** + * Description placeholder + * @date 6/30/2023 - 1:26:51 PM + * + * @type {{}} + */ +let iplist = []; + +fs.watchFile('./blacklist', function(c, p) { + updateBlacklist(); +}); +fs.watchFile('./iplist', function(c, p) { + updateIPlist(); +}); + +/** + * Description placeholder + * @date 6/30/2023 - 1:26:29 PM + */ +function updateBlacklist() { + console.log('Updating blacklist.'); + blacklist = fs.readFileSync('./blacklist', {encoding: 'utf-8'}).split('\n') + .filter(function(rx) { + return rx.length; + }) + .map(function(rx) { + return RegExp(rx); + }); +} + +/** + * Description placeholder + * @date 6/30/2023 - 1:26:51 PM + */ +function updateIPlist() { + console.log('Updating iplist.'); + iplist = fs.readFileSync('./iplist', {encoding: 'utf-8'}).split('\n') + .filter(function(rx) { + return rx.length; + }); +} + +/** + * Description placeholder + * @date 6/30/2023 - 1:26:51 PM + * + * @param {*} ip + * @return {boolean} + */ +function ipAllowed(ip) { + for (i in iplist) { + if (iplist[i] == ip) { + return true; + } + } + return false; +} + +/** + * Description placeholder + * @date 6/30/2023 - 1:26:51 PM + * + * @param {*} host + * @return {boolean} + */ +function hostAllowed(host) { + for (i in blacklist) { + if (blacklist[i].test(host)) { + return false; + } + } + return true; +} + +/** + * Description placeholder + * @date 6/30/2023 - 1:26:51 PM + * + * @param {*} response + * @param {*} msg + */ +function deny(response, msg) { + response.writeHead(401); + response.write(msg); + response.end(); +} + +http.createServer(function(request, response) { + const ip = request.socket.remoteAddress; + if (!ipAllowed(ip)) { + const msg = `IP ${ip} is not allowed to use this proxy`; + deny(response, msg); + console.log(msg); + return; + } + + if (!hostAllowed(request.url)) { + const msg = `Host ${request.url} has been denied by proxy configuration`; + deny(response, msg); + console.log(msg); + return; + } + + console.log(ip + ': ' + request.method + ' ' + request.url); + const agent = new http.Agent({host: request.headers['host'], + port: 80, maxSockets: 1}); + const proxyRequest = http.request({ + host: request.headers['host'], + port: 80, + method: request.method, + path: request.url, + headers: request.headers, + agent: agent, + }); + proxyRequest.addListener('response', function(proxyResponse) { + proxyResponse.addListener('data', function(chunk) { + response.write(chunk, 'binary'); + }); + proxyResponse.addListener('end', function() { + response.end(); + }); + response.writeHead(proxyResponse.statusCode, proxyResponse.headers); + }); + request.addListener('data', function(chunk) { + proxyRequest.write(chunk, 'binary'); + }); + request.addListener('end', function() { + proxyRequest.end(); + }); +}).listen(8080); + +updateBlacklist(); +updateIPlist(); diff --git a/tsconfig-base.json b/tsconfig-base.json new file mode 100644 index 0000000..1099d73 --- /dev/null +++ b/tsconfig-base.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "allowJs": true, + "allowSyntheticDefaultImports": true, + "baseUrl": "lib", + "declaration": true, + "esModuleInterop": true, + "inlineSourceMap": false, + "lib": ["esnext"], + "listEmittedFiles": false, + "listFiles": false, + "moduleResolution": "node", + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false, + "pretty": true, + "resolveJsonModule": true, + "rootDir": "lib", + "skipLibCheck": true, + "strict": false, + "traceResolution": false, + "types": ["node", "jest"] + }, + "compileOnSave": false, + "exclude": ["node_modules", "dist"], + "include": ["lib"] +} \ No newline at end of file diff --git a/tsconfig-cjs.json b/tsconfig-cjs.json new file mode 100644 index 0000000..13a7594 --- /dev/null +++ b/tsconfig-cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig-base.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "dist/cjs", + "target": "es2015" + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..382b9c4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig-base.json", + "compilerOptions": { + "module": "esnext", + "outDir": "dist/mjs", + "target": "esnext" + } +} \ No newline at end of file