diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb074a8..2adf676 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,14 +7,16 @@ jobs: strategy: matrix: - node-version: [10.x, 12.x, 14.x, 16.x, '*'] + node-version: [20.x, 22.x, '*'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} + cache: 'npm' + cache-dependency-path: 'package.json' - uses: shivammathur/setup-php@v2 with: @@ -22,3 +24,62 @@ jobs: - run: npm ci - run: npm test + + publish: + name: Publish to npm + needs: build + if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + environment: + name: npm + url: https://www.npmjs.com/package/@httptoolkit/httpsnippet + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22.x' + registry-url: 'https://registry.npmjs.org' + cache: 'npm' + cache-dependency-path: 'package.json' + + - run: npm ci + + - name: Verify tag matches package.json version + id: version-check + run: | + TAG_VERSION=${GITHUB_REF#refs/tags/v} + PACKAGE_VERSION=$(node -p "require('./package.json').version") + if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then + echo "Error: Tag version (v$TAG_VERSION) does not match package.json version ($PACKAGE_VERSION)" + exit 1 + fi + echo "✓ Tag version matches package.json version: $PACKAGE_VERSION" + + # Check if version matches strict X.Y.Z format (stable release) + if echo "$PACKAGE_VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "Stable release version detected: $PACKAGE_VERSION" + echo "is_prerelease=false" >> $GITHUB_OUTPUT + else + echo "Prerelease version detected: $PACKAGE_VERSION" + echo "is_prerelease=true" >> $GITHUB_OUTPUT + fi + + # Make sure we have the latest npm for publishing: + - run: npm install -g npm@latest + + - name: Publish to npm + run: | + if [ "${{ steps.version-check.outputs.is_prerelease }}" == "true" ]; then + echo "Publishing untagged prerelease" + npm publish --provenance --tag test + # We have to publish with a tag (so we use 'test') but we can clean it up: + npm dist-tag rm @httptoolkit/httpsnippet test --silent + else + echo "Publishing stable release with 'latest' tag" + npm publish --provenance + fi \ No newline at end of file diff --git a/TARGETS.md b/TARGETS.md index 08d9986..e855002 100644 --- a/TARGETS.md +++ b/TARGETS.md @@ -40,6 +40,17 @@ Currently the following output targets are supported: | --------- | ------- | -------------------------------- | | `indent` | ` ` | line break & indent output value | +### [RestClient](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestClient.html) + +> Spring Framework REST client + +###### Options + +| Option | Default | Description | +| ------------ | -------- | -------------------------------- | +| `indent` | ` ` | line break & indent output value | +| `entityType` | `String` | Java type for the entity | + ---- ## JavaScript diff --git a/package-lock.json b/package-lock.json index e507f1e..69e2307 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "@httptoolkit/httpsnippet", - "version": "2.1.4", + "version": "3.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@httptoolkit/httpsnippet", - "version": "2.1.4", + "version": "3.0.2", "license": "MIT", "dependencies": { "chalk": "^1.1.1", "commander": "^2.9.0", "debug": "^2.2.0", "event-stream": "3.3.4", - "form-data": "3.0.0", + "form-data": "3.0.4", "fs-readfile-promise": "^2.0.1", "fs-writefile-promise": "^1.0.3", "har-validator": "^5.0.0" @@ -25,13 +25,13 @@ "echint": "^4.0.2", "glob": "^6.0.1", "istanbul": "^0.4.0", - "mocha": "^8.2.1", + "mocha": "^11.7.5", "require-directory": "^2.1.1", "should": "^13.2.3", "standard": "^16.0.3" }, "engines": { - "node": ">=10" + "node": ">=22" } }, "node_modules/@babel/code-frame": { @@ -128,22 +128,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/node_modules/debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -161,12 +145,6 @@ } } }, - "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -185,18 +163,118 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", @@ -225,14 +303,18 @@ } }, "node_modules/ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dependencies": { - "fast-deep-equal": "^2.0.1", + "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/amdefine": { @@ -270,19 +352,6 @@ "node": ">=0.10.0" } }, - "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -366,15 +435,6 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "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", @@ -385,18 +445,6 @@ "concat-map": "0.0.1" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -416,6 +464,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -425,15 +485,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -450,70 +501,53 @@ } }, "node_modules/chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, - "optionalDependencies": { - "fsevents": "~2.1.2" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "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, "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/cliui/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/cliui/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, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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": "^4.1.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/color-convert": { @@ -552,9 +586,9 @@ } }, "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==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -597,15 +631,6 @@ "node": ">=0.10.0" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -642,9 +667,9 @@ } }, "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, "engines": { "node": ">=0.3.1" @@ -671,11 +696,30 @@ "node": ">=6" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/echint": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/echint/-/echint-4.0.2.tgz", @@ -804,15 +848,6 @@ "node": ">=8.6" } }, - "node_modules/enquirer/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/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -850,18 +885,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-abstract/node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-abstract/node_modules/object-inspect": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", @@ -915,6 +938,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -932,6 +996,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1627,9 +1700,9 @@ } }, "node_modules/fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "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==" }, "node_modules/fast-json-stable-stringify": { "version": "2.0.0", @@ -1654,18 +1727,6 @@ "node": ">=4" } }, - "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-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -1713,14 +1774,32 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", - "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz", + "integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -1779,26 +1858,13 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "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 + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -1816,29 +1882,38 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.0.tgz", - "integrity": "sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg==", - "dev": true, + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-intrinsic/node_modules/has-symbols": { + "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true, + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-stdin": { @@ -1896,20 +1971,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, "node_modules/handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", @@ -2000,10 +2077,37 @@ } }, "node_modules/has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, "engines": { "node": ">= 0.4" } @@ -2099,18 +2203,6 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "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-callable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", @@ -2186,13 +2278,13 @@ "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==", + "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": ">=0.12.0" + "node": ">=8" } }, "node_modules/is-plain-obj": { @@ -2219,18 +2311,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-regex/node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", @@ -2255,6 +2335,18 @@ "node": ">= 0.4" } }, + "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/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2327,6 +2419,21 @@ "node": ">=0.8.0" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2334,9 +2441,9 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "dependencies": { "argparse": "^1.0.7", @@ -2377,9 +2484,9 @@ "dev": true }, "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -2401,18 +2508,6 @@ "node": ">=4.0" } }, - "node_modules/jsx-ast-utils/node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/jsx-ast-utils/node_modules/object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", @@ -2487,21 +2582,25 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true }, "node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "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.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-symbols/node_modules/ansi-styles": { @@ -2520,9 +2619,9 @@ } }, "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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", @@ -2601,20 +2700,28 @@ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.40.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -2638,6 +2745,15 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -2668,57 +2784,63 @@ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "node_modules/mocha": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", - "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.4.3", - "debug": "4.2.0", - "diff": "4.0.2", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.14.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.2", - "nanoid": "3.1.12", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "7.2.0", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.0.2", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "2.0.0" + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", + "dev": true, + "dependencies": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 10.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" } }, "node_modules/mocha/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2741,19 +2863,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/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/mocha/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2771,20 +2880,20 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "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" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2800,13 +2909,12 @@ } }, "node_modules/mocha/node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -2827,10 +2935,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mocha/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mocha/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==", + "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/p-limit": { @@ -2885,30 +3008,18 @@ } }, "node_modules/mocha/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==", + "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": ">=8" - } - }, - "node_modules/mocha/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, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "node": ">=10" }, - "engines": { - "node": ">= 8" + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/ms": { @@ -2916,18 +3027,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node_modules/nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || >=13.7" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -2986,15 +3085,6 @@ "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-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3123,6 +3213,12 @@ "node": ">=4" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3180,6 +3276,28 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -3200,17 +3318,11 @@ "through": "~2.3" } }, - "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true }, "node_modules/pify": { "version": "2.3.0", @@ -3477,15 +3589,16 @@ } }, "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, "engines": { - "node": ">=8.10.0" + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/regexp.prototype.flags": { @@ -3525,12 +3638,6 @@ "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.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", @@ -3579,10 +3686,24 @@ } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "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/semver": { "version": "7.3.4", @@ -3618,20 +3739,14 @@ "dev": true }, "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3736,6 +3851,18 @@ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -3762,15 +3889,6 @@ "node": ">=4" } }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", @@ -3913,37 +4031,104 @@ } }, "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "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": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "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-width-cjs/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/string-width-cjs/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/string-width-cjs/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/string-width-cjs/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/string-width/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/string-width/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/string-width/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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": ">=4" + "node": ">=8" } }, "node_modules/string-width/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "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": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/string.prototype.matchall": { @@ -3964,18 +4149,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.matchall/node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -3987,6 +4160,28 @@ "node": ">=0.10.0" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/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/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -4028,22 +4223,6 @@ "node": ">=6.0.0" } }, - "node_modules/table/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/table/node_modules/ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -4053,21 +4232,6 @@ "node": ">=6" } }, - "node_modules/table/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/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/table/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -4105,18 +4269,6 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/tsconfig-paths": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", @@ -4213,21 +4365,6 @@ "which": "bin/which" } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -4244,70 +4381,152 @@ "dev": true }, "node_modules/workerpool": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", "dev": true }, "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "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": ">=6" + "node": ">=8" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "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": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/wrap-ansi/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": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=6" + "node": ">=7.0.0" } }, + "node_modules/wrap-ansi/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/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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": "^4.1.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/wrappy": { @@ -4347,10 +4566,13 @@ } }, "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true + "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": "2.1.2", @@ -4359,31 +4581,30 @@ "dev": true }, "node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "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, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "engines": { + "node": ">=12" } }, "node_modules/yargs-unparser": { @@ -4416,109 +4637,13 @@ "node_modules/yargs-unparser/node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/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/yargs/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/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/yargs/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yocto-queue": { @@ -4616,18 +4741,6 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -4637,12 +4750,6 @@ "ms": "2.1.2" } }, - "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 - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4657,18 +4764,84 @@ } } }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, "abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", @@ -4689,11 +4862,11 @@ "requires": {} }, "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" @@ -4722,16 +4895,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -4794,12 +4957,6 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "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 - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4810,15 +4967,6 @@ "concat-map": "0.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -4835,18 +4983,21 @@ "get-intrinsic": "^1.0.2" } }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -4860,56 +5011,38 @@ } }, "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "^4.0.1" } }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "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": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" } } } @@ -4947,9 +5080,9 @@ "dev": true }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -4982,12 +5115,6 @@ "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", "dev": true }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -5015,9 +5142,9 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true }, "doctrine": { @@ -5035,11 +5162,27 @@ "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==", "dev": true }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "echint": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/echint/-/echint-4.0.2.tgz", @@ -5139,14 +5282,6 @@ "dev": true, "requires": { "ansi-colors": "^4.1.1" - }, - "dependencies": { - "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 - } } }, "error-ex": { @@ -5180,12 +5315,6 @@ "string.prototype.trimstart": "^1.0.3" }, "dependencies": { - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, "object-inspect": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", @@ -5226,6 +5355,35 @@ } } }, + "es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "requires": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + } + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -5237,6 +5395,12 @@ "is-symbol": "^1.0.2" } }, + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -5736,9 +5900,9 @@ } }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "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==" }, "fast-json-stable-stringify": { "version": "2.0.0", @@ -5760,15 +5924,6 @@ "flat-cache": "^2.0.1" } }, - "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, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -5807,14 +5962,26 @@ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, + "foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + } + }, "form-data": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", - "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz", + "integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35" }, "dependencies": { "combined-stream": { @@ -5865,18 +6032,10 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -5891,22 +6050,29 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.0.tgz", - "integrity": "sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg==", - "dev": true, + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "dependencies": { - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - } + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" } }, "get-stdin": { @@ -5946,17 +6112,16 @@ "type-fest": "^0.8.1" } }, + "gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, "graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, "handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", @@ -6022,10 +6187,25 @@ "dev": true }, "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "requires": { + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + } }, "he": { "version": "1.2.0", @@ -6100,15 +6280,6 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, "is-callable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", @@ -6157,10 +6328,10 @@ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "dev": true }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "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 }, "is-plain-obj": { @@ -6176,14 +6347,6 @@ "dev": true, "requires": { "has-symbols": "^1.0.1" - }, - "dependencies": { - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - } } }, "is-string": { @@ -6201,6 +6364,12 @@ "has-symbols": "^1.0.0" } }, + "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 + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -6265,6 +6434,16 @@ } } }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6272,9 +6451,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -6307,9 +6486,9 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -6325,12 +6504,6 @@ "object.assign": "^4.1.2" }, "dependencies": { - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", @@ -6389,18 +6562,19 @@ } }, "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true }, "log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "chalk": "^4.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "dependencies": { "ansi-styles": { @@ -6413,9 +6587,9 @@ } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -6478,17 +6652,22 @@ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.40.0" + "mime-db": "1.52.0" } }, "minimatch": { @@ -6506,6 +6685,12 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -6528,45 +6713,56 @@ "requires": {} }, "mocha": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", - "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.4.3", - "debug": "4.2.0", - "diff": "4.0.2", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.14.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.2", - "nanoid": "3.1.12", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "7.2.0", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.0.2", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "2.0.0" - }, - "dependencies": { + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", + "dev": true, + "requires": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.3" } }, "escape-string-regexp": { @@ -6575,12 +6771,6 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "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 - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -6592,17 +6782,17 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "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" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" } }, "has-flag": { @@ -6612,13 +6802,12 @@ "dev": true }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "locate-path": { @@ -6630,10 +6819,19 @@ "p-locate": "^5.0.0" } }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "p-limit": { @@ -6665,23 +6863,14 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { - "isexe": "^2.0.0" + "has-flag": "^4.0.0" } } } @@ -6691,12 +6880,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", - "dev": true - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6748,12 +6931,6 @@ } } }, - "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 - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -6849,6 +7026,12 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6891,6 +7074,24 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + } + } + }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -6908,10 +7109,10 @@ "through": "~2.3" } }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "pify": { @@ -7118,13 +7319,10 @@ } }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true }, "regexp.prototype.flags": { "version": "1.3.1", @@ -7148,12 +7346,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", @@ -7192,9 +7384,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "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 }, "semver": { @@ -7224,20 +7416,14 @@ } }, "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -7332,6 +7518,12 @@ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -7351,12 +7543,6 @@ "requires": { "color-convert": "^1.9.0" } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true } } }, @@ -7461,28 +7647,81 @@ } }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "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, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "dependencies": { "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 + }, + "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 + }, + "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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 }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "string-width-cjs": { + "version": "npm:string-width@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, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "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 + }, + "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 + }, + "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 + }, + "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, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" } } } @@ -7500,14 +7739,6 @@ "internal-slot": "^1.0.2", "regexp.prototype.flags": "^1.3.0", "side-channel": "^1.0.3" - }, - "dependencies": { - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - } } }, "strip-ansi": { @@ -7518,6 +7749,23 @@ "ansi-regex": "^2.0.0" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "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 + } + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -7547,36 +7795,12 @@ "string-width": "^3.0.0" }, "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "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 - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -7610,15 +7834,6 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, - "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": { - "is-number": "^7.0.0" - } - }, "tsconfig-paths": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", @@ -7699,21 +7914,6 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -7727,55 +7927,111 @@ "dev": true }, "workerpool": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", "dev": true }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "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": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "color-name": "~1.1.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 + }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.1" + } + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@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": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "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 + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.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 + }, + "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, + "requires": { + "ansi-regex": "^5.0.1" } } } @@ -7808,9 +8064,9 @@ "dev": true }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { @@ -7820,103 +8076,25 @@ "dev": true }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "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 - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "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 }, "yargs-unparser": { "version": "2.0.0", diff --git a/package.json b/package.json index 600a9a5..a9a9247 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "2.1.4", + "version": "3.0.2", "name": "@httptoolkit/httpsnippet", "description": "HTTP request snippet generator for *most* languages", "author": "Tim Perry ", @@ -38,7 +38,7 @@ "xmlhttprequest" ], "engines": { - "node": ">=10" + "node": ">=22" }, "files": [ "bin", @@ -72,7 +72,7 @@ "echint": "^4.0.2", "glob": "^6.0.1", "istanbul": "^0.4.0", - "mocha": "^8.2.1", + "mocha": "^11.7.5", "require-directory": "^2.1.1", "should": "^13.2.3", "standard": "^16.0.3" @@ -82,7 +82,7 @@ "commander": "^2.9.0", "debug": "^2.2.0", "event-stream": "3.3.4", - "form-data": "3.0.0", + "form-data": "3.0.4", "fs-readfile-promise": "^2.0.1", "fs-writefile-promise": "^1.0.3", "har-validator": "^5.0.0" diff --git a/src/helpers/code-builder.js b/src/helpers/code-builder.js index 62a8f21..245f3d7 100644 --- a/src/helpers/code-builder.js +++ b/src/helpers/code-builder.js @@ -93,6 +93,18 @@ CodeBuilder.prototype.blank = function () { return this } +/** + * Add the line to the end of the last line. Creates a new line + * if no lines exist yet. + */ +CodeBuilder.prototype.pushToLast = function (line) { + if (!this.code) { + this.push(line) + } + const updatedLine = `${this.code[this.code.length - 1]}${line}` + this.code[this.code.length - 1] = updatedLine +} + /** * Concatenate all current lines using the given lineJoin * @return {string} diff --git a/src/index.js b/src/index.js index c8ebfc8..0801c78 100644 --- a/src/index.js +++ b/src/index.js @@ -34,12 +34,12 @@ const HTTPSnippet = function (data) { entries.forEach(function (entry) { // add optional properties to make validation successful - entry.request.httpVersion = entry.request.httpVersion || 'HTTP/1.1' - entry.request.queryString = entry.request.queryString || [] - entry.request.headers = entry.request.headers || [] - entry.request.cookies = entry.request.cookies || [] - entry.request.postData = entry.request.postData || {} - entry.request.postData.mimeType = entry.request.postData.mimeType || 'application/octet-stream' + entry.request.httpVersion ||= 'HTTP/1.1' + entry.request.queryString ||= [] + entry.request.headers ||= [] + entry.request.cookies ||= [] + entry.request.postData ||= {} + entry.request.postData.mimeType ||= 'application/octet-stream' entry.request.bodySize = 0 entry.request.headersSize = 0 @@ -168,13 +168,21 @@ HTTPSnippet.prototype.prepare = function (request) { request.postData.boundary = boundary - // Since headers are case-sensitive we need to see if there's an existing `Content-Type` header that we can - // override. - const contentTypeHeader = helpers.hasHeader(request.headersObj, 'content-type') - ? helpers.getHeaderName(request.headersObj, 'content-type') - : 'content-type' + const multipartContentType = 'multipart/form-data; boundary=' + boundary - request.headersObj[contentTypeHeader] = 'multipart/form-data; boundary=' + boundary + // We need to update the various header states to match the CT to our boundary: + if (helpers.hasHeader(request.headersObj, 'content-type')) { + // Since headers are case-sensitive we need to see if there's an existing `Content-Type` + // header that we can override. + const contentTypeHeader = helpers.getHeaderName(request.headersObj, 'content-type') + request.headersObj[contentTypeHeader] = multipartContentType + + const headerEntry = request.headers.findLast(h => h.name.toLowerCase() === 'content-type') + headerEntry.value = multipartContentType + } else { + request.headersObj['Content-Type'] = multipartContentType + request.headers.push({ name: 'Content-Type', value: multipartContentType }) + } } break @@ -216,23 +224,37 @@ HTTPSnippet.prototype.prepare = function (request) { // eslint-disable-next-line node/no-deprecated-api request.uriObj = url.parse(request.url, true, true) - // merge all possible queryString values - request.queryObj = Object.assign(request.queryObj, request.uriObj.query) + // In some cases (unparseable/partially parseable query string) we want to fully preserve the + // original string (as it may not follow qs conventions at all). We assume any scenario where + // qs cannot reproduce the original value is this case. + const simpleQueryString = !request.uriObj.search || + (qs.stringify(request.uriObj.query) === request.uriObj.search.slice(1)) - // reset uriObj values for a clean url - request.uriObj.query = null - request.uriObj.search = null - request.uriObj.path = request.uriObj.pathname + if (simpleQueryString) { + // merge all possible queryString values + request.queryObj = Object.assign(request.queryObj, request.uriObj.query) - // keep the base url clean of queryString - request.url = url.format(request.uriObj) + // reset uriObj values for a clean url + request.uriObj.query = null + request.uriObj.search = null + request.uriObj.path = request.uriObj.pathname - // update the uri object - request.uriObj.query = request.queryObj - request.uriObj.search = qs.stringify(request.queryObj) + // keep the base url clean of queryString + request.url = url.format(request.uriObj) - if (request.uriObj.search) { - request.uriObj.path = request.uriObj.pathname + '?' + request.uriObj.search + // update the uri object + request.uriObj.query = request.queryObj + request.uriObj.search = qs.stringify(request.queryObj) + + if (request.uriObj.search) { + request.uriObj.path = request.uriObj.pathname + '?' + request.uriObj.search + } + } else { + // We keep the queryString in request.url (so it's sent raw everywhere) but disable it + // elsewhere, so it's omitted from automatic code generation cases. + // request.fullUrl is recreated below (maybe mild fixed?) but preserves raw search etc + request.queryString = [] + request.queryObj = {} } // construct a full url diff --git a/src/targets/crystal/index.js b/src/targets/crystal/index.js new file mode 100644 index 0000000..b1f84a2 --- /dev/null +++ b/src/targets/crystal/index.js @@ -0,0 +1,12 @@ +'use strict' + +module.exports = { + info: { + key: 'crystal', + title: 'Crystal', + extname: '.cr', + default: 'native' + }, + + native: require('./native') +} diff --git a/src/targets/crystal/native.js b/src/targets/crystal/native.js new file mode 100644 index 0000000..c284baa --- /dev/null +++ b/src/targets/crystal/native.js @@ -0,0 +1,68 @@ +/** + * @description + * HTTP code snippet generator for native Crystal + * + * @author + * @yanecc + * + * for any questions or issues regarding the generated code snippet, please open an issue mentioning the author. + */ + +const CodeBuilder = require('../../helpers/code-builder') + +const { escape } = require('../../helpers/format') + +module.exports = function ({ method: rawMethod, fullUrl, postData, allHeaders }, options = {}) { + const { insecureSkipVerify = false } = options + + const code = new CodeBuilder() + + code.push('require "http/client"') + + code.blank() + + code.push(`url = "${fullUrl}"`) + + const headers = Object.keys(allHeaders) + if (headers.length) { + code.push('headers = HTTP::Headers{') + headers.forEach(key => { + code.push(` "${key}" => "${escape(allHeaders[key])}"`) + }) + code.push('}') + } + + if (postData.text) { + code.push(`reqBody = ${JSON.stringify(postData.text)}`) + } + + code.blank() + + const method = rawMethod.toUpperCase() + const methods = ['GET', 'POST', 'HEAD', 'DELETE', 'PATCH', 'PUT', 'OPTIONS'] + + const headersContext = headers.length ? ', headers: headers' : '' + const bodyContext = postData.text ? ', body: reqBody' : '' + const sslContext = insecureSkipVerify ? ', tls: OpenSSL::SSL::Context::Client.insecure' : '' + + if (methods.includes(method)) { + code.push( + `response = HTTP::Client.${method.toLowerCase()} url${headersContext}${bodyContext}${sslContext}` + ) + } else { + code.push( + `response = HTTP::Client.exec "${method}", url${headersContext}${bodyContext}${sslContext}` + ) + } + + code.push('puts response.body') + + return code.join() +} + +module.exports.info = { + key: 'native', + title: 'http::client', + link: 'https://crystal-lang.org/api/master/HTTP/Client.html', + description: 'Crystal HTTP client' +} diff --git a/src/targets/csharp/restsharp.js b/src/targets/csharp/restsharp.js index 373f996..63a4df1 100644 --- a/src/targets/csharp/restsharp.js +++ b/src/targets/csharp/restsharp.js @@ -1,17 +1,25 @@ 'use strict' const CodeBuilder = require('../../helpers/code-builder') +const { escape } = require('../../helpers/format') const helpers = require('../../helpers/headers') module.exports = function (source, options) { const code = new CodeBuilder() const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] + function toPascalCase (str) { + return str.replace( + /\w+/g, + word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() + ) + } + if (methods.indexOf(source.method.toUpperCase()) === -1) { return 'Method not supported' } else { - code.push('var client = new RestClient("%s");', source.fullUrl) - code.push('var request = new RestRequest(Method.%s);', source.method.toUpperCase()) + code.push('var client = new RestClient("%s//%s");', source.uriObj.protocol, source.uriObj.host) + code.push('var request = new RestRequest("%s", Method.%s);', escape(source.uriObj.path), toPascalCase(source.method)) } // Add headers, including the cookies @@ -32,14 +40,16 @@ module.exports = function (source, options) { } if (source.postData.text) { + const contentTypeHeader = helpers.getHeader(source.allHeaders, 'content-type') + code.push( - 'request.AddParameter("%s", %s, ParameterType.RequestBody);', - helpers.getHeader(source.allHeaders, 'content-type'), + 'request.AddParameter(%s, %s, ParameterType.RequestBody);', + contentTypeHeader ? `"${escape(contentTypeHeader)}"` : 'null', JSON.stringify(source.postData.text) ) } - code.push('IRestResponse response = client.Execute(request);') + code.push('var response = client.Execute(request);') return code.join() } diff --git a/src/targets/http/http1.1.js b/src/targets/http/http1.1.js index 58b5918..4a391c2 100644 --- a/src/targets/http/http1.1.js +++ b/src/targets/http/http1.1.js @@ -43,21 +43,27 @@ module.exports = function (source, options) { code.push('%s %s %s', source.method, requestUrl, source.httpVersion) // RFC 7231 Section 5. Header Fields - Object.keys(source.allHeaders).forEach(function (key) { - // Capitalize header keys, even though it's not required by the spec. - const keyCapitalized = key.toLowerCase().replace(/(^|-)(\w)/g, function (x) { - return x.toUpperCase() - }) - + source.headers.forEach((header) => { code.push( '%s', - util.format('%s: %s', keyCapitalized, source.allHeaders[key]) + util.format('%s: %s', header.name, header.value) ) }) + // Unlike most other snippets, we use the fully raw input here (not headerObj/allHeaders) + // so we need to hook into the prepare() cookie injection logic: + if (source.allHeaders.cookie && !source.headers.find(h => h.name.toLowerCase() === 'cookie')) { + code.push( + '%s', + util.format('%s: %s', 'Cookie', source.allHeaders.cookie) + ) + } + + const headerKeys = Object.keys(source.allHeaders).map(k => k.toLowerCase()) + // RFC 7230 Section 5.4. Host // Automatically set Host header if option is on and on header already exists. - if (opts.autoHost && Object.keys(source.allHeaders).indexOf('host') === -1) { + if (opts.autoHost && headerKeys.indexOf('host') === -1) { code.push('Host: %s', source.uriObj.host) } @@ -66,7 +72,7 @@ module.exports = function (source, options) { if ( opts.autoContentLength && source.postData.text && - Object.keys(source.allHeaders).indexOf('content-length') === -1 + headerKeys.indexOf('conteTnt-length') === -1 ) { code.push( 'Content-Length: %d', diff --git a/src/targets/index.js b/src/targets/index.js index dd90b48..9687e9d 100644 --- a/src/targets/index.js +++ b/src/targets/index.js @@ -3,6 +3,7 @@ module.exports = { c: require('./c'), clojure: require('./clojure'), + crystal: require('./crystal'), csharp: require('./csharp'), go: require('./go'), http: require('./http'), @@ -17,6 +18,7 @@ module.exports = { python: require('./python'), r: require('./r'), ruby: require('./ruby'), + rust: require('./rust'), shell: require('./shell'), swift: require('./swift') } diff --git a/src/targets/java/index.js b/src/targets/java/index.js index 37b0db7..ca0b259 100644 --- a/src/targets/java/index.js +++ b/src/targets/java/index.js @@ -11,5 +11,6 @@ module.exports = { okhttp: require('./okhttp'), unirest: require('./unirest'), asynchttp: require('./asynchttp'), - nethttp: require('./nethttp') + nethttp: require('./nethttp'), + restclient: require('./restclient') } diff --git a/src/targets/java/restclient.js b/src/targets/java/restclient.js new file mode 100644 index 0000000..a4fbeb5 --- /dev/null +++ b/src/targets/java/restclient.js @@ -0,0 +1,184 @@ +/** + * @description + * HTTP code snippet generator for Java using Spring RestClient. + * + * @author + * @jamezrin + * + * for any questions or issues regarding the generated code snippet, please open an issue mentioning the author. + */ + +'use strict' + +const CodeBuilder = require('../../helpers/code-builder') + +const standardMethods = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'TRACE'] + +const standardMediaTypes = { + 'application/atom+xml': 'APPLICATION_ATOM_XML', + 'application/cbor': 'APPLICATION_CBOR', + 'application/x-www-form-urlencoded': 'APPLICATION_FORM_URLENCODED', + 'application/graphql-response+json': 'APPLICATION_GRAPHQL_RESPONSE', + 'application/json': 'APPLICATION_JSON', + 'application/x-ndjson': 'APPLICATION_NDJSON', + 'application/octet-stream': 'APPLICATION_OCTET_STREAM', + 'application/pdf': 'APPLICATION_PDF', + 'application/problem+json': 'APPLICATION_PROBLEM_JSON', + 'application/problem+xml': 'APPLICATION_PROBLEM_XML', + 'application/x-protobuf': 'APPLICATION_PROTOBUF', + 'application/rss+xml': 'APPLICATION_RSS_XML', + 'application/xhtml+xml': 'APPLICATION_XHTML_XML', + 'application/xml': 'APPLICATION_XML', + 'application/yaml': 'APPLICATION_YAML', + 'image/gif': 'IMAGE_GIF', + 'image/jpeg': 'IMAGE_JPEG', + 'image/png': 'IMAGE_PNG', + 'multipart/form-data': 'MULTIPART_FORM_DATA', + 'multipart/mixed': 'MULTIPART_MIXED', + 'multipart/related': 'MULTIPART_RELATED', + 'text/event-stream': 'TEXT_EVENT_STREAM', + 'text/html': 'TEXT_HTML', + 'text/markdown': 'TEXT_MARKDOWN', + 'text/plain': 'TEXT_PLAIN', + 'text/xml': 'TEXT_XML' +} + +const multipartMimeTypes = [ + 'multipart/form-data', + 'multipart/mixed', + 'multipart/related', + 'multipart/alternative' +] + +module.exports = function (source, options) { + const opts = Object.assign({ + indent: ' ', + entityType: 'String' + }, options) + + const state = { + bodyType: null + } + + const code = new CodeBuilder(opts.indent) + + code.push('RestClient restClient = RestClient.create();') + .blank() + + if (source.postData) { + if (source.postData.params && source.postData.mimeType === 'application/x-www-form-urlencoded') { + state.bodyType = 'form' + + code.push('MultiValueMap formDataMap = new LinkedMultiValueMap<>();') + + source.postData.params.forEach(function (param) { + code.push('formDataMap.add("%qd", "%qd");', param.name, param.value) + }) + + code.blank() + } else if (source.postData.params && multipartMimeTypes.includes(source.postData.mimeType)) { + state.bodyType = 'multipart' + + code.push('MultipartBodyBuilder multipartBuilder = new MultipartBodyBuilder();') + + source.postData.params.forEach(function (param) { + if (param.fileName) { + if (param.value) { + code.push('multipartBuilder.part("%s", "%qd")', param.name, param.value) + code.push(1, '.filename("%s")', param.fileName) + } else { + code.push('multipartBuilder.part("%s", new FileSystemResource("%s"))', param.name, param.fileName) + } + + if (param.contentType) { + const mediaTypeConstant = standardMediaTypes[param.contentType] + if (mediaTypeConstant) { + code.push(1, '.contentType(MediaType.%s);', mediaTypeConstant) + } else { + code.push(1, '.contentType(MediaType.parseMediaType("%s"));', param.contentType) + } + } else { + code.push(1, ';') + } + } else { + code.push('multipartBuilder.part("%s", "%qd");', param.name, param.value || '') + } + }) + + code.blank() + } else if (source.postData.text) { + state.bodyType = 'plaintext' + } + } + + code.push('ResponseEntity<%s> response = restClient', opts.entityType) + + if (standardMethods.includes(source.method.toUpperCase())) { + code.push(1, '.method(HttpMethod.%s)', source.method.toUpperCase()) + } else { + code.push(1, '.method(HttpMethod.valueOf("%s"))', source.method.toUpperCase()) + } + + if (Object.keys(source.queryObj).length) { + code.push(1, '.uri("%s", uriBuilder -> {', source.url) + + Object.keys(source.queryObj).forEach(function (key) { + const value = source.queryObj[key] + const iterable = Array.isArray(value) ? value : [value] + iterable.forEach(function (val) { + code.push(2, 'uriBuilder.queryParam("%qd", "%qd");', key, val) + }) + }) + + code.push(2, 'return uriBuilder.build();') + code.push(1, '})') + } else { + code.push(1, '.uri("%s")', source.url) + } + + if (source.cookies && source.cookies.length) { + source.cookies.forEach(function (cookie) { + code.push(1, '.cookie("%qd", "%qd")', cookie.name, cookie.value) + }) + } + + const headers = Object.keys(source.headersObj) + if (headers.length) { + headers.forEach(function (key) { + if (key.toLowerCase() !== 'content-type') { + code.push(1, '.header("%s", "%qd")', key, source.headersObj[key]) + } + }) + } + + if (source.postData && state.bodyType) { + if (source.postData.mimeType) { + const mediaTypeEnumConstant = standardMediaTypes[source.postData.mimeType] + if (mediaTypeEnumConstant) { + code.push(1, '.contentType(MediaType.%s)', mediaTypeEnumConstant) + } else { + code.push(1, '.contentType(MediaType.parseMediaType("%s"))', source.postData.mimeType) + } + } + + if (state.bodyType === 'form') { + code.push(1, '.body(formDataMap)') + } else if (state.bodyType === 'multipart') { + code.push(1, '.body(multipartBuilder.build())') + } else if (state.bodyType === 'plaintext') { + code.push(1, '.body("%qd")', source.postData.text) + } + } + + code.push(1, '.retrieve()') + code.push(1, '.toEntity(%s.class);', opts.entityType) + + return code.join() +} + +module.exports.info = { + key: 'restclient', + title: 'Spring RestClient', + link: 'https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestClient.html', + description: 'Spring Framework REST client' +} diff --git a/src/targets/php/curl.js b/src/targets/php/curl.js index 50a2e0f..37a5d82 100644 --- a/src/targets/php/curl.js +++ b/src/targets/php/curl.js @@ -12,6 +12,7 @@ const { format } = require('../../helpers/format') const CodeBuilder = require('../../helpers/code-builder') +const { phpSqEscape } = require('./helpers') module.exports = function (source, options) { const opts = Object.assign({ @@ -78,7 +79,16 @@ module.exports = function (source, options) { curlOptions.forEach(function (option) { if (!~[null, undefined].indexOf(option.value)) { - curlopts.push(format('%s => %s,', option.name, option.escape ? JSON.stringify(option.value) : option.value)) + curlopts.push( + format('%s => %s,', + option.name, + option.escape && typeof option.value === 'string' + ? `'${phpSqEscape(option.value)}'` + : option.escape + ? JSON.stringify(option.value) + : option.value + ) + ) } }) @@ -88,12 +98,12 @@ module.exports = function (source, options) { }) if (cookies.length) { - curlopts.push(format('CURLOPT_COOKIE => "%s",', cookies.join('; '))) + curlopts.push(format("CURLOPT_COOKIE => '%s'", phpSqEscape(cookies.join('; ')))) } // construct cookies const headers = Object.keys(source.headersObj).sort().map(function (key) { - return format('"%s: %qd"', key, source.headersObj[key]) + return format("'%s: %s'", phpSqEscape(key), phpSqEscape(source.headersObj[key])) }) if (headers.length) { @@ -113,9 +123,9 @@ module.exports = function (source, options) { .push('if ($err) {') if (opts.namedErrors) { - code.push(1, 'echo array_flip(get_defined_constants(true)["curl"])[$err];') + code.push(1, "echo array_flip(get_defined_constants(true)['curl'])[$err];") } else { - code.push(1, 'echo "cURL Error #:" . $err;') + code.push(1, "echo 'cURL Error #:' . $err;") } code.push('} else {') diff --git a/src/targets/php/helpers.js b/src/targets/php/helpers.js index 0e833fa..c1dffd0 100644 --- a/src/targets/php/helpers.js +++ b/src/targets/php/helpers.js @@ -1,6 +1,7 @@ 'use strict' -const { escape } = require('../../helpers/format') +// PHP single quotes are super simple - all escapes ignored except sq & slash +const phpSqEscape = val => val.replace(/\\/g, '\\\\').replace(/'/g, "\\'") const convert = function (obj, indent, lastIndent) { let i, result @@ -19,7 +20,7 @@ const convert = function (obj, indent, lastIndent) { break case '[object String]': - result = "'" + escape(obj, { delimiter: "'", escapeNewlines: false }) + "'" + result = "'" + phpSqEscape(obj) + "'" break case '[object Number]': @@ -55,6 +56,7 @@ const convert = function (obj, indent, lastIndent) { } module.exports = { + phpSqEscape: phpSqEscape, convert: convert, methods: [ 'ACL', diff --git a/src/targets/powershell/common.js b/src/targets/powershell/common.js index aa5497e..9254300 100644 --- a/src/targets/powershell/common.js +++ b/src/targets/powershell/common.js @@ -14,11 +14,19 @@ const psSqEscape = function (input) { module.exports = function (command) { return function (source, options) { const code = new CodeBuilder() - const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] - - if (methods.indexOf(source.method.toUpperCase()) === -1) { - return 'Method not supported' - } + const methods = [ + 'DEFAULT', + 'DELETE', + 'GET', + 'HEAD', + 'MERGE', + 'OPTIONS', + 'PATCH', + 'POST', + 'PUT', + 'TRACE' + ] + const methodArg = methods.includes(source.method.toUpperCase()) ? '-Method' : '-CustomMethod' const commandOptions = [] @@ -66,9 +74,10 @@ module.exports = function (command) { ) } - code.push("$response = %s -Uri '%s' -Method %s %s", + code.push("$response = %s -Uri '%s' %s %s %s", command, psSqEscape(source.fullUrl), + methodArg, source.method, commandOptions.join(' ') ) diff --git a/src/targets/r/httr.js b/src/targets/r/httr.js index 11ba99a..0b815a6 100644 --- a/src/targets/r/httr.js +++ b/src/targets/r/httr.js @@ -106,7 +106,12 @@ module.exports = function (source, options) { const otherHeaders = Object.entries(source.allHeaders) // These headers are all handled separately: .filter(([key]) => !['cookie', 'accept', 'content-type'].includes(key.toLowerCase())) - .map(([key, value]) => `${key.replace(/-/g, '_')} = '${escape(value, { delimiter: "'" })}'`) + .map(([key, value]) => { + const safeKey = key.match(/^[a-zA-Z][a-zA-Z0-9_.-]*$/) + ? key.replace(/-/g, '_') + : '"' + escape(key) + '"' + return `${safeKey} = '${escape(value, { delimiter: "'" })}'` + }) .join(', ') const setHeaders = otherHeaders diff --git a/src/targets/ruby/faraday.js b/src/targets/ruby/faraday.js new file mode 100644 index 0000000..87657ea --- /dev/null +++ b/src/targets/ruby/faraday.js @@ -0,0 +1,104 @@ +const CodeBuilder = require('../../helpers/code-builder') + +module.exports = ({ uriObj, queryObj, method: rawMethod, postData, allHeaders }) => { + const code = new CodeBuilder() + + // To support custom methods we check for the supported methods + // and if doesn't exist then we build a custom class for it + const method = rawMethod.toUpperCase() + const methods = [ + 'GET', + 'POST', + 'HEAD', + 'DELETE', + 'PATCH', + 'PUT', + 'OPTIONS', + 'COPY', + 'LOCK', + 'UNLOCK', + 'MOVE', + 'TRACE' + ] + + if (!methods.includes(method)) { + code.push(`# Faraday cannot currently run ${method} requests. Please use another client.`) + return code.join() + } + + code.push("require 'faraday'") + code.blank() + + // Write body to beginning of script + if (postData.mimeType === 'application/x-www-form-urlencoded') { + if (postData.params) { + code.push('data = {') + postData.params.forEach(param => { + code.push(` :${param.name} => ${JSON.stringify(param.value)},`) + }) + code.push('}') + code.blank() + } + } + + code.push('conn = Faraday.new(') + code.push(` url: '${uriObj.protocol}//${uriObj.host}',`) + if (allHeaders['content-type'] || allHeaders['Content-Type']) { + code.push(` headers: {'Content-Type' => '${allHeaders['content-type'] || allHeaders['Content-Type']}'}`) + } + code.push(')') + + code.blank() + code.push(`response = conn.${method.toLowerCase()}('${uriObj.pathname}') do |req|`) + + const headers = Object.keys(allHeaders) + if (headers.length) { + headers.forEach(key => { + if (key.toLowerCase() !== 'content-type') { + code.push(" req.headers['%qs'] = '%qs'", key, allHeaders[key]) + } + }) + } + + Object.keys(queryObj).forEach(name => { + const value = queryObj[name] + if (Array.isArray(value)) { + code.push(` req.params['%qs'] = ${JSON.stringify(value)}`, name) + } else { + code.push(" req.params['%qs'] = '%qs'", name, value) + } + }) + + switch (postData.mimeType) { + case 'application/x-www-form-urlencoded': + if (postData.params) { + code.push(' req.body = URI.encode_www_form(data)') + } + break + + case 'application/json': + if (postData.jsonObj) { + code.push(` req.body = ${JSON.stringify(postData.text)}`) + } + break + + default: + if (postData.text) { + code.push(` req.body = ${JSON.stringify(postData.text)}`) + } + } + + code.push('end') + code.blank() + code.push('puts response.status') + code.push('puts response.body') + + return code.join() +} + +module.exports.info = { + key: 'faraday', + title: 'faraday', + link: 'https://github.com/lostisland/faraday', + description: 'Faraday HTTP client' +} diff --git a/src/targets/ruby/index.js b/src/targets/ruby/index.js index 1118a1b..184399b 100644 --- a/src/targets/ruby/index.js +++ b/src/targets/ruby/index.js @@ -8,5 +8,6 @@ module.exports = { default: 'native' }, - native: require('./native') + native: require('./native'), + faraday: require('./faraday') } diff --git a/src/targets/rust/helpers.js b/src/targets/rust/helpers.js new file mode 100644 index 0000000..bddf6c1 --- /dev/null +++ b/src/targets/rust/helpers.js @@ -0,0 +1,93 @@ +'use strict' + +const util = require('util') + +function concatValues ( + concatType, + values, + pretty, + indentation, + indentLevel +) { + const currentIndent = indentation.repeat(indentLevel) + const closingBraceIndent = indentation.repeat(indentLevel - 1) + const join = pretty ? `,\n${currentIndent}` : ', ' + const openingBrace = concatType === 'object' ? 'json!({' : '(' + const closingBrace = concatType === 'object' ? '})' : ')' + + if (pretty) { + return `${openingBrace}\n${currentIndent}${values.join( + join + )}\n${closingBraceIndent}${closingBrace}` + } + + return `${openingBrace}${values.join(join)}${closingBrace}` +} + +/** + * Create a valid Rust string of a literal value using serde_json according to its type. + * + * @param {*} value Any Javascript literal + * @param {Object} opts Target options + * @return {string} + */ +exports.literalRepresentation = ( + value, + opts, + indentLevel +) => { + /* + * Note: this version is almost entirely borrowed from the Python client helper. The + * only real modification involves the braces and the types. The helper + * could potentially be parameterised for reuse. + */ + indentLevel = indentLevel === undefined ? 1 : indentLevel + 1 + + switch (Object.prototype.toString.call(value)) { + case '[object Number]': + return value + + case '[object Array]': { + let pretty = false + const valuesRep = value.map(v => { + // Switch to prettify if the value is a dict with more than one key. + if (Object.prototype.toString.call(v) === '[object Object]') { + pretty = Object.keys(v).length > 1 + } + return exports.literalRepresentation(v, opts, indentLevel) + }) + return concatValues('array', valuesRep, pretty, opts.indent, indentLevel) + } + + case '[object Object]': { + const keyValuePairs = [] + for (const k in value) { + keyValuePairs.push( + util.format('%s: %s', + exports.literalRepresentation(k, opts, indentLevel), + exports.literalRepresentation(value[k], opts, indentLevel) + ) + ) + } + return concatValues( + 'object', + keyValuePairs, + opts.pretty && keyValuePairs.length > 1, + opts.indent, + indentLevel + ) + } + + case '[object Null]': + return 'json!(null)' + + case '[object Boolean]': + return value ? 'true' : 'false' + + default: + if (value === null || value === undefined) { + return '' + } + return JSON.stringify(value) + } +} diff --git a/src/targets/rust/index.js b/src/targets/rust/index.js new file mode 100644 index 0000000..011dadf --- /dev/null +++ b/src/targets/rust/index.js @@ -0,0 +1,12 @@ +'use strict' + +module.exports = { + info: { + key: 'rust', + title: 'Rust', + extname: '.rs', + default: 'reqwest' + }, + + reqwest: require('./reqwest') +} diff --git a/src/targets/rust/reqwest.js b/src/targets/rust/reqwest.js new file mode 100644 index 0000000..e381015 --- /dev/null +++ b/src/targets/rust/reqwest.js @@ -0,0 +1,238 @@ +/** + * @description + * HTTP code snippet generator for Rust using reqwest + * + * @author + * @Benjscho + * + * for any questions or issues regarding the generated code snippet, please open an issue mentioning the author. + */ + +const CodeBuilder = require('../../helpers/code-builder') +const { escape } = require('../../helpers/format') +const { literalRepresentation } = require('./helpers') + +module.exports = ({ queryObj, url, postData, allHeaders, method }, options) => { + const opts = { + indent: ' ', + pretty: true, + ...options + } + + let indentLevel = 0 + + // start snippet + const code = new CodeBuilder(opts.indent) + + // import reqwest + code.push(indentLevel, 'use reqwest;') + code.blank() + + // start async main for tokio + code.push(indentLevel, '#[tokio::main]') + code.push(indentLevel, 'pub async fn main() {') + indentLevel += 1 + + // add url + code.push(indentLevel, `let url = "${url}";`) + code.blank() + + let hasQuery = false + // construct query string + if (Object.keys(queryObj).length) { + hasQuery = true + code.push(indentLevel, 'let querystring = [') + indentLevel += 1 + for (const [key, value] of Object.entries(queryObj)) { + code.push(indentLevel, `("${escape(key)}", "${escape(value)}"),`) + } + indentLevel -= 1 + code.push(indentLevel, '];') + code.blank() + } + + // construct payload + let payload = {} + const files = {} + + let hasFiles = false + let hasForm = false + let hasBody = false + let jsonPayload = false + let isMultipart = false + switch (postData.mimeType) { + case 'application/json': + if (postData.jsonObj) { + code.push( + indentLevel, + `let payload = ${literalRepresentation(postData.jsonObj, opts, indentLevel)};` + ) + } + jsonPayload = true + break + + case 'multipart/form-data': + isMultipart = true + + if (!postData.params) { + code.push(indentLevel, 'let form = reqwest::multipart::Form::new()') + code.push(indentLevel + 1, '.text("", "");') + break + } + + payload = {} + postData.params.forEach(p => { + if (p.fileName) { + files[p.name] = p.fileName + hasFiles = true + } else { + payload[p.name] = p.value + } + }) + + if (hasFiles) { + for (const line of fileToPartString) { + code.push(indentLevel, line) + } + code.blank() + } + code.push(indentLevel, 'let form = reqwest::multipart::Form::new()') + + for (const [name, fileName] of Object.entries(files)) { + code.push(indentLevel + 1, `.part("${name}", file_to_part("${fileName}").await)`) + } + for (const [name, value] of Object.entries(payload)) { + code.push(indentLevel + 1, `.text("${name}", "${value}")`) + } + code.pushToLast(';') + + break + + default: { + if (postData.mimeType === 'application/x-www-form-urlencoded' && postData.paramsObj) { + code.push( + indentLevel, + `let payload = ${literalRepresentation(postData.paramsObj, opts, indentLevel)};` + ) + hasForm = true + break + } + + if (postData.text) { + code.push( + indentLevel, + `let payload = ${literalRepresentation(postData.text, opts, indentLevel)};` + ) + hasBody = true + break + } + } + } + + if (hasForm || jsonPayload || hasBody) { + code.unshift('use serde_json::json;') + code.blank() + } + + let hasHeaders = false + // construct headers + if (Object.keys(allHeaders).length) { + hasHeaders = true + code.push(indentLevel, 'let mut headers = reqwest::header::HeaderMap::new();') + for (const [key, value] of Object.entries(allHeaders)) { + // Skip setting content-type if there is a file, as this header will + // cause the request to hang, and reqwest will set it for us. + if (key.toLowerCase() === 'content-type' && isMultipart) { + continue + } + code.push( + indentLevel, + `headers.insert("${escape(key)}", ${literalRepresentation(value, opts)}.parse().unwrap());` + ) + } + code.blank() + } + + // construct client + code.push(indentLevel, 'let client = reqwest::Client::new();') + + // construct query + switch (method) { + case 'POST': + code.push(indentLevel, 'let response = client.post(url)') + break + + case 'GET': + code.push(indentLevel, 'let response = client.get(url)') + break + + default: { + code.push( + indentLevel, + `let response = client.request(reqwest::Method::from_str("${method}").unwrap(), url)` + ) + code.unshift('use std::str::FromStr;') + break + } + } + + if (hasQuery) { + code.push(indentLevel + 1, '.query(&querystring)') + } + + if (isMultipart) { + code.push(indentLevel + 1, '.multipart(form)') + } + + if (hasHeaders) { + code.push(indentLevel + 1, '.headers(headers)') + } + + if (jsonPayload) { + code.push(indentLevel + 1, '.json(&payload)') + } + + if (hasForm) { + code.push(indentLevel + 1, '.form(&payload)') + } + + if (hasBody) { + code.push(indentLevel + 1, '.body(payload)') + } + + // send query + code.push(indentLevel + 1, '.send()') + code.push(indentLevel + 1, '.await;') + code.blank() + + // Print response + code.push(indentLevel, 'let results = response.unwrap()') + code.push(indentLevel + 1, '.json::()') + code.push(indentLevel + 1, '.await') + code.push(indentLevel + 1, '.unwrap();') + code.blank() + + code.push(indentLevel, 'dbg!(results);') + + code.push('}\n') + + return code.join() +} + +const fileToPartString = [ + 'async fn file_to_part(file_name: &\'static str) -> reqwest::multipart::Part {', + ' let file = tokio::fs::File::open(file_name).await.unwrap();', + ' let stream = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new());', + ' let body = reqwest::Body::wrap_stream(stream);', + ' reqwest::multipart::Part::stream(body)', + ' .file_name(file_name)', + ' .mime_str("text/plain").unwrap()', + '}' +] + +module.exports.info = { + key: 'reqwest', + title: 'reqwest', + link: 'https://docs.rs/reqwest/latest/reqwest/', + description: 'reqwest HTTP library' +} diff --git a/src/targets/shell/httpie.js b/src/targets/shell/httpie.js index 40b0338..0836ff2 100644 --- a/src/targets/shell/httpie.js +++ b/src/targets/shell/httpie.js @@ -90,7 +90,7 @@ module.exports = function (source, options) { // construct headers Object.keys(source.allHeaders).sort().forEach(function (key) { - code.push('%s:%s', key, shell.quote(source.allHeaders[key])) + code.push('%s:%s', shell.quote(key), shell.quote(source.allHeaders[key])) }) if (source.postData.mimeType === 'application/x-www-form-urlencoded') { @@ -109,7 +109,12 @@ module.exports = function (source, options) { code.unshift('http %s%s %s', flags.length ? flags.join(' ') + ' ' : '', source.method, shell.quote(opts.queryParams ? source.url : source.fullUrl)) if (raw && source.postData.text) { - code.unshift('echo %s | ', shell.quote(source.postData.text)) + if (source.postData.text.includes('\\')) { + // Printf handles escape characters more clearly & portably than echo + code.unshift("printf '%%s' %s | ", shell.quote(source.postData.text)) + } else { + code.unshift('echo %s | ', shell.quote(source.postData.text)) + } } return code.join() diff --git a/test/fixtures/available-targets.json b/test/fixtures/available-targets.json index 7ad7857..b8b2618 100644 --- a/test/fixtures/available-targets.json +++ b/test/fixtures/available-targets.json @@ -1,65 +1,129 @@ [ { - "key": "shell", - "title": "Shell", - "extname": ".sh", - "default": "curl", + "key": "c", + "title": "C", + "extname": ".c", + "default": "libcurl", "clients": [ { - "key": "curl", - "title": "cURL", - "link": "http://curl.haxx.se/", - "description": "cURL is a command line tool and library for transferring data with URL syntax" - }, + "key": "libcurl", + "title": "Libcurl", + "link": "http://curl.haxx.se/libcurl/", + "description": "Simple REST and HTTP API Client for C" + } + ] + }, + { + "key": "clojure", + "title": "Clojure", + "extname": ".clj", + "default": "clj_http", + "clients": [ { - "key": "httpie", - "title": "HTTPie", - "link": "http://httpie.org/", - "description": "a CLI, cURL-like tool for humans" + "key": "clj_http", + "title": "clj-http", + "link": "https://github.com/dakrone/clj-http", + "description": "An idiomatic clojure http client wrapping the apache client." + } + ] + }, + { + "key": "crystal", + "title": "Crystal", + "extname": ".cr", + "default": "native", + "clients": [ + { + "key": "native", + "title": "http::client", + "link": "https://crystal-lang.org/api/master/HTTP/Client.html", + "description": "Crystal HTTP client" + } + ] + }, + { + "key": "csharp", + "title": "C#", + "extname": ".cs", + "default": "restsharp", + "clients": [ + { + "key": "restsharp", + "title": "RestSharp", + "link": "http://restsharp.org/", + "description": "Simple REST and HTTP API Client for .NET" }, { - "key": "wget", - "title": "Wget", - "link": "https://www.gnu.org/software/wget/", - "description": "a free software package for retrieving files using HTTP, HTTPS" + "key": "httpclient", + "title": "HttpClient", + "link": "https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient", + "description": ".NET Standard HTTP Client" } ] }, { - "key": "node", - "title": "Node.js", - "extname": ".js", + "key": "go", + "title": "Go", + "extname": ".go", "default": "native", "clients": [ { "key": "native", - "title": "HTTP", - "link": "http://nodejs.org/api/http.html#http_http_request_options_callback", - "description": "Node.js native HTTP interface" - }, + "title": "NewRequest", + "link": "http://golang.org/pkg/net/http/#NewRequest", + "description": "Golang HTTP client request" + } + ] + }, + { + "key": "http", + "title": "HTTP", + "extname": "", + "default": "1.1", + "clients": [ { - "key": "request", - "title": "Request", - "link": "https://github.com/request/request", - "description": "Simplified HTTP request client" + "key": "1.1", + "title": "HTTP/1.1", + "link": "https://tools.ietf.org/html/rfc7230", + "description": "HTTP/1.1 request string in accordance with RFC 7230" + } + ] + }, + { + "key": "java", + "title": "Java", + "extname": ".java", + "default": "unirest", + "clients": [ + { + "key": "okhttp", + "title": "OkHttp", + "link": "http://square.github.io/okhttp/", + "description": "An HTTP Request Client Library" }, { "key": "unirest", "title": "Unirest", - "link": "http://unirest.io/nodejs.html", + "link": "http://unirest.io/java.html", "description": "Lightweight HTTP Request Client Library" }, { - "key": "axios", - "title": "Axios", - "link": "https://github.com/axios/axios", - "description": "Promise based HTTP client for the browser and node.js" + "key": "asynchttp", + "title": "AsyncHttp", + "link": "https://github.com/AsyncHttpClient/async-http-client", + "description": "Asynchronous Http and WebSocket Client library for Java" }, { - "key": "fetch", - "title": "Fetch", - "link": "https://github.com/bitinn/node-fetch", - "description": "Simplified HTTP node-fetch client" + "key": "nethttp", + "title": "java.net.http", + "link": "https://openjdk.java.net/groups/net/httpclient/intro.html", + "description": "Java Standardized HTTP Client API" + }, + { + "key": "restclient", + "title": "Spring RestClient", + "link": "https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestClient.html", + "description": "Spring Framework REST client" } ] }, @@ -95,6 +159,72 @@ } ] }, + { + "key": "kotlin", + "title": "Kotlin", + "extname": ".kt", + "default": "okhttp", + "clients": [ + { + "key": "okhttp", + "title": "OkHttp", + "link": "http://square.github.io/okhttp/", + "description": "An HTTP Request Client Library" + } + ] + }, + { + "key": "node", + "title": "Node.js", + "extname": ".js", + "default": "native", + "clients": [ + { + "key": "native", + "title": "HTTP", + "link": "http://nodejs.org/api/http.html#http_http_request_options_callback", + "description": "Node.js native HTTP interface" + }, + { + "key": "request", + "title": "Request", + "link": "https://github.com/request/request", + "description": "Simplified HTTP request client" + }, + { + "key": "unirest", + "title": "Unirest", + "link": "http://unirest.io/nodejs.html", + "description": "Lightweight HTTP Request Client Library" + }, + { + "key": "axios", + "title": "Axios", + "link": "https://github.com/axios/axios", + "description": "Promise based HTTP client for the browser and node.js" + }, + { + "key": "fetch", + "title": "Fetch", + "link": "https://github.com/bitinn/node-fetch", + "description": "Simplified HTTP node-fetch client" + } + ] + }, + { + "key": "objc", + "title": "Objective-C", + "extname": ".m", + "default": "nsurlsession", + "clients": [ + { + "key": "nsurlsession", + "title": "NSURLSession", + "link": "https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html", + "description": "Foundation's NSURLSession request" + } + ] + }, { "key": "ocaml", "title": "OCaml", @@ -135,6 +265,26 @@ } ] }, + { + "key": "powershell", + "title": "Powershell", + "extname": ".ps1", + "default": "webrequest", + "clients": [ + { + "key": "webrequest", + "title": "Invoke-WebRequest", + "link": "https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Invoke-WebRequest", + "description": "Powershell Invoke-WebRequest client" + }, + { + "key": "restmethod", + "title": "Invoke-RestMethod", + "link": "https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Invoke-RestMethod", + "description": "Powershell Invoke-RestMethod client" + } + ] + }, { "key": "python", "title": "Python", @@ -156,76 +306,16 @@ ] }, { - "key": "objc", - "title": "Objective-C", - "extname": ".m", - "default": "nsurlsession", - "clients": [ - { - "key": "nsurlsession", - "title": "NSURLSession", - "link": "https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html", - "description": "Foundation's NSURLSession request" - } - ] - }, - { - "key": "swift", - "title": "Swift", - "extname": ".swift", - "default": "nsurlsession", - "clients": [ - { - "key": "nsurlsession", - "title": "NSURLSession", - "link": "https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html", - "description": "Foundation's NSURLSession request" - } - ] - }, - { - "key": "go", - "title": "Go", - "extname": ".go", - "default": "native", - "clients": [ - { - "key": "native", - "title": "NewRequest", - "link": "http://golang.org/pkg/net/http/#NewRequest", - "description": "Golang HTTP client request" - } - ] - }, - { - "key": "java", - "title": "Java", - "extname": ".java", - "default": "unirest", + "key": "r", + "title": "R", + "extname": ".r", + "default": "httr", "clients": [ { - "key": "okhttp", - "title": "OkHttp", - "link": "http://square.github.io/okhttp/", - "description": "An HTTP Request Client Library" - }, - { - "key": "unirest", - "title": "Unirest", - "link": "http://unirest.io/java.html", - "description": "Lightweight HTTP Request Client Library" - }, - { - "key": "asynchttp", - "title": "AsyncHttp", - "link": "https://github.com/AsyncHttpClient/async-http-client", - "description": "Asynchronous Http and WebSocket Client library for Java" - }, - { - "key": "nethttp", - "title": "java.net.http", - "link": "https://openjdk.java.net/groups/net/httpclient/intro.html", - "description": "Java Standardized HTTP Client API" + "key": "httr", + "title": "httr", + "link": "https://cran.r-project.org/web/packages/httr/vignettes/quickstart.html", + "description": "httr: Tools for Working with URLs and HTTP" } ] }, @@ -240,116 +330,66 @@ "title": "net::http", "link": "http://ruby-doc.org/stdlib-2.2.1/libdoc/net/http/rdoc/Net/HTTP.html", "description": "Ruby HTTP client" - } - ] - }, - { - "key": "csharp", - "title": "C#", - "extname": ".cs", - "default": "restsharp", - "clients": [ - { - "key": "restsharp", - "title": "RestSharp", - "link": "http://restsharp.org/", - "description": "Simple REST and HTTP API Client for .NET" }, { - "key": "httpclient", - "title": "HttpClient", - "link": "https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient", - "description": ".NET Standard HTTP Client" + "key": "faraday", + "title": "faraday", + "link": "https://github.com/lostisland/faraday", + "description": "Faraday HTTP client" } ] }, { - "key": "clojure", - "title": "Clojure", - "extname": ".clj", - "default": "clj_http", + "key": "rust", + "title": "Rust", + "extname": ".rs", + "default": "reqwest", "clients": [ { - "key": "clj_http", - "title": "clj-http", - "link": "https://github.com/dakrone/clj-http", - "description": "An idiomatic clojure http client wrapping the apache client." + "key": "reqwest", + "title": "reqwest", + "link": "https://docs.rs/reqwest/latest/reqwest/", + "description": "reqwest HTTP library" } ] }, { - "key": "c", - "title": "C", - "extname": ".c", - "default": "libcurl", - "clients": [ - { - "key": "libcurl", - "title": "Libcurl", - "link": "http://curl.haxx.se/libcurl/", - "description": "Simple REST and HTTP API Client for C" - } - ] - }, - { - "key": "r", - "title": "R", - "extname": ".r", - "default": "httr", - "clients": [ - { - "key": "httr", - "title": "httr", - "link": "https://cran.r-project.org/web/packages/httr/vignettes/quickstart.html", - "description": "httr: Tools for Working with URLs and HTTP" - } - ] - }, - { - "default": "webrequest", - "extname": ".ps1", - "key": "powershell", - "title": "Powershell", + "key": "shell", + "title": "Shell", + "extname": ".sh", + "default": "curl", "clients": [ { - "description": "Powershell Invoke-WebRequest client", - "key": "webrequest", - "link": "https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Invoke-WebRequest", - "title": "Invoke-WebRequest" + "key": "curl", + "title": "cURL", + "link": "http://curl.haxx.se/", + "description": "cURL is a command line tool and library for transferring data with URL syntax" }, { - "description": "Powershell Invoke-RestMethod client", - "key": "restmethod", - "link": "https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Invoke-RestMethod", - "title": "Invoke-RestMethod" - } - ] - }, - { - "default": "1.1", - "extname": "", - "key": "http", - "title": "HTTP", - "clients": [ + "key": "httpie", + "title": "HTTPie", + "link": "http://httpie.org/", + "description": "a CLI, cURL-like tool for humans" + }, { - "description": "HTTP/1.1 request string in accordance with RFC 7230", - "key": "1.1", - "link": "https://tools.ietf.org/html/rfc7230", - "title": "HTTP/1.1" + "key": "wget", + "title": "Wget", + "link": "https://www.gnu.org/software/wget/", + "description": "a free software package for retrieving files using HTTP, HTTPS" } ] }, { - "key": "kotlin", - "title": "Kotlin", - "extname": ".kt", - "default": "okhttp", + "key": "swift", + "title": "Swift", + "extname": ".swift", + "default": "nsurlsession", "clients": [ { - "key": "okhttp", - "title": "OkHttp", - "link": "http://square.github.io/okhttp/", - "description": "An HTTP Request Client Library" + "key": "nsurlsession", + "title": "NSURLSession", + "link": "https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSURLSession_class/index.html", + "description": "Foundation's NSURLSession request" } ] } diff --git a/test/fixtures/output/c/libcurl/malicious.c b/test/fixtures/output/c/libcurl/malicious.c index 21f004d..b521db5 100644 --- a/test/fixtures/output/c/libcurl/malicious.c +++ b/test/fixtures/output/c/libcurl/malicious.c @@ -4,11 +4,16 @@ curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(hnd, CURLOPT_URL, "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C"); struct curl_slist *headers = NULL; +headers = curl_slist_append(headers, "': squote-key-test"); headers = curl_slist_append(headers, "squote-value-test: '"); headers = curl_slist_append(headers, "dquote-value-test: \""); +headers = curl_slist_append(headers, "`: backtick-key-test"); headers = curl_slist_append(headers, "backtick-value-test: `"); +headers = curl_slist_append(headers, "$: dollar-key-test"); headers = curl_slist_append(headers, "dollar-parenthesis-value-test: $("); +headers = curl_slist_append(headers, "#: hash-key-test"); headers = curl_slist_append(headers, "hash-brace-value-test: #{"); +headers = curl_slist_append(headers, "%: percent-key-test"); headers = curl_slist_append(headers, "percent-parenthesis-value-test: %("); headers = curl_slist_append(headers, "percent-brace-value-test: %{"); headers = curl_slist_append(headers, "double-brace-value-test: {{"); diff --git a/test/fixtures/output/c/libcurl/unparseable-query.c b/test/fixtures/output/c/libcurl/unparseable-query.c new file mode 100644 index 0000000..dfb694d --- /dev/null +++ b/test/fixtures/output/c/libcurl/unparseable-query.c @@ -0,0 +1,6 @@ +CURL *hnd = curl_easy_init(); + +curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET"); +curl_easy_setopt(hnd, CURLOPT_URL, "http://mockbin.com/har?&&a=b&&"); + +CURLcode ret = curl_easy_perform(hnd); \ No newline at end of file diff --git a/test/fixtures/output/clojure/clj_http/malicious.clj b/test/fixtures/output/clojure/clj_http/malicious.clj index 9c99ba8..9f74137 100644 --- a/test/fixtures/output/clojure/clj_http/malicious.clj +++ b/test/fixtures/output/clojure/clj_http/malicious.clj @@ -1,10 +1,15 @@ (require '[clj-http.client :as client]) -(client/post "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//" {:headers {:squote-value-test "'" +(client/post "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//" {:headers {"'" "squote-key-test" + :squote-value-test "'" :dquote-value-test "\"" + "`" "backtick-key-test" :backtick-value-test "`" + "$" "dollar-key-test" :dollar-parenthesis-value-test "$(" + "#" "hash-key-test" :hash-brace-value-test "#{" + "%" "percent-key-test" :percent-parenthesis-value-test "%(" :percent-brace-value-test "%{" :double-brace-value-test "{{" diff --git a/test/fixtures/output/clojure/clj_http/unparseable-query.clj b/test/fixtures/output/clojure/clj_http/unparseable-query.clj new file mode 100644 index 0000000..36fc53a --- /dev/null +++ b/test/fixtures/output/clojure/clj_http/unparseable-query.clj @@ -0,0 +1,3 @@ +(require '[clj-http.client :as client]) + +(client/get "http://mockbin.com/har?&&a=b&&") \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/application-form-encoded.cr b/test/fixtures/output/crystal/native/application-form-encoded.cr new file mode 100644 index 0000000..1a88422 --- /dev/null +++ b/test/fixtures/output/crystal/native/application-form-encoded.cr @@ -0,0 +1,10 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "content-type" => "application/x-www-form-urlencoded" +} +reqBody = "foo=bar&hello=world" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/application-json.cr b/test/fixtures/output/crystal/native/application-json.cr new file mode 100644 index 0000000..1389c2f --- /dev/null +++ b/test/fixtures/output/crystal/native/application-json.cr @@ -0,0 +1,10 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "content-type" => "application/json" +} +reqBody = "{\"number\":1,\"string\":\"f\\\"oo\",\"arr\":[1,2,3],\"nested\":{\"a\":\"b\"},\"arr_mix\":[1,\"a\",{\"arr_mix_nested\":{}}],\"boolean\":false}" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/compression.cr b/test/fixtures/output/crystal/native/compression.cr new file mode 100644 index 0000000..7658836 --- /dev/null +++ b/test/fixtures/output/crystal/native/compression.cr @@ -0,0 +1,9 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "accept-encoding" => "deflate, gzip, br" +} + +response = HTTP::Client.get url, headers: headers +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/cookies.cr b/test/fixtures/output/crystal/native/cookies.cr new file mode 100644 index 0000000..70d45c1 --- /dev/null +++ b/test/fixtures/output/crystal/native/cookies.cr @@ -0,0 +1,9 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "cookie" => "foo=bar; bar=baz" +} + +response = HTTP::Client.post url, headers: headers +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/custom-method.cr b/test/fixtures/output/crystal/native/custom-method.cr new file mode 100644 index 0000000..ee1852b --- /dev/null +++ b/test/fixtures/output/crystal/native/custom-method.cr @@ -0,0 +1,6 @@ +require "http/client" + +url = "http://mockbin.com/har" + +response = HTTP::Client.exec "PROPFIND", url +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/full.cr b/test/fixtures/output/crystal/native/full.cr new file mode 100644 index 0000000..edd8f4c --- /dev/null +++ b/test/fixtures/output/crystal/native/full.cr @@ -0,0 +1,12 @@ +require "http/client" + +url = "http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value" +headers = HTTP::Headers{ + "cookie" => "foo=bar; bar=baz" + "accept" => "application/json" + "content-type" => "application/x-www-form-urlencoded" +} +reqBody = "foo=bar" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/headers.cr b/test/fixtures/output/crystal/native/headers.cr new file mode 100644 index 0000000..1061d33 --- /dev/null +++ b/test/fixtures/output/crystal/native/headers.cr @@ -0,0 +1,11 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "accept" => "application/json" + "x-foo" => "Bar" + "quoted-value" => "\"quoted\" 'string'" +} + +response = HTTP::Client.get url, headers: headers +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/https.cr b/test/fixtures/output/crystal/native/https.cr new file mode 100644 index 0000000..c9fa4fd --- /dev/null +++ b/test/fixtures/output/crystal/native/https.cr @@ -0,0 +1,6 @@ +require "http/client" + +url = "https://mockbin.com/har" + +response = HTTP::Client.get url +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/jsonObj-multiline.cr b/test/fixtures/output/crystal/native/jsonObj-multiline.cr new file mode 100644 index 0000000..12ce719 --- /dev/null +++ b/test/fixtures/output/crystal/native/jsonObj-multiline.cr @@ -0,0 +1,10 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "content-type" => "application/json" +} +reqBody = "{\n \"foo\": \"bar\"\n}" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/jsonObj-null-value.cr b/test/fixtures/output/crystal/native/jsonObj-null-value.cr new file mode 100644 index 0000000..053961c --- /dev/null +++ b/test/fixtures/output/crystal/native/jsonObj-null-value.cr @@ -0,0 +1,10 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "content-type" => "application/json" +} +reqBody = "{\"foo\":null}" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/malicious.cr b/test/fixtures/output/crystal/native/malicious.cr new file mode 100644 index 0000000..e8374f3 --- /dev/null +++ b/test/fixtures/output/crystal/native/malicious.cr @@ -0,0 +1,25 @@ +require "http/client" + +url = "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C" +headers = HTTP::Headers{ + "'" => "squote-key-test" + "squote-value-test" => "'" + "dquote-value-test" => "\"" + "`" => "backtick-key-test" + "backtick-value-test" => "`" + "$" => "dollar-key-test" + "dollar-parenthesis-value-test" => "$(" + "#" => "hash-key-test" + "hash-brace-value-test" => "#{" + "%" => "percent-key-test" + "percent-parenthesis-value-test" => "%(" + "percent-brace-value-test" => "%{" + "double-brace-value-test" => "{{" + "null-value-test" => "\\0" + "string-fmt-value-test" => "%s" + "slash-value-test" => "\\" +} +reqBody = "' \" ` $( #{ %( %{ {{ \\0 %s \\" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/multipart-data.cr b/test/fixtures/output/crystal/native/multipart-data.cr new file mode 100644 index 0000000..96f265a --- /dev/null +++ b/test/fixtures/output/crystal/native/multipart-data.cr @@ -0,0 +1,10 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "content-type" => "multipart/form-data; boundary=---011000010111000001101001" +} +reqBody = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\nHello World\r\n-----011000010111000001101001--\r\n" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/multipart-file.cr b/test/fixtures/output/crystal/native/multipart-file.cr new file mode 100644 index 0000000..1555da8 --- /dev/null +++ b/test/fixtures/output/crystal/native/multipart-file.cr @@ -0,0 +1,10 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "content-type" => "multipart/form-data; boundary=---011000010111000001101001" +} +reqBody = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\n\r\n-----011000010111000001101001--\r\n" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/multipart-form-data.cr b/test/fixtures/output/crystal/native/multipart-form-data.cr new file mode 100644 index 0000000..d5216d7 --- /dev/null +++ b/test/fixtures/output/crystal/native/multipart-form-data.cr @@ -0,0 +1,10 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "Content-Type" => "multipart/form-data; boundary=---011000010111000001101001" +} +reqBody = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n-----011000010111000001101001--\r\n" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/nested.cr b/test/fixtures/output/crystal/native/nested.cr new file mode 100644 index 0000000..f6fbf4b --- /dev/null +++ b/test/fixtures/output/crystal/native/nested.cr @@ -0,0 +1,6 @@ +require "http/client" + +url = "http://mockbin.com/har?foo%5Bbar%5D=baz%2Czap&fiz=buz&key=value" + +response = HTTP::Client.get url +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/query.cr b/test/fixtures/output/crystal/native/query.cr new file mode 100644 index 0000000..cacc2b3 --- /dev/null +++ b/test/fixtures/output/crystal/native/query.cr @@ -0,0 +1,6 @@ +require "http/client" + +url = "http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value" + +response = HTTP::Client.get url +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/short.cr b/test/fixtures/output/crystal/native/short.cr new file mode 100644 index 0000000..0715616 --- /dev/null +++ b/test/fixtures/output/crystal/native/short.cr @@ -0,0 +1,6 @@ +require "http/client" + +url = "http://mockbin.com/har" + +response = HTTP::Client.get url +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/text-plain.cr b/test/fixtures/output/crystal/native/text-plain.cr new file mode 100644 index 0000000..8890116 --- /dev/null +++ b/test/fixtures/output/crystal/native/text-plain.cr @@ -0,0 +1,10 @@ +require "http/client" + +url = "http://mockbin.com/har" +headers = HTTP::Headers{ + "content-type" => "text/plain" +} +reqBody = "Hello World" + +response = HTTP::Client.post url, headers: headers, body: reqBody +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/crystal/native/unparseable-query.cr b/test/fixtures/output/crystal/native/unparseable-query.cr new file mode 100644 index 0000000..83b1dd7 --- /dev/null +++ b/test/fixtures/output/crystal/native/unparseable-query.cr @@ -0,0 +1,6 @@ +require "http/client" + +url = "http://mockbin.com/har?&&a=b&&" + +response = HTTP::Client.get url +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/csharp/httpclient/malicious.cs b/test/fixtures/output/csharp/httpclient/malicious.cs index b88e5e2..7524b59 100644 --- a/test/fixtures/output/csharp/httpclient/malicious.cs +++ b/test/fixtures/output/csharp/httpclient/malicious.cs @@ -5,11 +5,16 @@ RequestUri = new Uri("http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C"), Headers = { + { "'", "squote-key-test" }, { "squote-value-test", "'" }, { "dquote-value-test", "\"" }, + { "`", "backtick-key-test" }, { "backtick-value-test", "`" }, + { "$", "dollar-key-test" }, { "dollar-parenthesis-value-test", "$(" }, + { "#", "hash-key-test" }, { "hash-brace-value-test", "#{" }, + { "%", "percent-key-test" }, { "percent-parenthesis-value-test", "%(" }, { "percent-brace-value-test", "%{" }, { "double-brace-value-test", "{{" }, diff --git a/test/fixtures/output/csharp/httpclient/unparseable-query.cs b/test/fixtures/output/csharp/httpclient/unparseable-query.cs new file mode 100644 index 0000000..c0659b0 --- /dev/null +++ b/test/fixtures/output/csharp/httpclient/unparseable-query.cs @@ -0,0 +1,12 @@ +var client = new HttpClient(); +var request = new HttpRequestMessage +{ + Method = HttpMethod.Get, + RequestUri = new Uri("http://mockbin.com/har?&&a=b&&"), +}; +using (var response = await client.SendAsync(request)) +{ + response.EnsureSuccessStatusCode(); + var body = await response.Content.ReadAsStringAsync(); + Console.WriteLine(body); +} \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/application-form-encoded.cs b/test/fixtures/output/csharp/restsharp/application-form-encoded.cs index 96f3f8b..2959968 100644 --- a/test/fixtures/output/csharp/restsharp/application-form-encoded.cs +++ b/test/fixtures/output/csharp/restsharp/application-form-encoded.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddHeader("content-type", "application/x-www-form-urlencoded"); request.AddParameter("application/x-www-form-urlencoded", "foo=bar&hello=world", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/application-json.cs b/test/fixtures/output/csharp/restsharp/application-json.cs index 30a977b..5f1559b 100644 --- a/test/fixtures/output/csharp/restsharp/application-json.cs +++ b/test/fixtures/output/csharp/restsharp/application-json.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddHeader("content-type", "application/json"); request.AddParameter("application/json", "{\"number\":1,\"string\":\"f\\\"oo\",\"arr\":[1,2,3],\"nested\":{\"a\":\"b\"},\"arr_mix\":[1,\"a\",{\"arr_mix_nested\":{}}],\"boolean\":false}", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/compression.cs b/test/fixtures/output/csharp/restsharp/compression.cs index c3f7c28..f7bab10 100644 --- a/test/fixtures/output/csharp/restsharp/compression.cs +++ b/test/fixtures/output/csharp/restsharp/compression.cs @@ -1,4 +1,4 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.GET); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Get); request.AddHeader("accept-encoding", "deflate, gzip, br"); -IRestResponse response = client.Execute(request); \ No newline at end of file +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/cookies.cs b/test/fixtures/output/csharp/restsharp/cookies.cs index 910b4f5..6e4d410 100644 --- a/test/fixtures/output/csharp/restsharp/cookies.cs +++ b/test/fixtures/output/csharp/restsharp/cookies.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddCookie("foo", "bar"); request.AddCookie("bar", "baz"); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/custom-method.cs b/test/fixtures/output/csharp/restsharp/custom-method.cs index 5e5237a..8eb41a6 100644 --- a/test/fixtures/output/csharp/restsharp/custom-method.cs +++ b/test/fixtures/output/csharp/restsharp/custom-method.cs @@ -1 +1 @@ -Method not supported +Method not supported \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/full.cs b/test/fixtures/output/csharp/restsharp/full.cs index 2a326cc..6642d48 100644 --- a/test/fixtures/output/csharp/restsharp/full.cs +++ b/test/fixtures/output/csharp/restsharp/full.cs @@ -1,8 +1,8 @@ -var client = new RestClient("http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har?foo=bar&foo=baz&baz=abc&key=value", Method.Post); request.AddHeader("accept", "application/json"); request.AddHeader("content-type", "application/x-www-form-urlencoded"); request.AddCookie("foo", "bar"); request.AddCookie("bar", "baz"); request.AddParameter("application/x-www-form-urlencoded", "foo=bar", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/headers.cs b/test/fixtures/output/csharp/restsharp/headers.cs index febda66..345f140 100644 --- a/test/fixtures/output/csharp/restsharp/headers.cs +++ b/test/fixtures/output/csharp/restsharp/headers.cs @@ -1,6 +1,6 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.GET); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Get); request.AddHeader("accept", "application/json"); request.AddHeader("x-foo", "Bar"); request.AddHeader("quoted-value", "\"quoted\" 'string'"); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/https.cs b/test/fixtures/output/csharp/restsharp/https.cs index 8be49d7..97355f7 100644 --- a/test/fixtures/output/csharp/restsharp/https.cs +++ b/test/fixtures/output/csharp/restsharp/https.cs @@ -1,3 +1,3 @@ -var client = new RestClient("https://mockbin.com/har"); -var request = new RestRequest(Method.GET); -IRestResponse response = client.Execute(request); +var client = new RestClient("https://mockbin.com"); +var request = new RestRequest("/har", Method.Get); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/jsonObj-multiline.cs b/test/fixtures/output/csharp/restsharp/jsonObj-multiline.cs index 20a7577..b3062e3 100644 --- a/test/fixtures/output/csharp/restsharp/jsonObj-multiline.cs +++ b/test/fixtures/output/csharp/restsharp/jsonObj-multiline.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddHeader("content-type", "application/json"); request.AddParameter("application/json", "{\n \"foo\": \"bar\"\n}", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/jsonObj-null-value.cs b/test/fixtures/output/csharp/restsharp/jsonObj-null-value.cs index fda9215..1eb3388 100644 --- a/test/fixtures/output/csharp/restsharp/jsonObj-null-value.cs +++ b/test/fixtures/output/csharp/restsharp/jsonObj-null-value.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddHeader("content-type", "application/json"); request.AddParameter("application/json", "{\"foo\":null}", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/malicious.cs b/test/fixtures/output/csharp/restsharp/malicious.cs index 91dca32..0c80d86 100644 --- a/test/fixtures/output/csharp/restsharp/malicious.cs +++ b/test/fixtures/output/csharp/restsharp/malicious.cs @@ -1,15 +1,20 @@ -var client = new RestClient("http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://example.test"); +var request = new RestRequest("/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C", Method.Post); +request.AddHeader("'", "squote-key-test"); request.AddHeader("squote-value-test", "'"); request.AddHeader("dquote-value-test", "\""); +request.AddHeader("`", "backtick-key-test"); request.AddHeader("backtick-value-test", "`"); +request.AddHeader("$", "dollar-key-test"); request.AddHeader("dollar-parenthesis-value-test", "$("); +request.AddHeader("#", "hash-key-test"); request.AddHeader("hash-brace-value-test", "#{"); +request.AddHeader("%", "percent-key-test"); request.AddHeader("percent-parenthesis-value-test", "%("); request.AddHeader("percent-brace-value-test", "%{"); request.AddHeader("double-brace-value-test", "{{"); request.AddHeader("null-value-test", "\\0"); request.AddHeader("string-fmt-value-test", "%s"); request.AddHeader("slash-value-test", "\\"); -request.AddParameter("undefined", "' \" ` $( #{ %( %{ {{ \\0 %s \\", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); \ No newline at end of file +request.AddParameter(null, "' \" ` $( #{ %( %{ {{ \\0 %s \\", ParameterType.RequestBody); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/multipart-data.cs b/test/fixtures/output/csharp/restsharp/multipart-data.cs index 9db5bec..4d48b37 100644 --- a/test/fixtures/output/csharp/restsharp/multipart-data.cs +++ b/test/fixtures/output/csharp/restsharp/multipart-data.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001"); request.AddParameter("multipart/form-data; boundary=---011000010111000001101001", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\nHello World\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/multipart-file.cs b/test/fixtures/output/csharp/restsharp/multipart-file.cs index d91e66b..d449324 100644 --- a/test/fixtures/output/csharp/restsharp/multipart-file.cs +++ b/test/fixtures/output/csharp/restsharp/multipart-file.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001"); request.AddParameter("multipart/form-data; boundary=---011000010111000001101001", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\n\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/multipart-form-data.cs b/test/fixtures/output/csharp/restsharp/multipart-form-data.cs index aae6aa5..bae66ae 100644 --- a/test/fixtures/output/csharp/restsharp/multipart-form-data.cs +++ b/test/fixtures/output/csharp/restsharp/multipart-form-data.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddHeader("Content-Type", "multipart/form-data; boundary=---011000010111000001101001"); request.AddParameter("multipart/form-data; boundary=---011000010111000001101001", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n-----011000010111000001101001--\r\n", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/nested.cs b/test/fixtures/output/csharp/restsharp/nested.cs index fbc0fd7..ba3dc6e 100644 --- a/test/fixtures/output/csharp/restsharp/nested.cs +++ b/test/fixtures/output/csharp/restsharp/nested.cs @@ -1,3 +1,3 @@ -var client = new RestClient("http://mockbin.com/har?foo%5Bbar%5D=baz%2Czap&fiz=buz&key=value"); -var request = new RestRequest(Method.GET); -IRestResponse response = client.Execute(request); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har?foo%5Bbar%5D=baz%2Czap&fiz=buz&key=value", Method.Get); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/query.cs b/test/fixtures/output/csharp/restsharp/query.cs index 9384530..36fdee0 100644 --- a/test/fixtures/output/csharp/restsharp/query.cs +++ b/test/fixtures/output/csharp/restsharp/query.cs @@ -1,3 +1,3 @@ -var client = new RestClient("http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value"); -var request = new RestRequest(Method.GET); -IRestResponse response = client.Execute(request); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har?foo=bar&foo=baz&baz=abc&key=value", Method.Get); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/short.cs b/test/fixtures/output/csharp/restsharp/short.cs index eb5c9f5..1312efe 100644 --- a/test/fixtures/output/csharp/restsharp/short.cs +++ b/test/fixtures/output/csharp/restsharp/short.cs @@ -1,3 +1,3 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.GET); -IRestResponse response = client.Execute(request); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Get); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/text-plain.cs b/test/fixtures/output/csharp/restsharp/text-plain.cs index 958eb97..5789fa7 100644 --- a/test/fixtures/output/csharp/restsharp/text-plain.cs +++ b/test/fixtures/output/csharp/restsharp/text-plain.cs @@ -1,5 +1,5 @@ -var client = new RestClient("http://mockbin.com/har"); -var request = new RestRequest(Method.POST); +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har", Method.Post); request.AddHeader("content-type", "text/plain"); request.AddParameter("text/plain", "Hello World", ParameterType.RequestBody); -IRestResponse response = client.Execute(request); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/csharp/restsharp/unparseable-query.cs b/test/fixtures/output/csharp/restsharp/unparseable-query.cs new file mode 100644 index 0000000..2089b1b --- /dev/null +++ b/test/fixtures/output/csharp/restsharp/unparseable-query.cs @@ -0,0 +1,3 @@ +var client = new RestClient("http://mockbin.com"); +var request = new RestRequest("/har?&&a=b&&", Method.Get); +var response = client.Execute(request); \ No newline at end of file diff --git a/test/fixtures/output/go/native/malicious.go b/test/fixtures/output/go/native/malicious.go index 70c67a9..0e89205 100644 --- a/test/fixtures/output/go/native/malicious.go +++ b/test/fixtures/output/go/native/malicious.go @@ -15,11 +15,16 @@ func main() { req, _ := http.NewRequest("POST", url, payload) + req.Header.Add("'", "squote-key-test") req.Header.Add("squote-value-test", "'") req.Header.Add("dquote-value-test", "\"") + req.Header.Add("`", "backtick-key-test") req.Header.Add("backtick-value-test", "`") + req.Header.Add("$", "dollar-key-test") req.Header.Add("dollar-parenthesis-value-test", "$(") + req.Header.Add("#", "hash-key-test") req.Header.Add("hash-brace-value-test", "#{") + req.Header.Add("%", "percent-key-test") req.Header.Add("percent-parenthesis-value-test", "%(") req.Header.Add("percent-brace-value-test", "%{") req.Header.Add("double-brace-value-test", "{{") diff --git a/test/fixtures/output/go/native/unparseable-query.go b/test/fixtures/output/go/native/unparseable-query.go new file mode 100644 index 0000000..655601e --- /dev/null +++ b/test/fixtures/output/go/native/unparseable-query.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "net/http" + "io" +) + +func main() { + + url := "http://mockbin.com/har?&&a=b&&" + + req, _ := http.NewRequest("GET", url, nil) + + res, _ := http.DefaultClient.Do(req) + + defer res.Body.Close() + body, _ := io.ReadAll(res.Body) + + fmt.Println(res) + fmt.Println(string(body)) + +} \ No newline at end of file diff --git a/test/fixtures/output/http/1.1/application-form-encoded b/test/fixtures/output/http/1.1/application-form-encoded index 723d94a..a979905 100644 --- a/test/fixtures/output/http/1.1/application-form-encoded +++ b/test/fixtures/output/http/1.1/application-form-encoded @@ -1,5 +1,5 @@ POST /har HTTP/1.1 -Content-Type: application/x-www-form-urlencoded +content-type: application/x-www-form-urlencoded Host: mockbin.com Content-Length: 19 diff --git a/test/fixtures/output/http/1.1/application-json b/test/fixtures/output/http/1.1/application-json index ee65b54..ac5f1b3 100644 --- a/test/fixtures/output/http/1.1/application-json +++ b/test/fixtures/output/http/1.1/application-json @@ -1,5 +1,5 @@ POST /har HTTP/1.1 -Content-Type: application/json +content-type: application/json Host: mockbin.com Content-Length: 118 diff --git a/test/fixtures/output/http/1.1/compression b/test/fixtures/output/http/1.1/compression index 8e2f8b1..9a99d1b 100644 --- a/test/fixtures/output/http/1.1/compression +++ b/test/fixtures/output/http/1.1/compression @@ -1,3 +1,3 @@ GET /har HTTP/1.1 -Accept-Encoding: deflate, gzip, br +accept-encoding: deflate, gzip, br Host: mockbin.com \ No newline at end of file diff --git a/test/fixtures/output/http/1.1/full b/test/fixtures/output/http/1.1/full index d4d41ec..530af73 100644 --- a/test/fixtures/output/http/1.1/full +++ b/test/fixtures/output/http/1.1/full @@ -1,7 +1,7 @@ POST /har?foo=bar&foo=baz&baz=abc&key=value HTTP/1.1 +accept: application/json +content-type: application/x-www-form-urlencoded Cookie: foo=bar; bar=baz -Accept: application/json -Content-Type: application/x-www-form-urlencoded Host: mockbin.com Content-Length: 7 diff --git a/test/fixtures/output/http/1.1/headers b/test/fixtures/output/http/1.1/headers index ad12eff..171dbda 100644 --- a/test/fixtures/output/http/1.1/headers +++ b/test/fixtures/output/http/1.1/headers @@ -1,7 +1,7 @@ GET /har HTTP/1.1 -Accept: application/json -X-Foo: Bar -Quoted-Value: "quoted" 'string' +accept: application/json +x-foo: Bar +quoted-value: "quoted" 'string' Host: mockbin.com diff --git a/test/fixtures/output/http/1.1/jsonObj-multiline b/test/fixtures/output/http/1.1/jsonObj-multiline index ebc26ad..9c19277 100644 --- a/test/fixtures/output/http/1.1/jsonObj-multiline +++ b/test/fixtures/output/http/1.1/jsonObj-multiline @@ -1,5 +1,5 @@ POST /har HTTP/1.1 -Content-Type: application/json +content-type: application/json Host: mockbin.com Content-Length: 18 diff --git a/test/fixtures/output/http/1.1/jsonObj-null-value b/test/fixtures/output/http/1.1/jsonObj-null-value index 240a57b..e4c7e14 100644 --- a/test/fixtures/output/http/1.1/jsonObj-null-value +++ b/test/fixtures/output/http/1.1/jsonObj-null-value @@ -1,5 +1,5 @@ POST /har HTTP/1.1 -Content-Type: application/json +content-type: application/json Host: mockbin.com Content-Length: 12 diff --git a/test/fixtures/output/http/1.1/malicious b/test/fixtures/output/http/1.1/malicious index 114186f..8f7cbe3 100644 --- a/test/fixtures/output/http/1.1/malicious +++ b/test/fixtures/output/http/1.1/malicious @@ -1,15 +1,20 @@ POST /%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C HTTP/1.1 -Squote-Value-Test: ' -Dquote-Value-Test: " -Backtick-Value-Test: ` -Dollar-Parenthesis-Value-Test: $( -Hash-Brace-Value-Test: #{ -Percent-Parenthesis-Value-Test: %( -Percent-Brace-Value-Test: %{ -Double-Brace-Value-Test: {{ -Null-Value-Test: \0 -String-Fmt-Value-Test: %s -Slash-Value-Test: \ +': squote-key-test +squote-value-test: ' +dquote-value-test: " +`: backtick-key-test +backtick-value-test: ` +$: dollar-key-test +dollar-parenthesis-value-test: $( +#: hash-key-test +hash-brace-value-test: #{ +%: percent-key-test +percent-parenthesis-value-test: %( +percent-brace-value-test: %{ +double-brace-value-test: {{ +null-value-test: \0 +string-fmt-value-test: %s +slash-value-test: \ Host: example.test Content-Length: 28 diff --git a/test/fixtures/output/http/1.1/multipart-data b/test/fixtures/output/http/1.1/multipart-data index cbe1c5f..d0306c7 100644 --- a/test/fixtures/output/http/1.1/multipart-data +++ b/test/fixtures/output/http/1.1/multipart-data @@ -1,5 +1,5 @@ POST /har HTTP/1.1 -Content-Type: multipart/form-data; boundary=---011000010111000001101001 +content-type: multipart/form-data; boundary=---011000010111000001101001 Host: mockbin.com Content-Length: 171 diff --git a/test/fixtures/output/http/1.1/multipart-file b/test/fixtures/output/http/1.1/multipart-file index be0776f..0f8d0e0 100644 --- a/test/fixtures/output/http/1.1/multipart-file +++ b/test/fixtures/output/http/1.1/multipart-file @@ -1,5 +1,5 @@ POST /har HTTP/1.1 -Content-Type: multipart/form-data; boundary=---011000010111000001101001 +content-type: multipart/form-data; boundary=---011000010111000001101001 Host: mockbin.com Content-Length: 160 diff --git a/test/fixtures/output/http/1.1/text-plain b/test/fixtures/output/http/1.1/text-plain index c341a43..6ba9edf 100644 --- a/test/fixtures/output/http/1.1/text-plain +++ b/test/fixtures/output/http/1.1/text-plain @@ -1,5 +1,5 @@ POST /har HTTP/1.1 -Content-Type: text/plain +content-type: text/plain Host: mockbin.com Content-Length: 11 diff --git a/test/fixtures/output/http/1.1/unparseable-query b/test/fixtures/output/http/1.1/unparseable-query new file mode 100644 index 0000000..d4e4f28 --- /dev/null +++ b/test/fixtures/output/http/1.1/unparseable-query @@ -0,0 +1,2 @@ +GET /har?&&a=b&& HTTP/1.1 +Host: mockbin.com \ No newline at end of file diff --git a/test/fixtures/output/java/asynchttp/malicious.java b/test/fixtures/output/java/asynchttp/malicious.java index 7ff3d80..763dab9 100644 --- a/test/fixtures/output/java/asynchttp/malicious.java +++ b/test/fixtures/output/java/asynchttp/malicious.java @@ -1,10 +1,15 @@ AsyncHttpClient client = new DefaultAsyncHttpClient(); client.prepare("POST", "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C") + .setHeader("'", "squote-key-test") .setHeader("squote-value-test", "'") .setHeader("dquote-value-test", "\"") + .setHeader("`", "backtick-key-test") .setHeader("backtick-value-test", "`") + .setHeader("$", "dollar-key-test") .setHeader("dollar-parenthesis-value-test", "$(") + .setHeader("#", "hash-key-test") .setHeader("hash-brace-value-test", "#{") + .setHeader("%", "percent-key-test") .setHeader("percent-parenthesis-value-test", "%(") .setHeader("percent-brace-value-test", "%{") .setHeader("double-brace-value-test", "{{") diff --git a/test/fixtures/output/java/asynchttp/unparseable-query.java b/test/fixtures/output/java/asynchttp/unparseable-query.java new file mode 100644 index 0000000..c6a63b3 --- /dev/null +++ b/test/fixtures/output/java/asynchttp/unparseable-query.java @@ -0,0 +1,8 @@ +AsyncHttpClient client = new DefaultAsyncHttpClient(); +client.prepare("GET", "http://mockbin.com/har?&&a=b&&") + .execute() + .toCompletableFuture() + .thenAccept(System.out::println) + .join(); + +client.close(); \ No newline at end of file diff --git a/test/fixtures/output/java/nethttp/malicious.java b/test/fixtures/output/java/nethttp/malicious.java index cd72894..e227616 100644 --- a/test/fixtures/output/java/nethttp/malicious.java +++ b/test/fixtures/output/java/nethttp/malicious.java @@ -1,10 +1,15 @@ HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C")) + .header("'", "squote-key-test") .header("squote-value-test", "'") .header("dquote-value-test", "\"") + .header("`", "backtick-key-test") .header("backtick-value-test", "`") + .header("$", "dollar-key-test") .header("dollar-parenthesis-value-test", "$(") + .header("#", "hash-key-test") .header("hash-brace-value-test", "#{") + .header("%", "percent-key-test") .header("percent-parenthesis-value-test", "%(") .header("percent-brace-value-test", "%{") .header("double-brace-value-test", "{{") diff --git a/test/fixtures/output/java/nethttp/unparseable-query.java b/test/fixtures/output/java/nethttp/unparseable-query.java new file mode 100644 index 0000000..9df4b62 --- /dev/null +++ b/test/fixtures/output/java/nethttp/unparseable-query.java @@ -0,0 +1,6 @@ +HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("http://mockbin.com/har?&&a=b&&")) + .method("GET", HttpRequest.BodyPublishers.noBody()) + .build(); +HttpResponse response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); +System.out.println(response.body()); \ No newline at end of file diff --git a/test/fixtures/output/java/okhttp/malicious.java b/test/fixtures/output/java/okhttp/malicious.java index 13d2499..008bb7c 100644 --- a/test/fixtures/output/java/okhttp/malicious.java +++ b/test/fixtures/output/java/okhttp/malicious.java @@ -5,11 +5,16 @@ Request request = new Request.Builder() .url("http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C") .post(body) + .addHeader("'", "squote-key-test") .addHeader("squote-value-test", "'") .addHeader("dquote-value-test", "\"") + .addHeader("`", "backtick-key-test") .addHeader("backtick-value-test", "`") + .addHeader("$", "dollar-key-test") .addHeader("dollar-parenthesis-value-test", "$(") + .addHeader("#", "hash-key-test") .addHeader("hash-brace-value-test", "#{") + .addHeader("%", "percent-key-test") .addHeader("percent-parenthesis-value-test", "%(") .addHeader("percent-brace-value-test", "%{") .addHeader("double-brace-value-test", "{{") diff --git a/test/fixtures/output/java/okhttp/unparseable-query.java b/test/fixtures/output/java/okhttp/unparseable-query.java new file mode 100644 index 0000000..b08a7d6 --- /dev/null +++ b/test/fixtures/output/java/okhttp/unparseable-query.java @@ -0,0 +1,8 @@ +OkHttpClient client = new OkHttpClient(); + +Request request = new Request.Builder() + .url("http://mockbin.com/har?&&a=b&&") + .get() + .build(); + +Response response = client.newCall(request).execute(); \ No newline at end of file diff --git a/test/fixtures/output/java/restclient/application-form-encoded.java b/test/fixtures/output/java/restclient/application-form-encoded.java new file mode 100644 index 0000000..63b17ff --- /dev/null +++ b/test/fixtures/output/java/restclient/application-form-encoded.java @@ -0,0 +1,13 @@ +RestClient restClient = RestClient.create(); + +MultiValueMap formDataMap = new LinkedMultiValueMap<>(); +formDataMap.add("foo", "bar"); +formDataMap.add("hello", "world"); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(formDataMap) + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/application-json.java b/test/fixtures/output/java/restclient/application-json.java new file mode 100644 index 0000000..5d12031 --- /dev/null +++ b/test/fixtures/output/java/restclient/application-json.java @@ -0,0 +1,9 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .contentType(MediaType.APPLICATION_JSON) + .body("{\"number\":1,\"string\":\"f\\\"oo\",\"arr\":[1,2,3],\"nested\":{\"a\":\"b\"},\"arr_mix\":[1,\"a\",{\"arr_mix_nested\":{}}],\"boolean\":false}") + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/compression.java b/test/fixtures/output/java/restclient/compression.java new file mode 100644 index 0000000..056a80b --- /dev/null +++ b/test/fixtures/output/java/restclient/compression.java @@ -0,0 +1,8 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.GET) + .uri("http://mockbin.com/har") + .header("accept-encoding", "deflate, gzip, br") + .retrieve() + .toEntity(String.class); \ No newline at end of file diff --git a/test/fixtures/output/java/restclient/cookies.java b/test/fixtures/output/java/restclient/cookies.java new file mode 100644 index 0000000..624d1fd --- /dev/null +++ b/test/fixtures/output/java/restclient/cookies.java @@ -0,0 +1,9 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .cookie("foo", "bar") + .cookie("bar", "baz") + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/custom-method.java b/test/fixtures/output/java/restclient/custom-method.java new file mode 100644 index 0000000..70eafc5 --- /dev/null +++ b/test/fixtures/output/java/restclient/custom-method.java @@ -0,0 +1,7 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.valueOf("PROPFIND")) + .uri("http://mockbin.com/har") + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/full.java b/test/fixtures/output/java/restclient/full.java new file mode 100644 index 0000000..8126f6d --- /dev/null +++ b/test/fixtures/output/java/restclient/full.java @@ -0,0 +1,21 @@ +RestClient restClient = RestClient.create(); + +MultiValueMap formDataMap = new LinkedMultiValueMap<>(); +formDataMap.add("foo", "bar"); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har", uriBuilder -> { + uriBuilder.queryParam("foo", "bar"); + uriBuilder.queryParam("foo", "baz"); + uriBuilder.queryParam("baz", "abc"); + uriBuilder.queryParam("key", "value"); + return uriBuilder.build(); + }) + .cookie("foo", "bar") + .cookie("bar", "baz") + .header("accept", "application/json") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(formDataMap) + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/headers.java b/test/fixtures/output/java/restclient/headers.java new file mode 100644 index 0000000..229d844 --- /dev/null +++ b/test/fixtures/output/java/restclient/headers.java @@ -0,0 +1,10 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.GET) + .uri("http://mockbin.com/har") + .header("accept", "application/json") + .header("x-foo", "Bar") + .header("quoted-value", "\"quoted\" 'string'") + .retrieve() + .toEntity(String.class); \ No newline at end of file diff --git a/test/fixtures/output/java/restclient/https.java b/test/fixtures/output/java/restclient/https.java new file mode 100644 index 0000000..0946263 --- /dev/null +++ b/test/fixtures/output/java/restclient/https.java @@ -0,0 +1,7 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.GET) + .uri("https://mockbin.com/har") + .retrieve() + .toEntity(String.class); \ No newline at end of file diff --git a/test/fixtures/output/java/restclient/jsonObj-multiline.java b/test/fixtures/output/java/restclient/jsonObj-multiline.java new file mode 100644 index 0000000..71a2fbe --- /dev/null +++ b/test/fixtures/output/java/restclient/jsonObj-multiline.java @@ -0,0 +1,9 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .contentType(MediaType.APPLICATION_JSON) + .body("{\n \"foo\": \"bar\"\n}") + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/jsonObj-null-value.java b/test/fixtures/output/java/restclient/jsonObj-null-value.java new file mode 100644 index 0000000..8b3f17b --- /dev/null +++ b/test/fixtures/output/java/restclient/jsonObj-null-value.java @@ -0,0 +1,9 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .contentType(MediaType.APPLICATION_JSON) + .body("{\"foo\":null}") + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/malicious.java b/test/fixtures/output/java/restclient/malicious.java new file mode 100644 index 0000000..9919ca1 --- /dev/null +++ b/test/fixtures/output/java/restclient/malicious.java @@ -0,0 +1,49 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//", uriBuilder -> { + uriBuilder.queryParam("'", "squote-key-test"); + uriBuilder.queryParam("squote-value-test", "'"); + uriBuilder.queryParam("\"", "dquote-key-test"); + uriBuilder.queryParam("dquote-value-test", "\""); + uriBuilder.queryParam("`", "backtick-key-test"); + uriBuilder.queryParam("backtick-value-test", "`"); + uriBuilder.queryParam("$(", "dollar-parenthesis-key-test"); + uriBuilder.queryParam("dollar-parenthesis-value-test", "$("); + uriBuilder.queryParam("#{", "hash-brace-key-test"); + uriBuilder.queryParam("hash-brace-value-test", "#{"); + uriBuilder.queryParam("%(", "percent-parenthesis-key-test"); + uriBuilder.queryParam("percent-parenthesis-value-test", "%("); + uriBuilder.queryParam("%{", "percent-brace-key-test"); + uriBuilder.queryParam("percent-brace-value-test", "%{"); + uriBuilder.queryParam("{{", "double-brace-key-test"); + uriBuilder.queryParam("double-brace-value-test", "{{"); + uriBuilder.queryParam("\\0", "null-key-test"); + uriBuilder.queryParam("null-value-test", "\\0"); + uriBuilder.queryParam("%s", "string-fmt-key-test"); + uriBuilder.queryParam("string-fmt-value-test", "%s"); + uriBuilder.queryParam("\\", "slash-key-test"); + uriBuilder.queryParam("slash-value-test", "\\"); + return uriBuilder.build(); + }) + .header("'", "squote-key-test") + .header("squote-value-test", "'") + .header("dquote-value-test", "\"") + .header("`", "backtick-key-test") + .header("backtick-value-test", "`") + .header("$", "dollar-key-test") + .header("dollar-parenthesis-value-test", "$(") + .header("#", "hash-key-test") + .header("hash-brace-value-test", "#{") + .header("%", "percent-key-test") + .header("percent-parenthesis-value-test", "%(") + .header("percent-brace-value-test", "%{") + .header("double-brace-value-test", "{{") + .header("null-value-test", "\\0") + .header("string-fmt-value-test", "%s") + .header("slash-value-test", "\\") + .contentType(MediaType.TEXT_PLAIN) + .body("' \" ` $( #{ %( %{ {{ \\0 %s \\") + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/multipart-data.java b/test/fixtures/output/java/restclient/multipart-data.java new file mode 100644 index 0000000..ef5d723 --- /dev/null +++ b/test/fixtures/output/java/restclient/multipart-data.java @@ -0,0 +1,14 @@ +RestClient restClient = RestClient.create(); + +MultipartBodyBuilder multipartBuilder = new MultipartBodyBuilder(); +multipartBuilder.part("foo", "Hello World") + .filename("hello.txt") + .contentType(MediaType.TEXT_PLAIN); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .contentType(MediaType.MULTIPART_FORM_DATA) + .body(multipartBuilder.build()) + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/multipart-file.java b/test/fixtures/output/java/restclient/multipart-file.java new file mode 100644 index 0000000..1144288 --- /dev/null +++ b/test/fixtures/output/java/restclient/multipart-file.java @@ -0,0 +1,13 @@ +RestClient restClient = RestClient.create(); + +MultipartBodyBuilder multipartBuilder = new MultipartBodyBuilder(); +multipartBuilder.part("foo", new FileSystemResource("test/fixtures/files/hello.txt")) + .contentType(MediaType.TEXT_PLAIN); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .contentType(MediaType.MULTIPART_FORM_DATA) + .body(multipartBuilder.build()) + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/multipart-form-data.java b/test/fixtures/output/java/restclient/multipart-form-data.java new file mode 100644 index 0000000..604d426 --- /dev/null +++ b/test/fixtures/output/java/restclient/multipart-form-data.java @@ -0,0 +1,12 @@ +RestClient restClient = RestClient.create(); + +MultipartBodyBuilder multipartBuilder = new MultipartBodyBuilder(); +multipartBuilder.part("foo", "bar"); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .contentType(MediaType.MULTIPART_FORM_DATA) + .body(multipartBuilder.build()) + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/nested.java b/test/fixtures/output/java/restclient/nested.java new file mode 100644 index 0000000..53b6846 --- /dev/null +++ b/test/fixtures/output/java/restclient/nested.java @@ -0,0 +1,12 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.GET) + .uri("http://mockbin.com/har", uriBuilder -> { + uriBuilder.queryParam("foo[bar]", "baz,zap"); + uriBuilder.queryParam("fiz", "buz"); + uriBuilder.queryParam("key", "value"); + return uriBuilder.build(); + }) + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/query.java b/test/fixtures/output/java/restclient/query.java new file mode 100644 index 0000000..7979608 --- /dev/null +++ b/test/fixtures/output/java/restclient/query.java @@ -0,0 +1,13 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.GET) + .uri("http://mockbin.com/har", uriBuilder -> { + uriBuilder.queryParam("foo", "bar"); + uriBuilder.queryParam("foo", "baz"); + uriBuilder.queryParam("baz", "abc"); + uriBuilder.queryParam("key", "value"); + return uriBuilder.build(); + }) + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/short.java b/test/fixtures/output/java/restclient/short.java new file mode 100644 index 0000000..b100f40 --- /dev/null +++ b/test/fixtures/output/java/restclient/short.java @@ -0,0 +1,7 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.GET) + .uri("http://mockbin.com/har") + .retrieve() + .toEntity(String.class); \ No newline at end of file diff --git a/test/fixtures/output/java/restclient/text-plain.java b/test/fixtures/output/java/restclient/text-plain.java new file mode 100644 index 0000000..8aef2bf --- /dev/null +++ b/test/fixtures/output/java/restclient/text-plain.java @@ -0,0 +1,9 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.POST) + .uri("http://mockbin.com/har") + .contentType(MediaType.TEXT_PLAIN) + .body("Hello World") + .retrieve() + .toEntity(String.class); diff --git a/test/fixtures/output/java/restclient/unparseable-query.java b/test/fixtures/output/java/restclient/unparseable-query.java new file mode 100644 index 0000000..6d64f6c --- /dev/null +++ b/test/fixtures/output/java/restclient/unparseable-query.java @@ -0,0 +1,7 @@ +RestClient restClient = RestClient.create(); + +ResponseEntity response = restClient + .method(HttpMethod.GET) + .uri("http://mockbin.com/har?&&a=b&&") + .retrieve() + .toEntity(String.class); \ No newline at end of file diff --git a/test/fixtures/output/java/unirest/malicious.java b/test/fixtures/output/java/unirest/malicious.java index 346a5ce..85f1906 100644 --- a/test/fixtures/output/java/unirest/malicious.java +++ b/test/fixtures/output/java/unirest/malicious.java @@ -1,9 +1,14 @@ HttpResponse response = Unirest.post("http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C") + .header("'", "squote-key-test") .header("squote-value-test", "'") .header("dquote-value-test", "\"") + .header("`", "backtick-key-test") .header("backtick-value-test", "`") + .header("$", "dollar-key-test") .header("dollar-parenthesis-value-test", "$(") + .header("#", "hash-key-test") .header("hash-brace-value-test", "#{") + .header("%", "percent-key-test") .header("percent-parenthesis-value-test", "%(") .header("percent-brace-value-test", "%{") .header("double-brace-value-test", "{{") diff --git a/test/fixtures/output/java/unirest/unparseable-query.java b/test/fixtures/output/java/unirest/unparseable-query.java new file mode 100644 index 0000000..21aad1f --- /dev/null +++ b/test/fixtures/output/java/unirest/unparseable-query.java @@ -0,0 +1,2 @@ +HttpResponse response = Unirest.get("http://mockbin.com/har?&&a=b&&") + .asString(); \ No newline at end of file diff --git a/test/fixtures/output/javascript/axios/malicious.js b/test/fixtures/output/javascript/axios/malicious.js index c6a440e..c0435b0 100644 --- a/test/fixtures/output/javascript/axios/malicious.js +++ b/test/fixtures/output/javascript/axios/malicious.js @@ -28,11 +28,16 @@ const options = { 'slash-value-test': '\\' }, headers: { + '\'': 'squote-key-test', 'squote-value-test': '\'', 'dquote-value-test': '"', + '`': 'backtick-key-test', 'backtick-value-test': '`', + $: 'dollar-key-test', 'dollar-parenthesis-value-test': '$(', + '#': 'hash-key-test', 'hash-brace-value-test': '#{', + '%': 'percent-key-test', 'percent-parenthesis-value-test': '%(', 'percent-brace-value-test': '%{', 'double-brace-value-test': '{{', diff --git a/test/fixtures/output/javascript/axios/unparseable-query.js b/test/fixtures/output/javascript/axios/unparseable-query.js new file mode 100644 index 0000000..a74bf9f --- /dev/null +++ b/test/fixtures/output/javascript/axios/unparseable-query.js @@ -0,0 +1,9 @@ +import axios from "axios"; + +const options = {method: 'GET', url: 'http://mockbin.com/har?&&a=b&&'}; + +axios.request(options).then(function (response) { + console.log(response.data); +}).catch(function (error) { + console.error(error); +}); \ No newline at end of file diff --git a/test/fixtures/output/javascript/fetch/malicious.js b/test/fixtures/output/javascript/fetch/malicious.js index 3a02317..4fd3ce1 100644 --- a/test/fixtures/output/javascript/fetch/malicious.js +++ b/test/fixtures/output/javascript/fetch/malicious.js @@ -1,11 +1,16 @@ const options = { method: 'POST', headers: { + '\'': 'squote-key-test', 'squote-value-test': '\'', 'dquote-value-test': '"', + '`': 'backtick-key-test', 'backtick-value-test': '`', + $: 'dollar-key-test', 'dollar-parenthesis-value-test': '$(', + '#': 'hash-key-test', 'hash-brace-value-test': '#{', + '%': 'percent-key-test', 'percent-parenthesis-value-test': '%(', 'percent-brace-value-test': '%{', 'double-brace-value-test': '{{', diff --git a/test/fixtures/output/javascript/fetch/unparseable-query.js b/test/fixtures/output/javascript/fetch/unparseable-query.js new file mode 100644 index 0000000..5e0d126 --- /dev/null +++ b/test/fixtures/output/javascript/fetch/unparseable-query.js @@ -0,0 +1,6 @@ +const options = {method: 'GET'}; + +fetch('http://mockbin.com/har?&&a=b&&', options) + .then(response => response.json()) + .then(response => console.log(response)) + .catch(err => console.error(err)); \ No newline at end of file diff --git a/test/fixtures/output/javascript/jquery/malicious.js b/test/fixtures/output/javascript/jquery/malicious.js index 476209e..b6ccbb6 100644 --- a/test/fixtures/output/javascript/jquery/malicious.js +++ b/test/fixtures/output/javascript/jquery/malicious.js @@ -4,11 +4,16 @@ const settings = { "url": "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C", "method": "POST", "headers": { + "'": "squote-key-test", "squote-value-test": "'", "dquote-value-test": "\"", + "`": "backtick-key-test", "backtick-value-test": "`", + "$": "dollar-key-test", "dollar-parenthesis-value-test": "$(", + "#": "hash-key-test", "hash-brace-value-test": "#{", + "%": "percent-key-test", "percent-parenthesis-value-test": "%(", "percent-brace-value-test": "%{", "double-brace-value-test": "{{", diff --git a/test/fixtures/output/javascript/jquery/unparseable-query.js b/test/fixtures/output/javascript/jquery/unparseable-query.js new file mode 100644 index 0000000..3a59c9e --- /dev/null +++ b/test/fixtures/output/javascript/jquery/unparseable-query.js @@ -0,0 +1,11 @@ +const settings = { + "async": true, + "crossDomain": true, + "url": "http://mockbin.com/har?&&a=b&&", + "method": "GET", + "headers": {} +}; + +$.ajax(settings).done(function (response) { + console.log(response); +}); \ No newline at end of file diff --git a/test/fixtures/output/javascript/xhr/malicious.js b/test/fixtures/output/javascript/xhr/malicious.js index d998152..08c9797 100644 --- a/test/fixtures/output/javascript/xhr/malicious.js +++ b/test/fixtures/output/javascript/xhr/malicious.js @@ -10,11 +10,16 @@ xhr.addEventListener("readystatechange", function () { }); xhr.open("POST", "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C"); +xhr.setRequestHeader("'", "squote-key-test"); xhr.setRequestHeader("squote-value-test", "'"); xhr.setRequestHeader("dquote-value-test", "\""); +xhr.setRequestHeader("`", "backtick-key-test"); xhr.setRequestHeader("backtick-value-test", "`"); +xhr.setRequestHeader("$", "dollar-key-test"); xhr.setRequestHeader("dollar-parenthesis-value-test", "$("); +xhr.setRequestHeader("#", "hash-key-test"); xhr.setRequestHeader("hash-brace-value-test", "#{"); +xhr.setRequestHeader("%", "percent-key-test"); xhr.setRequestHeader("percent-parenthesis-value-test", "%("); xhr.setRequestHeader("percent-brace-value-test", "%{"); xhr.setRequestHeader("double-brace-value-test", "{{"); diff --git a/test/fixtures/output/javascript/xhr/unparseable-query.js b/test/fixtures/output/javascript/xhr/unparseable-query.js new file mode 100644 index 0000000..d955e0a --- /dev/null +++ b/test/fixtures/output/javascript/xhr/unparseable-query.js @@ -0,0 +1,14 @@ +const data = null; + +const xhr = new XMLHttpRequest(); +xhr.withCredentials = true; + +xhr.addEventListener("readystatechange", function () { + if (this.readyState === this.DONE) { + console.log(this.responseText); + } +}); + +xhr.open("GET", "http://mockbin.com/har?&&a=b&&"); + +xhr.send(data); \ No newline at end of file diff --git a/test/fixtures/output/kotlin/okhttp/malicious.kt b/test/fixtures/output/kotlin/okhttp/malicious.kt index ccd65e0..95d5e9f 100644 --- a/test/fixtures/output/kotlin/okhttp/malicious.kt +++ b/test/fixtures/output/kotlin/okhttp/malicious.kt @@ -5,11 +5,16 @@ val body = RequestBody.create(mediaType, "' \" ` $( #{ %( %{ {{ \\0 %s \\") val request = Request.Builder() .url("http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C") .post(body) + .addHeader("'", "squote-key-test") .addHeader("squote-value-test", "'") .addHeader("dquote-value-test", "\"") + .addHeader("`", "backtick-key-test") .addHeader("backtick-value-test", "`") + .addHeader("$", "dollar-key-test") .addHeader("dollar-parenthesis-value-test", "$(") + .addHeader("#", "hash-key-test") .addHeader("hash-brace-value-test", "#{") + .addHeader("%", "percent-key-test") .addHeader("percent-parenthesis-value-test", "%(") .addHeader("percent-brace-value-test", "%{") .addHeader("double-brace-value-test", "{{") diff --git a/test/fixtures/output/kotlin/okhttp/unparseable-query.kt b/test/fixtures/output/kotlin/okhttp/unparseable-query.kt new file mode 100644 index 0000000..208e62d --- /dev/null +++ b/test/fixtures/output/kotlin/okhttp/unparseable-query.kt @@ -0,0 +1,8 @@ +val client = OkHttpClient() + +val request = Request.Builder() + .url("http://mockbin.com/har?&&a=b&&") + .get() + .build() + +val response = client.newCall(request).execute() \ No newline at end of file diff --git a/test/fixtures/output/node/axios/malicious.js b/test/fixtures/output/node/axios/malicious.js index c0c381f..0c3bc7c 100644 --- a/test/fixtures/output/node/axios/malicious.js +++ b/test/fixtures/output/node/axios/malicious.js @@ -28,11 +28,16 @@ var options = { 'slash-value-test': '\\' }, headers: { + '\'': 'squote-key-test', 'squote-value-test': '\'', 'dquote-value-test': '"', + '`': 'backtick-key-test', 'backtick-value-test': '`', + $: 'dollar-key-test', 'dollar-parenthesis-value-test': '$(', + '#': 'hash-key-test', 'hash-brace-value-test': '#{', + '%': 'percent-key-test', 'percent-parenthesis-value-test': '%(', 'percent-brace-value-test': '%{', 'double-brace-value-test': '{{', diff --git a/test/fixtures/output/node/axios/unparseable-query.js b/test/fixtures/output/node/axios/unparseable-query.js new file mode 100644 index 0000000..dac5faa --- /dev/null +++ b/test/fixtures/output/node/axios/unparseable-query.js @@ -0,0 +1,9 @@ +var axios = require("axios").default; + +var options = {method: 'GET', url: 'http://mockbin.com/har?&&a=b&&'}; + +axios.request(options).then(function (response) { + console.log(response.data); +}).catch(function (error) { + console.error(error); +}); \ No newline at end of file diff --git a/test/fixtures/output/node/fetch/malicious.js b/test/fixtures/output/node/fetch/malicious.js index 6f286b7..a50f8e9 100644 --- a/test/fixtures/output/node/fetch/malicious.js +++ b/test/fixtures/output/node/fetch/malicious.js @@ -5,11 +5,16 @@ let url = 'http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?\'=squote-key-test& let options = { method: 'POST', headers: { + '\'': 'squote-key-test', 'squote-value-test': '\'', 'dquote-value-test': '"', + '`': 'backtick-key-test', 'backtick-value-test': '`', + $: 'dollar-key-test', 'dollar-parenthesis-value-test': '$(', + '#': 'hash-key-test', 'hash-brace-value-test': '#{', + '%': 'percent-key-test', 'percent-parenthesis-value-test': '%(', 'percent-brace-value-test': '%{', 'double-brace-value-test': '{{', diff --git a/test/fixtures/output/node/fetch/unparseable-query.js b/test/fixtures/output/node/fetch/unparseable-query.js new file mode 100644 index 0000000..7064d64 --- /dev/null +++ b/test/fixtures/output/node/fetch/unparseable-query.js @@ -0,0 +1,10 @@ +const fetch = require('node-fetch'); + +let url = 'http://mockbin.com/har?&&a=b&&'; + +let options = {method: 'GET'}; + +fetch(url, options) + .then(res => res.json()) + .then(json => console.log(json)) + .catch(err => console.error('error:' + err)); \ No newline at end of file diff --git a/test/fixtures/output/node/native/malicious.js b/test/fixtures/output/node/native/malicious.js index 830baac..13db86e 100644 --- a/test/fixtures/output/node/native/malicious.js +++ b/test/fixtures/output/node/native/malicious.js @@ -6,11 +6,16 @@ const options = { "port": null, "path": "/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C", "headers": { + "'": "squote-key-test", "squote-value-test": "'", "dquote-value-test": "\"", + "`": "backtick-key-test", "backtick-value-test": "`", + "$": "dollar-key-test", "dollar-parenthesis-value-test": "$(", + "#": "hash-key-test", "hash-brace-value-test": "#{", + "%": "percent-key-test", "percent-parenthesis-value-test": "%(", "percent-brace-value-test": "%{", "double-brace-value-test": "{{", diff --git a/test/fixtures/output/node/native/unparseable-query.js b/test/fixtures/output/node/native/unparseable-query.js new file mode 100644 index 0000000..b991ed0 --- /dev/null +++ b/test/fixtures/output/node/native/unparseable-query.js @@ -0,0 +1,24 @@ +const http = require("http"); + +const options = { + "method": "GET", + "hostname": "mockbin.com", + "port": null, + "path": "/har?&&a=b&&", + "headers": {} +}; + +const req = http.request(options, function (res) { + const chunks = []; + + res.on("data", function (chunk) { + chunks.push(chunk); + }); + + res.on("end", function () { + const body = Buffer.concat(chunks); + console.log(body.toString()); + }); +}); + +req.end(); \ No newline at end of file diff --git a/test/fixtures/output/node/request/malicious.js b/test/fixtures/output/node/request/malicious.js index f502254..e289ee6 100644 --- a/test/fixtures/output/node/request/malicious.js +++ b/test/fixtures/output/node/request/malicious.js @@ -28,11 +28,16 @@ const options = { 'slash-value-test': '\\' }, headers: { + '\'': 'squote-key-test', 'squote-value-test': '\'', 'dquote-value-test': '"', + '`': 'backtick-key-test', 'backtick-value-test': '`', + $: 'dollar-key-test', 'dollar-parenthesis-value-test': '$(', + '#': 'hash-key-test', 'hash-brace-value-test': '#{', + '%': 'percent-key-test', 'percent-parenthesis-value-test': '%(', 'percent-brace-value-test': '%{', 'double-brace-value-test': '{{', diff --git a/test/fixtures/output/node/request/unparseable-query.js b/test/fixtures/output/node/request/unparseable-query.js new file mode 100644 index 0000000..c10a732 --- /dev/null +++ b/test/fixtures/output/node/request/unparseable-query.js @@ -0,0 +1,9 @@ +const request = require('request'); + +const options = {method: 'GET', url: 'http://mockbin.com/har?&&a=b&&'}; + +request(options, function (error, response, body) { + if (error) throw new Error(error); + + console.log(body); +}); \ No newline at end of file diff --git a/test/fixtures/output/node/unirest/malicious.js b/test/fixtures/output/node/unirest/malicious.js index 58f76fd..d082c42 100644 --- a/test/fixtures/output/node/unirest/malicious.js +++ b/test/fixtures/output/node/unirest/malicious.js @@ -28,11 +28,16 @@ req.query({ }); req.headers({ + "'": "squote-key-test", "squote-value-test": "'", "dquote-value-test": "\"", + "`": "backtick-key-test", "backtick-value-test": "`", + "$": "dollar-key-test", "dollar-parenthesis-value-test": "$(", + "#": "hash-key-test", "hash-brace-value-test": "#{", + "%": "percent-key-test", "percent-parenthesis-value-test": "%(", "percent-brace-value-test": "%{", "double-brace-value-test": "{{", diff --git a/test/fixtures/output/node/unirest/unparseable-query.js b/test/fixtures/output/node/unirest/unparseable-query.js new file mode 100644 index 0000000..f0f961e --- /dev/null +++ b/test/fixtures/output/node/unirest/unparseable-query.js @@ -0,0 +1,9 @@ +const unirest = require("unirest"); + +const req = unirest("GET", "http://mockbin.com/har?&&a=b&&"); + +req.end(function (res) { + if (res.error) throw new Error(res.error); + + console.log(res.body); +}); \ No newline at end of file diff --git a/test/fixtures/output/objc/nsurlsession/malicious.m b/test/fixtures/output/objc/nsurlsession/malicious.m index 9c5ff77..66f2cc5 100644 --- a/test/fixtures/output/objc/nsurlsession/malicious.m +++ b/test/fixtures/output/objc/nsurlsession/malicious.m @@ -1,10 +1,15 @@ #import -NSDictionary *headers = @{ @"squote-value-test": @"'", +NSDictionary *headers = @{ @"'": @"squote-key-test", + @"squote-value-test": @"'", @"dquote-value-test": @"\"", + @"`": @"backtick-key-test", @"backtick-value-test": @"`", + @"$": @"dollar-key-test", @"dollar-parenthesis-value-test": @"$(", + @"#": @"hash-key-test", @"hash-brace-value-test": @"#{", + @"%": @"percent-key-test", @"percent-parenthesis-value-test": @"%(", @"percent-brace-value-test": @"%{", @"double-brace-value-test": @"{{", diff --git a/test/fixtures/output/objc/nsurlsession/unparseable-query.m b/test/fixtures/output/objc/nsurlsession/unparseable-query.m new file mode 100644 index 0000000..b201540 --- /dev/null +++ b/test/fixtures/output/objc/nsurlsession/unparseable-query.m @@ -0,0 +1,18 @@ +#import + +NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://mockbin.com/har?&&a=b&&"] + cachePolicy:NSURLRequestUseProtocolCachePolicy + timeoutInterval:10.0]; +[request setHTTPMethod:@"GET"]; + +NSURLSession *session = [NSURLSession sharedSession]; +NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error) { + NSLog(@"%@", error); + } else { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; + NSLog(@"%@", httpResponse); + } + }]; +[dataTask resume]; \ No newline at end of file diff --git a/test/fixtures/output/ocaml/cohttp/malicious.ml b/test/fixtures/output/ocaml/cohttp/malicious.ml index 20b0757..ada920e 100644 --- a/test/fixtures/output/ocaml/cohttp/malicious.ml +++ b/test/fixtures/output/ocaml/cohttp/malicious.ml @@ -4,11 +4,16 @@ open Lwt let uri = Uri.of_string "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C" in let headers = Header.add_list (Header.init ()) [ + ("'", "squote-key-test"); ("squote-value-test", "'"); ("dquote-value-test", "\""); + ("`", "backtick-key-test"); ("backtick-value-test", "`"); + ("$", "dollar-key-test"); ("dollar-parenthesis-value-test", "$("); + ("#", "hash-key-test"); ("hash-brace-value-test", "#{"); + ("%", "percent-key-test"); ("percent-parenthesis-value-test", "%("); ("percent-brace-value-test", "%{"); ("double-brace-value-test", "{{"); diff --git a/test/fixtures/output/ocaml/cohttp/unparseable-query.ml b/test/fixtures/output/ocaml/cohttp/unparseable-query.ml new file mode 100644 index 0000000..f601513 --- /dev/null +++ b/test/fixtures/output/ocaml/cohttp/unparseable-query.ml @@ -0,0 +1,9 @@ +open Cohttp_lwt_unix +open Cohttp +open Lwt + +let uri = Uri.of_string "http://mockbin.com/har?&&a=b&&" in + +Client.call `GET uri +>>= fun (res, body_stream) -> + (* Do stuff with the result *) \ No newline at end of file diff --git a/test/fixtures/output/php/curl/application-form-encoded.php b/test/fixtures/output/php/curl/application-form-encoded.php index 0892dd3..47114c3 100644 --- a/test/fixtures/output/php/curl/application-form-encoded.php +++ b/test/fixtures/output/php/curl/application-form-encoded.php @@ -3,16 +3,16 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "foo=bar&hello=world", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'foo=bar&hello=world', CURLOPT_HTTPHEADER => [ - "content-type: application/x-www-form-urlencoded" + 'content-type: application/x-www-form-urlencoded' ], ]); @@ -22,7 +22,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/application-json.php b/test/fixtures/output/php/curl/application-json.php index 8a0f0c1..e80ff42 100644 --- a/test/fixtures/output/php/curl/application-json.php +++ b/test/fixtures/output/php/curl/application-json.php @@ -3,16 +3,16 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "{\"number\":1,\"string\":\"f\\\"oo\",\"arr\":[1,2,3],\"nested\":{\"a\":\"b\"},\"arr_mix\":[1,\"a\",{\"arr_mix_nested\":{}}],\"boolean\":false}", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => '{"number":1,"string":"f\\"oo","arr":[1,2,3],"nested":{"a":"b"},"arr_mix":[1,"a",{"arr_mix_nested":{}}],"boolean":false}', CURLOPT_HTTPHEADER => [ - "content-type: application/json" + 'content-type: application/json' ], ]); @@ -22,7 +22,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/compression.php b/test/fixtures/output/php/curl/compression.php index 6bf18d4..bfc0378 100644 --- a/test/fixtures/output/php/curl/compression.php +++ b/test/fixtures/output/php/curl/compression.php @@ -3,15 +3,15 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => [ - "accept-encoding: deflate, gzip, br" + 'accept-encoding: deflate, gzip, br' ], ]); @@ -21,7 +21,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } \ No newline at end of file diff --git a/test/fixtures/output/php/curl/cookies.php b/test/fixtures/output/php/curl/cookies.php index 2810430..c604973 100644 --- a/test/fixtures/output/php/curl/cookies.php +++ b/test/fixtures/output/php/curl/cookies.php @@ -3,14 +3,14 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_COOKIE => "foo=bar; bar=baz", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_COOKIE => 'foo=bar; bar=baz' ]); $response = curl_exec($curl); @@ -19,7 +19,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/custom-method.php b/test/fixtures/output/php/curl/custom-method.php index 08aa597..16e6d57 100644 --- a/test/fixtures/output/php/curl/custom-method.php +++ b/test/fixtures/output/php/curl/custom-method.php @@ -3,13 +3,13 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "PROPFIND", + CURLOPT_CUSTOMREQUEST => 'PROPFIND', ]); $response = curl_exec($curl); @@ -18,7 +18,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/full.php b/test/fixtures/output/php/curl/full.php index 6f342b6..ee1aaee 100644 --- a/test/fixtures/output/php/curl/full.php +++ b/test/fixtures/output/php/curl/full.php @@ -3,18 +3,18 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value", + CURLOPT_URL => 'http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "foo=bar", - CURLOPT_COOKIE => "foo=bar; bar=baz", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'foo=bar', + CURLOPT_COOKIE => 'foo=bar; bar=baz' CURLOPT_HTTPHEADER => [ - "accept: application/json", - "content-type: application/x-www-form-urlencoded" + 'accept: application/json', + 'content-type: application/x-www-form-urlencoded' ], ]); @@ -24,7 +24,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/headers.php b/test/fixtures/output/php/curl/headers.php index d0d4bb7..42dfe33 100644 --- a/test/fixtures/output/php/curl/headers.php +++ b/test/fixtures/output/php/curl/headers.php @@ -3,17 +3,17 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => [ - "accept: application/json", - "quoted-value: \"quoted\" 'string'", - "x-foo: Bar" + 'accept: application/json', + 'quoted-value: "quoted" \'string\'', + 'x-foo: Bar' ], ]); @@ -23,7 +23,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/https.php b/test/fixtures/output/php/curl/https.php index 7d97476..bef4757 100644 --- a/test/fixtures/output/php/curl/https.php +++ b/test/fixtures/output/php/curl/https.php @@ -3,13 +3,13 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "https://mockbin.com/har", + CURLOPT_URL => 'https://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_CUSTOMREQUEST => 'GET', ]); $response = curl_exec($curl); @@ -18,7 +18,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/jsonObj-multiline.php b/test/fixtures/output/php/curl/jsonObj-multiline.php index 19f7727..2c5d836 100644 --- a/test/fixtures/output/php/curl/jsonObj-multiline.php +++ b/test/fixtures/output/php/curl/jsonObj-multiline.php @@ -3,16 +3,18 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "{\n \"foo\": \"bar\"\n}", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => '{ + "foo": "bar" +}', CURLOPT_HTTPHEADER => [ - "content-type: application/json" + 'content-type: application/json' ], ]); @@ -22,7 +24,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/jsonObj-null-value.php b/test/fixtures/output/php/curl/jsonObj-null-value.php index 99a2289..68fee65 100644 --- a/test/fixtures/output/php/curl/jsonObj-null-value.php +++ b/test/fixtures/output/php/curl/jsonObj-null-value.php @@ -3,16 +3,16 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "{\"foo\":null}", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => '{"foo":null}', CURLOPT_HTTPHEADER => [ - "content-type: application/json" + 'content-type: application/json' ], ]); @@ -22,7 +22,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/malicious.php b/test/fixtures/output/php/curl/malicious.php index 10b4e54..6418f5c 100644 --- a/test/fixtures/output/php/curl/malicious.php +++ b/test/fixtures/output/php/curl/malicious.php @@ -3,26 +3,31 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'=squote-key-test&squote-value-test='&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C", + CURLOPT_URL => 'http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?\'=squote-key-test&squote-value-test=\'&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "' \" ` $( #{ %( %{ {{ \\0 %s \\", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => '\' " ` $( #{ %( %{ {{ \\0 %s \\', CURLOPT_HTTPHEADER => [ - "backtick-value-test: `", - "dollar-parenthesis-value-test: $(", - "double-brace-value-test: {{", - "dquote-value-test: \"", - "hash-brace-value-test: #{", - "null-value-test: \\0", - "percent-brace-value-test: %{", - "percent-parenthesis-value-test: %(", - "slash-value-test: \\", - "squote-value-test: '", - "string-fmt-value-test: %s" + '#: hash-key-test', + '$: dollar-key-test', + '%: percent-key-test', + '\': squote-key-test', + '`: backtick-key-test', + 'backtick-value-test: `', + 'dollar-parenthesis-value-test: $(', + 'double-brace-value-test: {{', + 'dquote-value-test: "', + 'hash-brace-value-test: #{', + 'null-value-test: \\0', + 'percent-brace-value-test: %{', + 'percent-parenthesis-value-test: %(', + 'slash-value-test: \\', + 'squote-value-test: \'', + 'string-fmt-value-test: %s' ], ]); @@ -32,7 +37,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } \ No newline at end of file diff --git a/test/fixtures/output/php/curl/multipart-data.php b/test/fixtures/output/php/curl/multipart-data.php index d6ce07f..4f91074 100644 --- a/test/fixtures/output/php/curl/multipart-data.php +++ b/test/fixtures/output/php/curl/multipart-data.php @@ -3,16 +3,22 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\nHello World\r\n-----011000010111000001101001--\r\n", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => '-----011000010111000001101001 +Content-Disposition: form-data; name="foo"; filename="hello.txt" +Content-Type: text/plain + +Hello World +-----011000010111000001101001-- +', CURLOPT_HTTPHEADER => [ - "content-type: multipart/form-data; boundary=---011000010111000001101001" + 'content-type: multipart/form-data; boundary=---011000010111000001101001' ], ]); @@ -22,7 +28,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/multipart-file.php b/test/fixtures/output/php/curl/multipart-file.php index e238b8e..129b9d2 100644 --- a/test/fixtures/output/php/curl/multipart-file.php +++ b/test/fixtures/output/php/curl/multipart-file.php @@ -3,16 +3,22 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\n\r\n-----011000010111000001101001--\r\n", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => '-----011000010111000001101001 +Content-Disposition: form-data; name="foo"; filename="hello.txt" +Content-Type: text/plain + + +-----011000010111000001101001-- +', CURLOPT_HTTPHEADER => [ - "content-type: multipart/form-data; boundary=---011000010111000001101001" + 'content-type: multipart/form-data; boundary=---011000010111000001101001' ], ]); @@ -22,7 +28,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/multipart-form-data.php b/test/fixtures/output/php/curl/multipart-form-data.php index 038aa49..17e5a9d 100644 --- a/test/fixtures/output/php/curl/multipart-form-data.php +++ b/test/fixtures/output/php/curl/multipart-form-data.php @@ -3,16 +3,21 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n-----011000010111000001101001--\r\n", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => '-----011000010111000001101001 +Content-Disposition: form-data; name="foo" + +bar +-----011000010111000001101001-- +', CURLOPT_HTTPHEADER => [ - "Content-Type: multipart/form-data; boundary=---011000010111000001101001" + 'Content-Type: multipart/form-data; boundary=---011000010111000001101001' ], ]); @@ -22,7 +27,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/nested.php b/test/fixtures/output/php/curl/nested.php index 9b345ab..28161a8 100644 --- a/test/fixtures/output/php/curl/nested.php +++ b/test/fixtures/output/php/curl/nested.php @@ -3,13 +3,13 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har?foo%5Bbar%5D=baz%2Czap&fiz=buz&key=value", + CURLOPT_URL => 'http://mockbin.com/har?foo%5Bbar%5D=baz%2Czap&fiz=buz&key=value', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_CUSTOMREQUEST => 'GET', ]); $response = curl_exec($curl); @@ -18,7 +18,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/query.php b/test/fixtures/output/php/curl/query.php index 158e851..a799eb8 100644 --- a/test/fixtures/output/php/curl/query.php +++ b/test/fixtures/output/php/curl/query.php @@ -3,13 +3,13 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value", + CURLOPT_URL => 'http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_CUSTOMREQUEST => 'GET', ]); $response = curl_exec($curl); @@ -18,7 +18,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/short.php b/test/fixtures/output/php/curl/short.php index 9188e25..9f81196 100644 --- a/test/fixtures/output/php/curl/short.php +++ b/test/fixtures/output/php/curl/short.php @@ -3,13 +3,13 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", + CURLOPT_CUSTOMREQUEST => 'GET', ]); $response = curl_exec($curl); @@ -18,7 +18,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/text-plain.php b/test/fixtures/output/php/curl/text-plain.php index 8fbb09d..999c5c0 100644 --- a/test/fixtures/output/php/curl/text-plain.php +++ b/test/fixtures/output/php/curl/text-plain.php @@ -3,16 +3,16 @@ $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => "http://mockbin.com/har", + CURLOPT_URL => 'http://mockbin.com/har', CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", + CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => "Hello World", + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => 'Hello World', CURLOPT_HTTPHEADER => [ - "content-type: text/plain" + 'content-type: text/plain' ], ]); @@ -22,7 +22,7 @@ curl_close($curl); if ($err) { - echo "cURL Error #:" . $err; + echo 'cURL Error #:' . $err; } else { echo $response; } diff --git a/test/fixtures/output/php/curl/unparseable-query.php b/test/fixtures/output/php/curl/unparseable-query.php new file mode 100644 index 0000000..8108a21 --- /dev/null +++ b/test/fixtures/output/php/curl/unparseable-query.php @@ -0,0 +1,24 @@ + 'http://mockbin.com/har?&&a=b&&', + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => '', + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => 'GET', +]); + +$response = curl_exec($curl); +$err = curl_error($curl); + +curl_close($curl); + +if ($err) { + echo 'cURL Error #:' . $err; +} else { + echo $response; +} \ No newline at end of file diff --git a/test/fixtures/output/php/http1/malicious.php b/test/fixtures/output/php/http1/malicious.php index de63752..99ba255 100644 --- a/test/fixtures/output/php/http1/malicious.php +++ b/test/fixtures/output/php/http1/malicious.php @@ -30,11 +30,16 @@ ]); $request->setHeaders([ + '\'' => 'squote-key-test', 'squote-value-test' => '\'', 'dquote-value-test' => '"', + '`' => 'backtick-key-test', 'backtick-value-test' => '`', + '$' => 'dollar-key-test', 'dollar-parenthesis-value-test' => '$(', + '#' => 'hash-key-test', 'hash-brace-value-test' => '#{', + '%' => 'percent-key-test', 'percent-parenthesis-value-test' => '%(', 'percent-brace-value-test' => '%{', 'double-brace-value-test' => '{{', diff --git a/test/fixtures/output/php/http1/unparseable-query.php b/test/fixtures/output/php/http1/unparseable-query.php new file mode 100644 index 0000000..200d80d --- /dev/null +++ b/test/fixtures/output/php/http1/unparseable-query.php @@ -0,0 +1,13 @@ +setUrl('http://mockbin.com/har?&&a=b&&'); +$request->setMethod(HTTP_METH_GET); + +try { + $response = $request->send(); + + echo $response->getBody(); +} catch (HttpException $ex) { + echo $ex; +} \ No newline at end of file diff --git a/test/fixtures/output/php/http2/malicious.php b/test/fixtures/output/php/http2/malicious.php index 0dea61b..b21bac8 100644 --- a/test/fixtures/output/php/http2/malicious.php +++ b/test/fixtures/output/php/http2/malicious.php @@ -36,11 +36,16 @@ ])); $request->setHeaders([ + '\'' => 'squote-key-test', 'squote-value-test' => '\'', 'dquote-value-test' => '"', + '`' => 'backtick-key-test', 'backtick-value-test' => '`', + '$' => 'dollar-key-test', 'dollar-parenthesis-value-test' => '$(', + '#' => 'hash-key-test', 'hash-brace-value-test' => '#{', + '%' => 'percent-key-test', 'percent-parenthesis-value-test' => '%(', 'percent-brace-value-test' => '%{', 'double-brace-value-test' => '{{', diff --git a/test/fixtures/output/php/http2/unparseable-query.php b/test/fixtures/output/php/http2/unparseable-query.php new file mode 100644 index 0000000..52bf547 --- /dev/null +++ b/test/fixtures/output/php/http2/unparseable-query.php @@ -0,0 +1,11 @@ +setRequestUrl('http://mockbin.com/har?&&a=b&&'); +$request->setRequestMethod('GET'); +$client->enqueue($request)->send(); +$response = $client->getResponse(); + +echo $response->getBody(); \ No newline at end of file diff --git a/test/fixtures/output/powershell/restmethod/custom-method.ps1 b/test/fixtures/output/powershell/restmethod/custom-method.ps1 index 5e5237a..acbd914 100644 --- a/test/fixtures/output/powershell/restmethod/custom-method.ps1 +++ b/test/fixtures/output/powershell/restmethod/custom-method.ps1 @@ -1 +1 @@ -Method not supported +$response = Invoke-RestMethod -Uri 'http://mockbin.com/har' -CustomMethod PROPFIND \ No newline at end of file diff --git a/test/fixtures/output/powershell/restmethod/malicious.ps1 b/test/fixtures/output/powershell/restmethod/malicious.ps1 index da17c73..1ede1d0 100644 --- a/test/fixtures/output/powershell/restmethod/malicious.ps1 +++ b/test/fixtures/output/powershell/restmethod/malicious.ps1 @@ -1,9 +1,14 @@ $headers=@{} +$headers.Add('''', 'squote-key-test') $headers.Add('squote-value-test', '''') $headers.Add('dquote-value-test', '"') +$headers.Add('`', 'backtick-key-test') $headers.Add('backtick-value-test', '`') +$headers.Add('$', 'dollar-key-test') $headers.Add('dollar-parenthesis-value-test', '$(') +$headers.Add('#', 'hash-key-test') $headers.Add('hash-brace-value-test', '#{') +$headers.Add('%', 'percent-key-test') $headers.Add('percent-parenthesis-value-test', '%(') $headers.Add('percent-brace-value-test', '%{') $headers.Add('double-brace-value-test', '{{') diff --git a/test/fixtures/output/powershell/restmethod/unparseable-query.ps1 b/test/fixtures/output/powershell/restmethod/unparseable-query.ps1 new file mode 100644 index 0000000..8ca0208 --- /dev/null +++ b/test/fixtures/output/powershell/restmethod/unparseable-query.ps1 @@ -0,0 +1 @@ +$response = Invoke-RestMethod -Uri 'http://mockbin.com/har?&&a=b&&' -Method GET \ No newline at end of file diff --git a/test/fixtures/output/powershell/webrequest/custom-method.ps1 b/test/fixtures/output/powershell/webrequest/custom-method.ps1 index 5e5237a..5f587e4 100644 --- a/test/fixtures/output/powershell/webrequest/custom-method.ps1 +++ b/test/fixtures/output/powershell/webrequest/custom-method.ps1 @@ -1 +1 @@ -Method not supported +$response = Invoke-WebRequest -Uri 'http://mockbin.com/har' -CustomMethod PROPFIND \ No newline at end of file diff --git a/test/fixtures/output/powershell/webrequest/malicious.ps1 b/test/fixtures/output/powershell/webrequest/malicious.ps1 index 4676ad7..026ffb0 100644 --- a/test/fixtures/output/powershell/webrequest/malicious.ps1 +++ b/test/fixtures/output/powershell/webrequest/malicious.ps1 @@ -1,9 +1,14 @@ $headers=@{} +$headers.Add('''', 'squote-key-test') $headers.Add('squote-value-test', '''') $headers.Add('dquote-value-test', '"') +$headers.Add('`', 'backtick-key-test') $headers.Add('backtick-value-test', '`') +$headers.Add('$', 'dollar-key-test') $headers.Add('dollar-parenthesis-value-test', '$(') +$headers.Add('#', 'hash-key-test') $headers.Add('hash-brace-value-test', '#{') +$headers.Add('%', 'percent-key-test') $headers.Add('percent-parenthesis-value-test', '%(') $headers.Add('percent-brace-value-test', '%{') $headers.Add('double-brace-value-test', '{{') diff --git a/test/fixtures/output/powershell/webrequest/unparseable-query.ps1 b/test/fixtures/output/powershell/webrequest/unparseable-query.ps1 new file mode 100644 index 0000000..19bd44b --- /dev/null +++ b/test/fixtures/output/powershell/webrequest/unparseable-query.ps1 @@ -0,0 +1 @@ +$response = Invoke-WebRequest -Uri 'http://mockbin.com/har?&&a=b&&' -Method GET \ No newline at end of file diff --git a/test/fixtures/output/python/python3/malicious.py b/test/fixtures/output/python/python3/malicious.py index 706ecd0..9d5ecd8 100644 --- a/test/fixtures/output/python/python3/malicious.py +++ b/test/fixtures/output/python/python3/malicious.py @@ -5,11 +5,16 @@ payload = "' \" ` $( #{ %( %{ {{ \\0 %s \\" headers = { + "'": "squote-key-test", "squote-value-test": "'", "dquote-value-test": "\"", + "`": "backtick-key-test", "backtick-value-test": "`", + "$": "dollar-key-test", "dollar-parenthesis-value-test": "$(", + "#": "hash-key-test", "hash-brace-value-test": "#{", + "%": "percent-key-test", "percent-parenthesis-value-test": "%(", "percent-brace-value-test": "%{", "double-brace-value-test": "{{", diff --git a/test/fixtures/output/python/python3/unparseable-query.py b/test/fixtures/output/python/python3/unparseable-query.py new file mode 100644 index 0000000..4a74ee4 --- /dev/null +++ b/test/fixtures/output/python/python3/unparseable-query.py @@ -0,0 +1,10 @@ +import http.client + +conn = http.client.HTTPConnection("mockbin.com") + +conn.request("GET", "/har?&&a=b&&") + +res = conn.getresponse() +data = res.read() + +print(data.decode("utf-8")) \ No newline at end of file diff --git a/test/fixtures/output/python/requests/malicious.py b/test/fixtures/output/python/requests/malicious.py index 0e9a043..14eb9dd 100644 --- a/test/fixtures/output/python/requests/malicious.py +++ b/test/fixtures/output/python/requests/malicious.py @@ -29,11 +29,16 @@ payload = "' \" ` $( #{ %( %{ {{ \\0 %s \\" headers = { + "'": "squote-key-test", "squote-value-test": "'", "dquote-value-test": "\"", + "`": "backtick-key-test", "backtick-value-test": "`", + "$": "dollar-key-test", "dollar-parenthesis-value-test": "$(", + "#": "hash-key-test", "hash-brace-value-test": "#{", + "%": "percent-key-test", "percent-parenthesis-value-test": "%(", "percent-brace-value-test": "%{", "double-brace-value-test": "{{", diff --git a/test/fixtures/output/python/requests/unparseable-query.py b/test/fixtures/output/python/requests/unparseable-query.py new file mode 100644 index 0000000..af5d7bd --- /dev/null +++ b/test/fixtures/output/python/requests/unparseable-query.py @@ -0,0 +1,7 @@ +import requests + +url = "http://mockbin.com/har?&&a=b&&" + +response = requests.get(url) + +print(response.text) \ No newline at end of file diff --git a/test/fixtures/output/r/httr/malicious.r b/test/fixtures/output/r/httr/malicious.r index 8275064..ac36ea6 100644 --- a/test/fixtures/output/r/httr/malicious.r +++ b/test/fixtures/output/r/httr/malicious.r @@ -31,6 +31,6 @@ payload <- "' \" ` $( #{ %( %{ {{ \\0 %s \\" encode <- "raw" -response <- VERB("POST", url, body = payload, query = queryString, add_headers(squote_value_test = '\'', dquote_value_test = '"', backtick_value_test = '`', dollar_parenthesis_value_test = '$(', hash_brace_value_test = '#{', percent_parenthesis_value_test = '%(', percent_brace_value_test = '%{', double_brace_value_test = '{{', null_value_test = '\\0', string_fmt_value_test = '%s', slash_value_test = '\\'), content_type("text/plain"), encode = encode) +response <- VERB("POST", url, body = payload, query = queryString, add_headers("'" = 'squote-key-test', squote_value_test = '\'', dquote_value_test = '"', "`" = 'backtick-key-test', backtick_value_test = '`', "$" = 'dollar-key-test', dollar_parenthesis_value_test = '$(', "#" = 'hash-key-test', hash_brace_value_test = '#{', "%" = 'percent-key-test', percent_parenthesis_value_test = '%(', percent_brace_value_test = '%{', double_brace_value_test = '{{', null_value_test = '\\0', string_fmt_value_test = '%s', slash_value_test = '\\'), content_type("text/plain"), encode = encode) content(response, "text") \ No newline at end of file diff --git a/test/fixtures/output/r/httr/unparseable-query.r b/test/fixtures/output/r/httr/unparseable-query.r new file mode 100644 index 0000000..b39a545 --- /dev/null +++ b/test/fixtures/output/r/httr/unparseable-query.r @@ -0,0 +1,7 @@ +library(httr) + +url <- "http://mockbin.com/har?&&a=b&&" + +response <- VERB("GET", url, content_type("application/octet-stream")) + +content(response, "text") \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/application-form-encoded.rb b/test/fixtures/output/ruby/faraday/application-form-encoded.rb new file mode 100644 index 0000000..9f15c8a --- /dev/null +++ b/test/fixtures/output/ruby/faraday/application-form-encoded.rb @@ -0,0 +1,18 @@ +require 'faraday' + +data = { + :foo => "bar", + :hello => "world", +} + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'application/x-www-form-urlencoded'} +) + +response = conn.post('/har') do |req| + req.body = URI.encode_www_form(data) +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/application-json.rb b/test/fixtures/output/ruby/faraday/application-json.rb new file mode 100644 index 0000000..2c22a0e --- /dev/null +++ b/test/fixtures/output/ruby/faraday/application-json.rb @@ -0,0 +1,13 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'application/json'} +) + +response = conn.post('/har') do |req| + req.body = "{\"number\":1,\"string\":\"f\\\"oo\",\"arr\":[1,2,3],\"nested\":{\"a\":\"b\"},\"arr_mix\":[1,\"a\",{\"arr_mix_nested\":{}}],\"boolean\":false}" +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/compression.rb b/test/fixtures/output/ruby/faraday/compression.rb new file mode 100644 index 0000000..4c0f30b --- /dev/null +++ b/test/fixtures/output/ruby/faraday/compression.rb @@ -0,0 +1,12 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', +) + +response = conn.get('/har') do |req| + req.headers['accept-encoding'] = 'deflate, gzip, br' +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/cookies.rb b/test/fixtures/output/ruby/faraday/cookies.rb new file mode 100644 index 0000000..5c884d7 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/cookies.rb @@ -0,0 +1,12 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', +) + +response = conn.post('/har') do |req| + req.headers['cookie'] = 'foo=bar; bar=baz' +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/custom-method.rb b/test/fixtures/output/ruby/faraday/custom-method.rb new file mode 100644 index 0000000..213ada5 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/custom-method.rb @@ -0,0 +1 @@ +# Faraday cannot currently run PROPFIND requests. Please use another client. \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/full.rb b/test/fixtures/output/ruby/faraday/full.rb new file mode 100644 index 0000000..00cf3c6 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/full.rb @@ -0,0 +1,22 @@ +require 'faraday' + +data = { + :foo => "bar", +} + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'application/x-www-form-urlencoded'} +) + +response = conn.post('/har') do |req| + req.headers['cookie'] = 'foo=bar; bar=baz' + req.headers['accept'] = 'application/json' + req.params['foo'] = ["bar","baz"] + req.params['baz'] = 'abc' + req.params['key'] = 'value' + req.body = URI.encode_www_form(data) +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/headers.rb b/test/fixtures/output/ruby/faraday/headers.rb new file mode 100644 index 0000000..efaaa37 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/headers.rb @@ -0,0 +1,14 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', +) + +response = conn.get('/har') do |req| + req.headers['accept'] = 'application/json' + req.headers['x-foo'] = 'Bar' + req.headers['quoted-value'] = '"quoted" \'string\'' +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/https.rb b/test/fixtures/output/ruby/faraday/https.rb new file mode 100644 index 0000000..8416136 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/https.rb @@ -0,0 +1,11 @@ +require 'faraday' + +conn = Faraday.new( + url: 'https://mockbin.com', +) + +response = conn.get('/har') do |req| +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/jsonObj-multiline.rb b/test/fixtures/output/ruby/faraday/jsonObj-multiline.rb new file mode 100644 index 0000000..e6e66b0 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/jsonObj-multiline.rb @@ -0,0 +1,13 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'application/json'} +) + +response = conn.post('/har') do |req| + req.body = "{\n \"foo\": \"bar\"\n}" +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/jsonObj-null-value.rb b/test/fixtures/output/ruby/faraday/jsonObj-null-value.rb new file mode 100644 index 0000000..d2ecc57 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/jsonObj-null-value.rb @@ -0,0 +1,13 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'application/json'} +) + +response = conn.post('/har') do |req| + req.body = "{\"foo\":null}" +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/malicious.rb b/test/fixtures/output/ruby/faraday/malicious.rb new file mode 100644 index 0000000..a5423a2 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/malicious.rb @@ -0,0 +1,50 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://example.test', +) + +response = conn.post('/%27%22%60$(%(%%7B%7B%7B/0%s//') do |req| + req.headers['\''] = 'squote-key-test' + req.headers['squote-value-test'] = '\'' + req.headers['dquote-value-test'] = '"' + req.headers['`'] = 'backtick-key-test' + req.headers['backtick-value-test'] = '`' + req.headers['$'] = 'dollar-key-test' + req.headers['dollar-parenthesis-value-test'] = '$(' + req.headers['#'] = 'hash-key-test' + req.headers['hash-brace-value-test'] = '#{' + req.headers['%'] = 'percent-key-test' + req.headers['percent-parenthesis-value-test'] = '%(' + req.headers['percent-brace-value-test'] = '%{' + req.headers['double-brace-value-test'] = '{{' + req.headers['null-value-test'] = '\\0' + req.headers['string-fmt-value-test'] = '%s' + req.headers['slash-value-test'] = '\\' + req.params['\''] = 'squote-key-test' + req.params['squote-value-test'] = '\'' + req.params['"'] = 'dquote-key-test' + req.params['dquote-value-test'] = '"' + req.params['`'] = 'backtick-key-test' + req.params['backtick-value-test'] = '`' + req.params['$('] = 'dollar-parenthesis-key-test' + req.params['dollar-parenthesis-value-test'] = '$(' + req.params['#{'] = 'hash-brace-key-test' + req.params['hash-brace-value-test'] = '#{' + req.params['%('] = 'percent-parenthesis-key-test' + req.params['percent-parenthesis-value-test'] = '%(' + req.params['%{'] = 'percent-brace-key-test' + req.params['percent-brace-value-test'] = '%{' + req.params['{{'] = 'double-brace-key-test' + req.params['double-brace-value-test'] = '{{' + req.params['\\0'] = 'null-key-test' + req.params['null-value-test'] = '\\0' + req.params['%s'] = 'string-fmt-key-test' + req.params['string-fmt-value-test'] = '%s' + req.params['\\'] = 'slash-key-test' + req.params['slash-value-test'] = '\\' + req.body = "' \" ` $( #{ %( %{ {{ \\0 %s \\" +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/multipart-data.rb b/test/fixtures/output/ruby/faraday/multipart-data.rb new file mode 100644 index 0000000..225c6f6 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/multipart-data.rb @@ -0,0 +1,13 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'multipart/form-data; boundary=---011000010111000001101001'} +) + +response = conn.post('/har') do |req| + req.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\nHello World\r\n-----011000010111000001101001--\r\n" +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/multipart-file.rb b/test/fixtures/output/ruby/faraday/multipart-file.rb new file mode 100644 index 0000000..4d71689 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/multipart-file.rb @@ -0,0 +1,13 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'multipart/form-data; boundary=---011000010111000001101001'} +) + +response = conn.post('/har') do |req| + req.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\n\r\n-----011000010111000001101001--\r\n" +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/multipart-form-data.rb b/test/fixtures/output/ruby/faraday/multipart-form-data.rb new file mode 100644 index 0000000..fe3e144 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/multipart-form-data.rb @@ -0,0 +1,13 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'multipart/form-data; boundary=---011000010111000001101001'} +) + +response = conn.post('/har') do |req| + req.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n-----011000010111000001101001--\r\n" +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/nested.rb b/test/fixtures/output/ruby/faraday/nested.rb new file mode 100644 index 0000000..1a6966d --- /dev/null +++ b/test/fixtures/output/ruby/faraday/nested.rb @@ -0,0 +1,14 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', +) + +response = conn.get('/har') do |req| + req.params['foo[bar]'] = 'baz,zap' + req.params['fiz'] = 'buz' + req.params['key'] = 'value' +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/query.rb b/test/fixtures/output/ruby/faraday/query.rb new file mode 100644 index 0000000..c418c55 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/query.rb @@ -0,0 +1,14 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', +) + +response = conn.get('/har') do |req| + req.params['foo'] = ["bar","baz"] + req.params['baz'] = 'abc' + req.params['key'] = 'value' +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/short.rb b/test/fixtures/output/ruby/faraday/short.rb new file mode 100644 index 0000000..8ce34f7 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/short.rb @@ -0,0 +1,11 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', +) + +response = conn.get('/har') do |req| +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/text-plain.rb b/test/fixtures/output/ruby/faraday/text-plain.rb new file mode 100644 index 0000000..b253cc3 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/text-plain.rb @@ -0,0 +1,13 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', + headers: {'Content-Type' => 'text/plain'} +) + +response = conn.post('/har') do |req| + req.body = "Hello World" +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/faraday/unparseable-query.rb b/test/fixtures/output/ruby/faraday/unparseable-query.rb new file mode 100644 index 0000000..8ce34f7 --- /dev/null +++ b/test/fixtures/output/ruby/faraday/unparseable-query.rb @@ -0,0 +1,11 @@ +require 'faraday' + +conn = Faraday.new( + url: 'http://mockbin.com', +) + +response = conn.get('/har') do |req| +end + +puts response.status +puts response.body \ No newline at end of file diff --git a/test/fixtures/output/ruby/native/malicious.rb b/test/fixtures/output/ruby/native/malicious.rb index 9755a8a..6294fb8 100644 --- a/test/fixtures/output/ruby/native/malicious.rb +++ b/test/fixtures/output/ruby/native/malicious.rb @@ -6,11 +6,16 @@ http = Net::HTTP.new(url.host, url.port) request = Net::HTTP::Post.new(url) +request["'"] = 'squote-key-test' request["squote-value-test"] = '\'' request["dquote-value-test"] = '"' +request["`"] = 'backtick-key-test' request["backtick-value-test"] = '`' +request["$"] = 'dollar-key-test' request["dollar-parenthesis-value-test"] = '$(' +request["#"] = 'hash-key-test' request["hash-brace-value-test"] = '#{' +request["%"] = 'percent-key-test' request["percent-parenthesis-value-test"] = '%(' request["percent-brace-value-test"] = '%{' request["double-brace-value-test"] = '{{' diff --git a/test/fixtures/output/ruby/native/unparseable-query.rb b/test/fixtures/output/ruby/native/unparseable-query.rb new file mode 100644 index 0000000..3653394 --- /dev/null +++ b/test/fixtures/output/ruby/native/unparseable-query.rb @@ -0,0 +1,11 @@ +require 'uri' +require 'net/http' + +url = URI("http://mockbin.com/har?&&a=b&&") + +http = Net::HTTP.new(url.host, url.port) + +request = Net::HTTP::Get.new(url) + +response = http.request(request) +puts response.read_body \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/application-form-encoded.rs b/test/fixtures/output/rust/reqwest/application-form-encoded.rs new file mode 100644 index 0000000..4a96f4a --- /dev/null +++ b/test/fixtures/output/rust/reqwest/application-form-encoded.rs @@ -0,0 +1,29 @@ +use serde_json::json; +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let payload = json!({ + "foo": "bar", + "hello": "world" + }); + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("content-type", "application/x-www-form-urlencoded".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.post(url) + .headers(headers) + .form(&payload) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/application-json.rs b/test/fixtures/output/rust/reqwest/application-json.rs new file mode 100644 index 0000000..d3105ac --- /dev/null +++ b/test/fixtures/output/rust/reqwest/application-json.rs @@ -0,0 +1,33 @@ +use serde_json::json; +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let payload = json!({ + "number": 1, + "string": "f\"oo", + "arr": (1, 2, 3), + "nested": json!({"a": "b"}), + "arr_mix": (1, "a", json!({"arr_mix_nested": json!({})})), + "boolean": false + }); + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("content-type", "application/json".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.post(url) + .headers(headers) + .json(&payload) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/compression.rs b/test/fixtures/output/rust/reqwest/compression.rs new file mode 100644 index 0000000..df4fdb4 --- /dev/null +++ b/test/fixtures/output/rust/reqwest/compression.rs @@ -0,0 +1,22 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("accept-encoding", "deflate, gzip, br".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.get(url) + .headers(headers) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/cookies.rs b/test/fixtures/output/rust/reqwest/cookies.rs new file mode 100644 index 0000000..c420b5a --- /dev/null +++ b/test/fixtures/output/rust/reqwest/cookies.rs @@ -0,0 +1,22 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("cookie", "foo=bar; bar=baz".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.post(url) + .headers(headers) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/custom-method.rs b/test/fixtures/output/rust/reqwest/custom-method.rs new file mode 100644 index 0000000..449e46c --- /dev/null +++ b/test/fixtures/output/rust/reqwest/custom-method.rs @@ -0,0 +1,19 @@ +use std::str::FromStr; +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let client = reqwest::Client::new(); + let response = client.request(reqwest::Method::from_str("PROPFIND").unwrap(), url) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/full.rs b/test/fixtures/output/rust/reqwest/full.rs new file mode 100644 index 0000000..486a102 --- /dev/null +++ b/test/fixtures/output/rust/reqwest/full.rs @@ -0,0 +1,35 @@ +use serde_json::json; +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let querystring = [ + ("foo", "barbaz"), + ("baz", "abc"), + ("key", "value"), + ]; + + let payload = json!({"foo": "bar"}); + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("cookie", "foo=bar; bar=baz".parse().unwrap()); + headers.insert("accept", "application/json".parse().unwrap()); + headers.insert("content-type", "application/x-www-form-urlencoded".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.post(url) + .query(&querystring) + .headers(headers) + .form(&payload) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/headers.rs b/test/fixtures/output/rust/reqwest/headers.rs new file mode 100644 index 0000000..59cfbbc --- /dev/null +++ b/test/fixtures/output/rust/reqwest/headers.rs @@ -0,0 +1,24 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("accept", "application/json".parse().unwrap()); + headers.insert("x-foo", "Bar".parse().unwrap()); + headers.insert("quoted-value", "\"quoted\" 'string'".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.get(url) + .headers(headers) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/https.rs b/test/fixtures/output/rust/reqwest/https.rs new file mode 100644 index 0000000..2b783c2 --- /dev/null +++ b/test/fixtures/output/rust/reqwest/https.rs @@ -0,0 +1,18 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "https://mockbin.com/har"; + + let client = reqwest::Client::new(); + let response = client.get(url) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/jsonObj-multiline.rs b/test/fixtures/output/rust/reqwest/jsonObj-multiline.rs new file mode 100644 index 0000000..c883631 --- /dev/null +++ b/test/fixtures/output/rust/reqwest/jsonObj-multiline.rs @@ -0,0 +1,26 @@ +use serde_json::json; +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let payload = json!({"foo": "bar"}); + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("content-type", "application/json".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.post(url) + .headers(headers) + .json(&payload) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/jsonObj-null-value.rs b/test/fixtures/output/rust/reqwest/jsonObj-null-value.rs new file mode 100644 index 0000000..daa72c9 --- /dev/null +++ b/test/fixtures/output/rust/reqwest/jsonObj-null-value.rs @@ -0,0 +1,26 @@ +use serde_json::json; +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let payload = json!({"foo": json!(null)}); + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("content-type", "application/json".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.post(url) + .headers(headers) + .json(&payload) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/malicious.rs b/test/fixtures/output/rust/reqwest/malicious.rs new file mode 100644 index 0000000..f6e19d1 --- /dev/null +++ b/test/fixtures/output/rust/reqwest/malicious.rs @@ -0,0 +1,67 @@ +use serde_json::json; +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//"; + + let querystring = [ + ("'", "squote-key-test"), + ("squote-value-test", "'"), + ("\"", "dquote-key-test"), + ("dquote-value-test", "\""), + ("`", "backtick-key-test"), + ("backtick-value-test", "`"), + ("$(", "dollar-parenthesis-key-test"), + ("dollar-parenthesis-value-test", "$("), + ("#{", "hash-brace-key-test"), + ("hash-brace-value-test", "#{"), + ("%(", "percent-parenthesis-key-test"), + ("percent-parenthesis-value-test", "%("), + ("%{", "percent-brace-key-test"), + ("percent-brace-value-test", "%{"), + ("{{", "double-brace-key-test"), + ("double-brace-value-test", "{{"), + ("\\0", "null-key-test"), + ("null-value-test", "\\0"), + ("%s", "string-fmt-key-test"), + ("string-fmt-value-test", "%s"), + ("\\", "slash-key-test"), + ("slash-value-test", "\\"), + ]; + + let payload = "' \" ` $( #{ %( %{ {{ \\0 %s \\"; + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("'", "squote-key-test".parse().unwrap()); + headers.insert("squote-value-test", "'".parse().unwrap()); + headers.insert("dquote-value-test", "\"".parse().unwrap()); + headers.insert("`", "backtick-key-test".parse().unwrap()); + headers.insert("backtick-value-test", "`".parse().unwrap()); + headers.insert("$", "dollar-key-test".parse().unwrap()); + headers.insert("dollar-parenthesis-value-test", "$(".parse().unwrap()); + headers.insert("#", "hash-key-test".parse().unwrap()); + headers.insert("hash-brace-value-test", "#{".parse().unwrap()); + headers.insert("%", "percent-key-test".parse().unwrap()); + headers.insert("percent-parenthesis-value-test", "%(".parse().unwrap()); + headers.insert("percent-brace-value-test", "%{".parse().unwrap()); + headers.insert("double-brace-value-test", "{{".parse().unwrap()); + headers.insert("null-value-test", "\\0".parse().unwrap()); + headers.insert("string-fmt-value-test", "%s".parse().unwrap()); + headers.insert("slash-value-test", "\\".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.post(url) + .query(&querystring) + .headers(headers) + .body(payload) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/multipart-data.rs b/test/fixtures/output/rust/reqwest/multipart-data.rs new file mode 100644 index 0000000..ae79cbf --- /dev/null +++ b/test/fixtures/output/rust/reqwest/multipart-data.rs @@ -0,0 +1,33 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + async fn file_to_part(file_name: &'static str) -> reqwest::multipart::Part { + let file = tokio::fs::File::open(file_name).await.unwrap(); + let stream = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new()); + let body = reqwest::Body::wrap_stream(stream); + reqwest::multipart::Part::stream(body) + .file_name(file_name) + .mime_str("text/plain").unwrap() + } + + let form = reqwest::multipart::Form::new() + .part("foo", file_to_part("hello.txt").await); + let mut headers = reqwest::header::HeaderMap::new(); + + let client = reqwest::Client::new(); + let response = client.post(url) + .multipart(form) + .headers(headers) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/multipart-file.rs b/test/fixtures/output/rust/reqwest/multipart-file.rs new file mode 100644 index 0000000..64f372b --- /dev/null +++ b/test/fixtures/output/rust/reqwest/multipart-file.rs @@ -0,0 +1,33 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + async fn file_to_part(file_name: &'static str) -> reqwest::multipart::Part { + let file = tokio::fs::File::open(file_name).await.unwrap(); + let stream = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new()); + let body = reqwest::Body::wrap_stream(stream); + reqwest::multipart::Part::stream(body) + .file_name(file_name) + .mime_str("text/plain").unwrap() + } + + let form = reqwest::multipart::Form::new() + .part("foo", file_to_part("test/fixtures/files/hello.txt").await); + let mut headers = reqwest::header::HeaderMap::new(); + + let client = reqwest::Client::new(); + let response = client.post(url) + .multipart(form) + .headers(headers) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/multipart-form-data.rs b/test/fixtures/output/rust/reqwest/multipart-form-data.rs new file mode 100644 index 0000000..a2907cc --- /dev/null +++ b/test/fixtures/output/rust/reqwest/multipart-form-data.rs @@ -0,0 +1,24 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let form = reqwest::multipart::Form::new() + .text("foo", "bar"); + let mut headers = reqwest::header::HeaderMap::new(); + + let client = reqwest::Client::new(); + let response = client.post(url) + .multipart(form) + .headers(headers) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/nested.rs b/test/fixtures/output/rust/reqwest/nested.rs new file mode 100644 index 0000000..77ddc19 --- /dev/null +++ b/test/fixtures/output/rust/reqwest/nested.rs @@ -0,0 +1,25 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let querystring = [ + ("foo[bar]", "baz,zap"), + ("fiz", "buz"), + ("key", "value"), + ]; + + let client = reqwest::Client::new(); + let response = client.get(url) + .query(&querystring) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/query.rs b/test/fixtures/output/rust/reqwest/query.rs new file mode 100644 index 0000000..753741c --- /dev/null +++ b/test/fixtures/output/rust/reqwest/query.rs @@ -0,0 +1,25 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let querystring = [ + ("foo", "barbaz"), + ("baz", "abc"), + ("key", "value"), + ]; + + let client = reqwest::Client::new(); + let response = client.get(url) + .query(&querystring) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/short.rs b/test/fixtures/output/rust/reqwest/short.rs new file mode 100644 index 0000000..4250488 --- /dev/null +++ b/test/fixtures/output/rust/reqwest/short.rs @@ -0,0 +1,18 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let client = reqwest::Client::new(); + let response = client.get(url) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/text-plain.rs b/test/fixtures/output/rust/reqwest/text-plain.rs new file mode 100644 index 0000000..3a47ddf --- /dev/null +++ b/test/fixtures/output/rust/reqwest/text-plain.rs @@ -0,0 +1,26 @@ +use serde_json::json; +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har"; + + let payload = "Hello World"; + + let mut headers = reqwest::header::HeaderMap::new(); + headers.insert("content-type", "text/plain".parse().unwrap()); + + let client = reqwest::Client::new(); + let response = client.post(url) + .headers(headers) + .body(payload) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/rust/reqwest/unparseable-query.rs b/test/fixtures/output/rust/reqwest/unparseable-query.rs new file mode 100644 index 0000000..c402cdf --- /dev/null +++ b/test/fixtures/output/rust/reqwest/unparseable-query.rs @@ -0,0 +1,18 @@ +use reqwest; + +#[tokio::main] +pub async fn main() { + let url = "http://mockbin.com/har?&&a=b&&"; + + let client = reqwest::Client::new(); + let response = client.get(url) + .send() + .await; + + let results = response.unwrap() + .json::() + .await + .unwrap(); + + dbg!(results); +} \ No newline at end of file diff --git a/test/fixtures/output/shell/curl/malicious.sh b/test/fixtures/output/shell/curl/malicious.sh index 19c1c8d..ee64132 100644 --- a/test/fixtures/output/shell/curl/malicious.sh +++ b/test/fixtures/output/shell/curl/malicious.sh @@ -1,5 +1,10 @@ curl --request POST \ --url 'http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'\''=squote-key-test&squote-value-test='\''&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C' \ + --header '#: hash-key-test' \ + --header '$: dollar-key-test' \ + --header '%: percent-key-test' \ + --header ''\'': squote-key-test' \ + --header '`: backtick-key-test' \ --header 'backtick-value-test: `' \ --header 'dollar-parenthesis-value-test: $(' \ --header 'double-brace-value-test: {{' \ diff --git a/test/fixtures/output/shell/curl/unparseable-query.sh b/test/fixtures/output/shell/curl/unparseable-query.sh new file mode 100644 index 0000000..1b2f29c --- /dev/null +++ b/test/fixtures/output/shell/curl/unparseable-query.sh @@ -0,0 +1,2 @@ +curl --request GET \ + --url 'http://mockbin.com/har?&&a=b&&' \ No newline at end of file diff --git a/test/fixtures/output/shell/httpie/application-json.sh b/test/fixtures/output/shell/httpie/application-json.sh index 073a258..979ef3a 100644 --- a/test/fixtures/output/shell/httpie/application-json.sh +++ b/test/fixtures/output/shell/httpie/application-json.sh @@ -1,3 +1,3 @@ -echo '{"number":1,"string":"f\"oo","arr":[1,2,3],"nested":{"a":"b"},"arr_mix":[1,"a",{"arr_mix_nested":{}}],"boolean":false}' | \ +printf '%s' '{"number":1,"string":"f\"oo","arr":[1,2,3],"nested":{"a":"b"},"arr_mix":[1,"a",{"arr_mix_nested":{}}],"boolean":false}' | \ http POST http://mockbin.com/har \ content-type:application/json diff --git a/test/fixtures/output/shell/httpie/malicious.sh b/test/fixtures/output/shell/httpie/malicious.sh index 5a44864..e9e64d3 100644 --- a/test/fixtures/output/shell/httpie/malicious.sh +++ b/test/fixtures/output/shell/httpie/malicious.sh @@ -1,5 +1,10 @@ -echo ''\'' " ` $( #{ %( %{ {{ \0 %s \' | \ +printf '%s' ''\'' " ` $( #{ %( %{ {{ \0 %s \' | \ http POST 'http://example.test/%27%22%60$(%(%%7B%7B%7B/0%s//?'\''=squote-key-test&squote-value-test='\''&%22=dquote-key-test&dquote-value-test=%22&%60=backtick-key-test&backtick-value-test=%60&%24(=dollar-parenthesis-key-test&dollar-parenthesis-value-test=%24(&%23%7B=hash-brace-key-test&hash-brace-value-test=%23%7B&%25(=percent-parenthesis-key-test&percent-parenthesis-value-test=%25(&%25%7B=percent-brace-key-test&percent-brace-value-test=%25%7B&%7B%7B=double-brace-key-test&double-brace-value-test=%7B%7B&%5C0=null-key-test&null-value-test=%5C0&%25s=string-fmt-key-test&string-fmt-value-test=%25s&%5C=slash-key-test&slash-value-test=%5C' \ + '#':hash-key-test \ + '$':dollar-key-test \ + %:percent-key-test \ + ''\''':squote-key-test \ + '`':backtick-key-test \ backtick-value-test:'`' \ dollar-parenthesis-value-test:'$(' \ double-brace-value-test:'{{' \ diff --git a/test/fixtures/output/shell/httpie/unparseable-query.sh b/test/fixtures/output/shell/httpie/unparseable-query.sh new file mode 100644 index 0000000..0a973a2 --- /dev/null +++ b/test/fixtures/output/shell/httpie/unparseable-query.sh @@ -0,0 +1 @@ +http GET 'http://mockbin.com/har?&&a=b&&' \ No newline at end of file diff --git a/test/fixtures/output/shell/wget/malicious.sh b/test/fixtures/output/shell/wget/malicious.sh index cdd5905..3649342 100644 --- a/test/fixtures/output/shell/wget/malicious.sh +++ b/test/fixtures/output/shell/wget/malicious.sh @@ -1,10 +1,15 @@ wget --quiet \ --method POST \ + --header ''\'': squote-key-test' \ --header 'squote-value-test: '\''' \ --header 'dquote-value-test: "' \ + --header '`: backtick-key-test' \ --header 'backtick-value-test: `' \ + --header '$: dollar-key-test' \ --header 'dollar-parenthesis-value-test: $(' \ + --header '#: hash-key-test' \ --header 'hash-brace-value-test: #{' \ + --header '%: percent-key-test' \ --header 'percent-parenthesis-value-test: %(' \ --header 'percent-brace-value-test: %{' \ --header 'double-brace-value-test: {{' \ diff --git a/test/fixtures/output/shell/wget/unparseable-query.sh b/test/fixtures/output/shell/wget/unparseable-query.sh new file mode 100644 index 0000000..ef5ca27 --- /dev/null +++ b/test/fixtures/output/shell/wget/unparseable-query.sh @@ -0,0 +1,4 @@ +wget --quiet \ + --method GET \ + --output-document \ + - 'http://mockbin.com/har?&&a=b&&' \ No newline at end of file diff --git a/test/fixtures/output/swift/nsurlsession/malicious.swift b/test/fixtures/output/swift/nsurlsession/malicious.swift index a6c5ff6..7dd4777 100644 --- a/test/fixtures/output/swift/nsurlsession/malicious.swift +++ b/test/fixtures/output/swift/nsurlsession/malicious.swift @@ -1,11 +1,16 @@ import Foundation let headers = [ + "'": "squote-key-test", "squote-value-test": "'", "dquote-value-test": "\"", + "`": "backtick-key-test", "backtick-value-test": "`", + "$": "dollar-key-test", "dollar-parenthesis-value-test": "$(", + "#": "hash-key-test", "hash-brace-value-test": "#{", + "%": "percent-key-test", "percent-parenthesis-value-test": "%(", "percent-brace-value-test": "%{", "double-brace-value-test": "{{", diff --git a/test/fixtures/output/swift/nsurlsession/unparseable-query.swift b/test/fixtures/output/swift/nsurlsession/unparseable-query.swift new file mode 100644 index 0000000..995fb60 --- /dev/null +++ b/test/fixtures/output/swift/nsurlsession/unparseable-query.swift @@ -0,0 +1,18 @@ +import Foundation + +let request = NSMutableURLRequest(url: NSURL(string: "http://mockbin.com/har?&&a=b&&")! as URL, + cachePolicy: .useProtocolCachePolicy, + timeoutInterval: 10.0) +request.httpMethod = "GET" + +let session = URLSession.shared +let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in + if (error != nil) { + print(error) + } else { + let httpResponse = response as? HTTPURLResponse + print(httpResponse) + } +}) + +dataTask.resume() \ No newline at end of file diff --git a/test/fixtures/requests/malicious.json b/test/fixtures/requests/malicious.json index 1ad354e..a701153 100644 --- a/test/fixtures/requests/malicious.json +++ b/test/fixtures/requests/malicious.json @@ -92,6 +92,10 @@ } ], "headers": [ + { + "name": "'", + "value": "squote-key-test" + }, { "name": "squote-value-test", "value": "'" @@ -100,18 +104,34 @@ "name": "dquote-value-test", "value": "\"" }, + { + "name": "`", + "value": "backtick-key-test" + }, { "name": "backtick-value-test", "value": "`" }, + { + "name": "$", + "value": "dollar-key-test" + }, { "name": "dollar-parenthesis-value-test", "value": "$(" }, + { + "name": "#", + "value": "hash-key-test" + }, { "name": "hash-brace-value-test", "value": "#{" }, + { + "name": "%", + "value": "percent-key-test" + }, { "name": "percent-parenthesis-value-test", "value": "%(" diff --git a/test/fixtures/requests/unparseable-query.json b/test/fixtures/requests/unparseable-query.json new file mode 100644 index 0000000..30875b6 --- /dev/null +++ b/test/fixtures/requests/unparseable-query.json @@ -0,0 +1,11 @@ +{ + "method": "GET", + "url": "http://mockbin.com/har?&&a=b&&", + "queryString": [ + { + "name": "a", + "value": "b" + } + ], + "httpVersion": "HTTP/1.1" +} diff --git a/test/targets.js b/test/targets.js index 58d77e3..0e4cf6c 100644 --- a/test/targets.js +++ b/test/targets.js @@ -92,6 +92,9 @@ describe('Available Targets', function () { fixtures['available-targets'].should.containEql(target) }) }) + + // Update with: + // node -e "console.log(JSON.stringify(require('.').availableTargets(), null, 2))" > ./test/fixtures/available-targets.json }) describe('Custom targets', function () { diff --git a/test/targets/crystal/native.js b/test/targets/crystal/native.js new file mode 100644 index 0000000..b77cc77 --- /dev/null +++ b/test/targets/crystal/native.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = function (snippet, fixtures) {} diff --git a/test/targets/java/restclient.js b/test/targets/java/restclient.js new file mode 100644 index 0000000..9ad8c17 --- /dev/null +++ b/test/targets/java/restclient.js @@ -0,0 +1,5 @@ +'use strict' + +require('should') + +module.exports = function (snippet, fixtures) {} diff --git a/test/targets/ruby/faraday.js b/test/targets/ruby/faraday.js new file mode 100644 index 0000000..b77cc77 --- /dev/null +++ b/test/targets/ruby/faraday.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = function (snippet, fixtures) {} diff --git a/test/targets/rust/reqwest.js b/test/targets/rust/reqwest.js new file mode 100644 index 0000000..b77cc77 --- /dev/null +++ b/test/targets/rust/reqwest.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = function (snippet, fixtures) {}