diff --git a/.eslintignore b/.eslintignore index a34884f0..8ee5d6f0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,12 +1,12 @@ !.alexrc.js # api subpackage -packages/api/.nyc_output/ +packages/api/coverage/ packages/api/dist/ packages/api/test/__fixtures__/sdk/ # httpsnippet-client-api subpackage -packages/httpsnippet-client-api/.nyc_output/ +packages/httpsnippet-client-api/coverage/ packages/httpsnippet-client-api/dist/ packages/httpsnippet-client-api/node_modules/ packages/httpsnippet-client-api/test/__datasets__/**/output.js diff --git a/.prettierignore b/.prettierignore index 0ba7e5c6..36c0b186 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,10 +2,9 @@ CHANGELOG.md # api subpackage packages/api/.api/ -packages/api/.nyc_output/ +packages/api/coverage/ packages/api/.eslint* packages/api/.gitignore -packages/api/.mocharc.json packages/api/.prettier* packages/api/CHANGELOG.md packages/api/dist/ @@ -13,6 +12,6 @@ packages/api/example.js packages/api/test/__fixtures__/sdk/ # httpsnippet-client-api subpackage -packages/httpsnippet-client-api/.nyc_output/ +packages/httpsnippet-client-api/coverage/ packages/httpsnippet-client-api/dist/ packages/httpsnippet-client-api/test/__datasets__/**/output.js diff --git a/package-lock.json b/package-lock.json index 8e32a8ed..d2615441 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,11 @@ "./packages/*" ], "devDependencies": { - "@commitlint/cli": "^17.4.2", - "@commitlint/config-conventional": "^17.4.2", - "@readme/eslint-config": "^10.5.0", + "@commitlint/cli": "^17.6.6", + "@commitlint/config-conventional": "^17.6.6", + "@readme/eslint-config": "^10.6.2", "alex": "^11.0.0", - "eslint": "^8.33.0", + "eslint": "^8.44.0", "husky": "^8.0.3", "prettier": "^2.8.0" }, @@ -21,6 +21,15 @@ "node": ">=16" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", @@ -236,6 +245,15 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-simple-access": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", @@ -260,10 +278,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "engines": { "node": ">=6.9.0" } @@ -369,9 +396,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", - "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "version": "7.22.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", + "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -380,6 +407,183 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.20.13", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", @@ -436,29 +640,36 @@ } }, "node_modules/@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, "node_modules/@commitlint/cli": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.4.2.tgz", - "integrity": "sha512-0rPGJ2O1owhpxMIXL9YJ2CgPkdrFLKZElIZHXDN8L8+qWK1DGH7Q7IelBT1pchXTYTuDlqkOTdh//aTvT3bSUA==", + "version": "17.6.6", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.6.6.tgz", + "integrity": "sha512-sTKpr2i/Fjs9OmhU+beBxjPavpnLSqZaO6CzwKVq2Tc4UYVTMFgpKOslDhUBVlfAUBfjVO8ParxC/MXkIOevEA==", "dev": true, "dependencies": { - "@commitlint/format": "^17.4.0", - "@commitlint/lint": "^17.4.2", - "@commitlint/load": "^17.4.2", - "@commitlint/read": "^17.4.2", - "@commitlint/types": "^17.4.0", + "@commitlint/format": "^17.4.4", + "@commitlint/lint": "^17.6.6", + "@commitlint/load": "^17.5.0", + "@commitlint/read": "^17.5.1", + "@commitlint/types": "^17.4.4", "execa": "^5.0.0", "lodash.isfunction": "^3.0.9", "resolve-from": "5.0.0", @@ -473,9 +684,9 @@ } }, "node_modules/@commitlint/config-conventional": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.4.2.tgz", - "integrity": "sha512-JVo1moSj5eDMoql159q8zKCU8lkOhQ+b23Vl3LVVrS6PXDLQIELnJ34ChQmFVbBdSSRNAbbXnRDhosFU+wnuHw==", + "version": "17.6.6", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.6.6.tgz", + "integrity": "sha512-phqPz3BDhfj49FUYuuZIuDiw+7T6gNAEy7Yew1IBHqSohVUCWOK2FXMSAExzS2/9X+ET93g0Uz83KjiHDOOFag==", "dev": true, "dependencies": { "conventional-changelog-conventionalcommits": "^5.0.0" @@ -485,12 +696,12 @@ } }, "node_modules/@commitlint/config-validator": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.0.tgz", - "integrity": "sha512-Sa/+8KNpDXz4zT4bVbz2fpFjvgkPO6u2V2fP4TKgt6FjmOw2z3eEX859vtfeaTav/ukBw0/0jr+5ZTZp9zCBhA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.4.tgz", + "integrity": "sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "ajv": "^8.11.0" }, "engines": { @@ -520,12 +731,12 @@ "dev": true }, "node_modules/@commitlint/ensure": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.4.0.tgz", - "integrity": "sha512-7oAxt25je0jeQ/E0O/M8L3ADb1Cvweu/5lc/kYF8g/kXatI0wxGE5La52onnAUAWeWlsuvBNar15WcrmDmr5Mw==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.4.4.tgz", + "integrity": "sha512-AHsFCNh8hbhJiuZ2qHv/m59W/GRE9UeOXbkOqxYMNNg9pJ7qELnFcwj5oYpa6vzTSHtPGKf3C2yUFNy1GGHq6g==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", @@ -546,12 +757,12 @@ } }, "node_modules/@commitlint/format": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.0.tgz", - "integrity": "sha512-Z2bWAU5+f1YZh9W76c84J8iLIWIvvm+mzqogTz0Nsc1x6EHW0Z2gI38g5HAjB0r0I3ZjR15IDEJKhsxyblcyhA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz", + "integrity": "sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "chalk": "^4.1.0" }, "engines": { @@ -559,43 +770,43 @@ } }, "node_modules/@commitlint/is-ignored": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.4.2.tgz", - "integrity": "sha512-1b2Y2qJ6n7bHG9K6h8S4lBGUl6kc7mMhJN9gy1SQfUZqe92ToDjUTtgNWb6LbzR1X8Cq4SEus4VU8Z/riEa94Q==", + "version": "17.6.6", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.6.6.tgz", + "integrity": "sha512-4Fw875faAKO+2nILC04yW/2Vy/wlV3BOYCSQ4CEFzriPEprc1Td2LILmqmft6PDEK5Sr14dT9tEzeaZj0V56Gg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", - "semver": "7.3.8" + "@commitlint/types": "^17.4.4", + "semver": "7.5.2" }, "engines": { "node": ">=v14" } }, "node_modules/@commitlint/lint": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.4.2.tgz", - "integrity": "sha512-HcymabrdBhsDMNzIv146+ZPNBPBK5gMNsVH+el2lCagnYgCi/4ixrHooeVyS64Fgce2K26+MC7OQ4vVH8wQWVw==", + "version": "17.6.6", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.6.6.tgz", + "integrity": "sha512-5bN+dnHcRLkTvwCHYMS7Xpbr+9uNi0Kq5NR3v4+oPNx6pYXt8ACuw9luhM/yMgHYwW0ajIR20wkPAFkZLEMGmg==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^17.4.2", - "@commitlint/parse": "^17.4.2", - "@commitlint/rules": "^17.4.2", - "@commitlint/types": "^17.4.0" + "@commitlint/is-ignored": "^17.6.6", + "@commitlint/parse": "^17.6.5", + "@commitlint/rules": "^17.6.5", + "@commitlint/types": "^17.4.4" }, "engines": { "node": ">=v14" } }, "node_modules/@commitlint/load": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.4.2.tgz", - "integrity": "sha512-Si++F85rJ9t4hw6JcOw1i2h0fdpdFQt0YKwjuK4bk9KhFjyFkRxvR3SB2dPaMs+EwWlDrDBGL+ygip1QD6gmPw==", + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.5.0.tgz", + "integrity": "sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.4.0", + "@commitlint/config-validator": "^17.4.4", "@commitlint/execute-rule": "^17.4.0", - "@commitlint/resolve-extends": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/resolve-extends": "^17.4.4", + "@commitlint/types": "^17.4.4", "@types/node": "*", "chalk": "^4.1.0", "cosmiconfig": "^8.0.0", @@ -605,7 +816,7 @@ "lodash.uniq": "^4.5.0", "resolve-from": "^5.0.0", "ts-node": "^10.8.1", - "typescript": "^4.6.4" + "typescript": "^4.6.4 || ^5.0.0" }, "engines": { "node": ">=v14" @@ -621,12 +832,12 @@ } }, "node_modules/@commitlint/parse": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.4.2.tgz", - "integrity": "sha512-DK4EwqhxfXpyCA+UH8TBRIAXAfmmX4q9QRBz/2h9F9sI91yt6mltTrL6TKURMcjUVmgaB80wgS9QybNIyVBIJA==", + "version": "17.6.5", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.6.5.tgz", + "integrity": "sha512-0zle3bcn1Hevw5Jqpz/FzEWNo2KIzUbc1XyGg6WrWEoa6GH3A1pbqNF6MvE6rjuy6OY23c8stWnb4ETRZyN+Yw==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "conventional-changelog-angular": "^5.0.11", "conventional-commits-parser": "^3.2.2" }, @@ -635,15 +846,15 @@ } }, "node_modules/@commitlint/read": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.4.2.tgz", - "integrity": "sha512-hasYOdbhEg+W4hi0InmXHxtD/1favB4WdwyFxs1eOy/DvMw6+2IZBmATgGOlqhahsypk4kChhxjAFJAZ2F+JBg==", + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.5.1.tgz", + "integrity": "sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==", "dev": true, "dependencies": { "@commitlint/top-level": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "fs-extra": "^11.0.0", - "git-raw-commits": "^2.0.0", + "git-raw-commits": "^2.0.11", "minimist": "^1.2.6" }, "engines": { @@ -651,13 +862,13 @@ } }, "node_modules/@commitlint/resolve-extends": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.0.tgz", - "integrity": "sha512-3JsmwkrCzoK8sO22AzLBvNEvC1Pmdn/65RKXzEtQMy6oYMl0Snrq97a5bQQEFETF0VsvbtUuKttLqqgn99OXRQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz", + "integrity": "sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/config-validator": "^17.4.4", + "@commitlint/types": "^17.4.4", "import-fresh": "^3.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0", @@ -668,15 +879,15 @@ } }, "node_modules/@commitlint/rules": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.4.2.tgz", - "integrity": "sha512-OGrPsMb9Fx3/bZ64/EzJehY9YDSGWzp81Pj+zJiY+r/NSgJI3nUYdlS37jykNIugzazdEXfMtQ10kmA+Kx2pZQ==", + "version": "17.6.5", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.6.5.tgz", + "integrity": "sha512-uTB3zSmnPyW2qQQH+Dbq2rekjlWRtyrjDo4aLFe63uteandgkI+cc0NhhbBAzcXShzVk0qqp8SlkQMu0mgHg/A==", "dev": true, "dependencies": { - "@commitlint/ensure": "^17.4.0", + "@commitlint/ensure": "^17.4.4", "@commitlint/message": "^17.4.2", "@commitlint/to-lines": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "execa": "^5.0.0" }, "engines": { @@ -705,9 +916,9 @@ } }, "node_modules/@commitlint/types": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.0.tgz", - "integrity": "sha512-2NjAnq5IcxY9kXtUeO2Ac0aPpvkuOmwbH/BxIm36XXK5LtWFObWJWjXOA+kcaABMrthjWu6la+FUpyYFMHRvbA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", + "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", "dev": true, "dependencies": { "chalk": "^4.1.0" @@ -729,23 +940,23 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", - "integrity": "sha512-922xqFsTpHs6D0BUiG4toiyPOMc8/jafnWKxz1KWgS4XzKPy2qXf1Pe6UFuNSCQqt6tOuhAWXBNuuyUhJmw9Vg==", + "version": "0.39.4", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.39.4.tgz", + "integrity": "sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg==", "dev": true, "dependencies": { "comment-parser": "1.3.1", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" }, "engines": { - "node": "^14 || ^16 || ^17 || ^18 || ^19" + "node": ">=16" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.1.2.tgz", - "integrity": "sha512-7qELuQWWjVDdVsFQ5+beUl+KPczrEDA7S3zM4QUd/bJl7oXgsmpXaEVqrRTnOBqenOV4rWf2kVZk2Ot085zPWA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" @@ -754,18 +965,27 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", + "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -780,15 +1000,24 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@exodus/schemasafe": { "version": "1.0.0-rc.9", "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.0.0-rc.9.tgz", "integrity": "sha512-dGGHpb61hLwifAu7sotuHFDBw6GTdpG8aKC0fsK17EuTzMRvUrH7lEAr6LTJ+sx3AZYed9yZ77rltVDHyg2hRg==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -925,127 +1154,486 @@ "node": ">=8" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "node_modules/@jest/console": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.1.tgz", + "integrity": "sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q==", "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "slash": "^3.0.0" + }, "engines": { - "node": ">=6.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "node_modules/@jest/core": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.1.tgz", + "integrity": "sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@jsdevtools/ono": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@jest/console": "^29.6.1", + "@jest/reporters": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.6.1", + "jest-haste-map": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-resolve-dependencies": "^29.6.1", + "jest-runner": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "jest-watcher": "^29.6.1", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { - "node": ">= 8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@npmcli/config": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-6.1.0.tgz", - "integrity": "sha512-fPVlvy6MmSN0zgJU1TOD0fimnKVmcFpK3WuPyIQfNtCE+HMkFDN1mIKBKhUNow5QYHmCzMvGbu7pAgwdlSoaQA==", + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@jest/environment": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.1.tgz", + "integrity": "sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A==", "dev": true, "dependencies": { - "@npmcli/map-workspaces": "^3.0.0", - "ini": "^3.0.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "read-package-json-fast": "^3.0.0", - "semver": "^7.3.5", - "walk-up-path": "^1.0.0" + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-mock": "^29.6.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@npmcli/config/node_modules/ini": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", - "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", + "node_modules/@jest/expect": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg==", "dev": true, + "dependencies": { + "expect": "^29.6.1", + "jest-snapshot": "^29.6.1" + }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@npmcli/map-workspaces": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.0.tgz", - "integrity": "sha512-aaEDwQ+fUH80iNYSDAcKv9lxIFWsgGkLjIPZENyep75hKeAk2CfSbCAZ6IHDDrVlNybvvNmlFjPap6GdTz9cCw==", + "node_modules/@jest/expect-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.1.tgz", + "integrity": "sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==", "dev": true, "dependencies": { - "@npmcli/name-from-folder": "^1.0.1", - "glob": "^8.0.1", - "minimatch": "^5.0.1", - "read-package-json-fast": "^3.0.0" + "jest-get-type": "^29.4.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/@jest/fake-timers": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.1.tgz", + "integrity": "sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "@jest/types": "^29.6.1", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.6.1", + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@npmcli/map-workspaces/node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "node_modules/@jest/globals": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.1.tgz", + "integrity": "sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", + "@jest/environment": "^29.6.1", + "@jest/expect": "^29.6.1", + "@jest/types": "^29.6.1", + "jest-mock": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.1.tgz", + "integrity": "sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "jest-worker": "^29.6.1", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.0.tgz", + "integrity": "sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jest/test-result": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.1.tgz", + "integrity": "sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.1.tgz", + "integrity": "sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.6.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.1.tgz", + "integrity": "sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/config": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-6.1.0.tgz", + "integrity": "sha512-fPVlvy6MmSN0zgJU1TOD0fimnKVmcFpK3WuPyIQfNtCE+HMkFDN1mIKBKhUNow5QYHmCzMvGbu7pAgwdlSoaQA==", + "dev": true, + "dependencies": { + "@npmcli/map-workspaces": "^3.0.0", + "ini": "^3.0.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "read-package-json-fast": "^3.0.0", + "semver": "^7.3.5", + "walk-up-path": "^1.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/config/node_modules/ini": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", + "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/map-workspaces": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.0.tgz", + "integrity": "sha512-aaEDwQ+fUH80iNYSDAcKv9lxIFWsgGkLjIPZENyep75hKeAk2CfSbCAZ6IHDDrVlNybvvNmlFjPap6GdTz9cCw==", + "dev": true, + "dependencies": { + "@npmcli/name-from-folder": "^1.0.1", + "glob": "^8.0.1", + "minimatch": "^5.0.1", + "read-package-json-fast": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" @@ -1076,17 +1664,17 @@ "dev": true }, "node_modules/@pkgr/utils": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.3.1.tgz", - "integrity": "sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", "is-glob": "^4.0.3", - "open": "^8.4.0", + "open": "^9.1.0", "picocolors": "^1.0.0", - "tiny-glob": "^0.2.9", - "tslib": "^2.4.0" + "tslib": "^2.6.0" }, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" @@ -1149,32 +1737,33 @@ } }, "node_modules/@readme/eslint-config": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/@readme/eslint-config/-/eslint-config-10.5.0.tgz", - "integrity": "sha512-3r45JiDV7YP/frRocBXiDJvJgXhm7PnVFlNB0PimbfR7oM0g+C8o3TtvjMgX3HAXAi8BsjOrzBAhIm4reCybfA==", + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/@readme/eslint-config/-/eslint-config-10.6.2.tgz", + "integrity": "sha512-j7iX0XxQ/wnsavRcfHYnaxQyHqD8UOBZ6+4HQ1KluX8dordUYjEo1nMgzUVXX2hyLV/7L2DtJv9rsiYVXus7CA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "^5.48.2", - "@typescript-eslint/parser": "^5.48.2", + "@typescript-eslint/eslint-plugin": "^5.60.1", + "@typescript-eslint/parser": "^5.60.1", "eslint-config-airbnb-base": "^15.0.0", - "eslint-config-prettier": "^8.6.0", - "eslint-import-resolver-typescript": "^3.5.3", + "eslint-config-prettier": "^8.8.0", + "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-chai-expect": "^3.0.0", "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.27.5", - "eslint-plugin-jest": "^27.2.1", - "eslint-plugin-jest-dom": "^4.0.3", + "eslint-plugin-jest": "^27.2.2", + "eslint-plugin-jest-dom": "^5.0.1", "eslint-plugin-jest-formatting": "^3.0.0", - "eslint-plugin-jsdoc": "^39.6.6", + "eslint-plugin-jsdoc": "^46.4.3", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-mocha": "10.1.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "^7.32.1", + "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-testing-library": "^5.9.1", - "eslint-plugin-unicorn": "^45.0.2", + "eslint-plugin-testing-library": "^5.11.0", + "eslint-plugin-typescript-sort-keys": "^2.3.0", + "eslint-plugin-unicorn": "^47.0.0", "eslint-plugin-you-dont-need-lodash-underscore": "^6.12.0" }, "engines": { @@ -1313,6 +1902,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, "node_modules/@sindresorhus/is": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", @@ -1343,23 +1938,6 @@ "@sinonjs/commons": "^2.0.0" } }, - "node_modules/@sinonjs/samsam": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", - "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -1373,22 +1951,23 @@ } }, "node_modules/@testing-library/dom": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.0.tgz", - "integrity": "sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", + "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", - "aria-query": "^5.0.0", + "aria-query": "5.1.3", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", + "lz-string": "^1.5.0", "pretty-format": "^27.0.2" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/@ts-morph/common": { @@ -1469,7 +2048,49 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==", - "dev": true + "dev": true, + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } }, "node_modules/@types/caseless": { "version": "0.12.2", @@ -1477,12 +2098,6 @@ "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", "dev": true }, - "node_modules/@types/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", - "dev": true - }, "node_modules/@types/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-2.0.0.tgz", @@ -1528,6 +2143,15 @@ "integrity": "sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==", "dev": true }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/har-format": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.8.tgz", @@ -1554,13 +2178,79 @@ "integrity": "sha512-a3xgqnFTuNJDm1fjsTjHocYJ40Cz3t8utYpi5GNaxzrJC2HSD08ym+whIL7fNqiqBCdM9bcqD1H/tORWAFXoZw==", "dev": true }, - "node_modules/@types/js-yaml": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", - "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "node_modules/@types/json-schema": { + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz", + "integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@types/js-yaml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", + "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", + "dev": true + }, + "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" @@ -1637,12 +2327,6 @@ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, - "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", - "dev": true - }, "node_modules/@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", @@ -1698,31 +2382,6 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, - "node_modules/@types/sinon": { - "version": "10.0.12", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.12.tgz", - "integrity": "sha512-uWf4QJ4oky/GckJ1MYQxU52cgVDcXwBhDkpvLbi4EKoLPqLE4MOH6T/ttM33l3hi0oZ882G6oIzWv/oupRYSxQ==", - "dev": true, - "dependencies": { - "@types/sinonjs__fake-timers": "*" - } - }, - "node_modules/@types/sinon-chai": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", - "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", - "dev": true, - "dependencies": { - "@types/chai": "*", - "@types/sinon": "*" - } - }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", - "dev": true - }, "node_modules/@types/ssri": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/ssri/-/ssri-7.1.1.tgz", @@ -1732,6 +2391,12 @@ "@types/node": "*" } }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, "node_modules/@types/stringify-object": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/stringify-object/-/stringify-object-4.0.2.tgz", @@ -1756,19 +2421,35 @@ "integrity": "sha512-RpO62vB2lkjEkyLbwTheA2+uwYmtVMWTr/kWRI++UAgVdZqNqdAuIQl/SxBCGeMKfdjWaXPbyhZbiCc4PAj+KA==", "dev": true }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.49.0.tgz", - "integrity": "sha512-IhxabIpcf++TBaBa1h7jtOWyon80SXPRLDq0dVz5SLFC/eW6tofkw/O7Ar3lkx5z5U6wzbKDrl2larprp5kk5Q==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz", + "integrity": "sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.49.0", - "@typescript-eslint/type-utils": "5.49.0", - "@typescript-eslint/utils": "5.49.0", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/type-utils": "5.61.0", + "@typescript-eslint/utils": "5.61.0", "debug": "^4.3.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -1789,15 +2470,34 @@ } } }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.61.0.tgz", + "integrity": "sha512-r4RTnwTcaRRVUyKb7JO4DiOGmcMCat+uNs6HqJBfX7K2nlq5TagYZShhbhAw7hFT3bHaYgxMw6pKP0fhu05VMA==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.61.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/@typescript-eslint/parser": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.49.0.tgz", - "integrity": "sha512-veDlZN9mUhGqU31Qiv2qEp+XrJj5fgZpJ8PW30sHU+j/8/e5ruAhLaVDAeznS7A7i4ucb/s8IozpDtt9NqCkZg==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", + "integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.49.0", - "@typescript-eslint/types": "5.49.0", - "@typescript-eslint/typescript-estree": "5.49.0", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", "debug": "^4.3.4" }, "engines": { @@ -1817,13 +2517,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.49.0.tgz", - "integrity": "sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", + "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.49.0", - "@typescript-eslint/visitor-keys": "5.49.0" + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1834,13 +2534,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.49.0.tgz", - "integrity": "sha512-eUgLTYq0tR0FGU5g1YHm4rt5H/+V2IPVkP0cBmbhRyEmyGe4XvJ2YJ6sYTmONfjmdMqyMLad7SB8GvblbeESZA==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.61.0.tgz", + "integrity": "sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.49.0", - "@typescript-eslint/utils": "5.49.0", + "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/utils": "5.61.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1861,9 +2561,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz", - "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", + "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1874,13 +2574,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz", - "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", + "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.49.0", - "@typescript-eslint/visitor-keys": "5.49.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/visitor-keys": "5.61.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1901,18 +2601,18 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.49.0.tgz", - "integrity": "sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.61.0.tgz", + "integrity": "sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.49.0", - "@typescript-eslint/types": "5.49.0", - "@typescript-eslint/typescript-estree": "5.49.0", + "@typescript-eslint/scope-manager": "5.61.0", + "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/typescript-estree": "5.61.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "engines": { @@ -1927,12 +2627,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz", - "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==", + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", + "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.49.0", + "@typescript-eslint/types": "5.61.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1953,9 +2653,9 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1982,19 +2682,6 @@ "node": ">=0.4.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2438,13 +3125,31 @@ "string-width": "^4.1.0" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { @@ -2486,24 +3191,15 @@ "resolved": "packages/api", "link": true }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=14" } }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -2626,15 +3322,6 @@ "node": ">=0.10.0" } }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -2677,6 +3364,97 @@ "deep-equal": "^2.0.5" } }, + "node_modules/babel-jest": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.1.tgz", + "integrity": "sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.6.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -2711,13 +3489,13 @@ } ] }, - "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==", + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.6" } }, "node_modules/bl": { @@ -2861,6 +3639,18 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2882,12 +3672,6 @@ "node": ">=8" } }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, "node_modules/browserslist": { "version": "4.19.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", @@ -2911,6 +3695,27 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, "node_modules/bubble-stream-error": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/bubble-stream-error/-/bubble-stream-error-1.0.0.tgz", @@ -2973,6 +3778,21 @@ "semver": "^7.0.0" } }, + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "dependencies": { + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cacheable-request": { "version": "10.2.3", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.3.tgz", @@ -3003,21 +3823,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -3071,9 +3876,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001423", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001423.tgz", - "integrity": "sha512-09iwWGOlifvE1XuHokFMP7eR38a0JnajoyL3/i87c8ZjRWRrdKo1fqjNfugfBD0UDBIOz0U+jtNhJ0EPm1VleQ==", + "version": "1.0.30001513", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001513.tgz", + "integrity": "sha512-pnjGJo7SOOjAGytZZ203Em95MRM8Cr6jhCXNF/FAXTpCTRTECnqQWLpiTRqrFtdYcth8hf4WECUpkezuYsMVww==", "dev": true, "funding": [ { @@ -3083,6 +3888,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -3101,24 +3910,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3134,6 +3925,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/character-entities": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", @@ -3174,73 +3974,37 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true, "funding": [ { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" } ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "node": ">=8" } }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "escape-string-regexp": "^1.0.5" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/ci-info": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", - "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", - "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=4" + "node": ">=4" } }, "node_modules/clean-regexp/node_modules/escape-string-regexp": { @@ -3252,15 +4016,6 @@ "node": ">=0.8.0" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/cli-boxes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", @@ -3313,6 +4068,16 @@ "node": ">=0.8" } }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, "node_modules/code-block-writer": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", @@ -3326,6 +4091,12 @@ "node": ">= 4" } }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3570,9 +4341,9 @@ "dev": true }, "node_modules/cosmiconfig": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", - "integrity": "sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", "dev": true, "dependencies": { "import-fresh": "^3.2.1", @@ -3582,6 +4353,9 @@ }, "engines": { "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" } }, "node_modules/cosmiconfig-typescript-loader": { @@ -3780,17 +4554,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/deep-eql": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", - "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true }, "node_modules/deep-equal": { "version": "2.2.0", @@ -3835,16 +4603,157 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/default-require-extensions": { + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "dependencies": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", "dev": true, "dependencies": { - "strip-bom": "^4.0.0" + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/execa": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/default-browser/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/default-browser/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/defaults": { @@ -3865,12 +4774,15 @@ } }, "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/define-properties": { @@ -3907,6 +4819,15 @@ "node": ">=6" } }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -3916,6 +4837,15 @@ "node": ">=0.3.1" } }, + "node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3944,7 +4874,8 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/dot-prop": { "version": "5.3.0", @@ -3975,6 +4906,18 @@ "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", "dev": true }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -3991,9 +4934,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -4133,12 +5076,6 @@ "node": ">=0.10" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, "node_modules/es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", @@ -4207,13 +5144,16 @@ } }, "node_modules/eslint": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.33.0.tgz", - "integrity": "sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.4.1", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -4222,32 +5162,29 @@ "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.0", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.6.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -4291,9 +5228,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", - "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -4340,18 +5277,19 @@ } }, "node_modules/eslint-import-resolver-typescript": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.3.tgz", - "integrity": "sha512-njRcKYBc3isE42LaTcJNVANR3R99H9bAxBDMNDr2W7yq5gYPxbU3MkdhsQukxZ/Xg9C2vcyLlDsbKfRDg0QvCQ==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz", + "integrity": "sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==", "dev": true, "dependencies": { "debug": "^4.3.4", - "enhanced-resolve": "^5.10.0", - "get-tsconfig": "^4.2.0", - "globby": "^13.1.2", - "is-core-module": "^2.10.0", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "get-tsconfig": "^4.5.0", + "globby": "^13.1.3", + "is-core-module": "^2.11.0", "is-glob": "^4.0.3", - "synckit": "^0.8.4" + "synckit": "^0.8.5" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -4365,14 +5303,14 @@ } }, "node_modules/eslint-import-resolver-typescript/node_modules/globby": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", - "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dev": true, "dependencies": { "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", "merge2": "^1.4.1", "slash": "^4.0.0" }, @@ -4593,9 +5531,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "27.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz", - "integrity": "sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==", + "version": "27.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.2.tgz", + "integrity": "sha512-euzbp06F934Z7UDl5ZUaRPLAc9MKjh0rMPERrHT7UhlCEwgb25kBj37TvMgWeHZVkR5I9CayswrpoaqZU1RImw==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.10.0" @@ -4605,7 +5543,8 @@ }, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0", + "jest": "*" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -4617,13 +5556,12 @@ } }, "node_modules/eslint-plugin-jest-dom": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-4.0.3.tgz", - "integrity": "sha512-9j+n8uj0+V0tmsoS7bYC7fLhQmIvjRqRYEcbDSi+TKPsTThLLXCyj5swMSSf/hTleeMktACnn+HFqXBr5gbcbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.0.1.tgz", + "integrity": "sha512-zD/BjNk12R5R9cxIu8oa2HfNeDSknI3ewtN8nygIUMQuieWDnTY9Np//6a1Z3G7Y3dx3l45hCUR4EphsgRmUtA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.3", - "@testing-library/dom": "^8.11.1", "requireindex": "^1.2.0" }, "engines": { @@ -4632,6 +5570,7 @@ "yarn": ">=1" }, "peerDependencies": { + "@testing-library/dom": "^8.0.0 || ^9.0.0", "eslint": "^6.8.0 || ^7.0.0 || ^8.0.0" } }, @@ -4648,21 +5587,23 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "39.6.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.7.tgz", - "integrity": "sha512-0mrzXrHvL2ZLe3QK9X0OEDy7Fs2cFQ/f1d1G5KHEGD+13D1qg56Iovq0uOkYf5bJlHiKPytWVgOOO9y7kLW3VA==", + "version": "46.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.3.tgz", + "integrity": "sha512-Prc7ol+vCIghPeECpwZq5+P+VZfoi87suywvbYCiCnkI1kTmVSdcOC2M8mioglWxBbd28wbb1OVjg/8OzGzatA==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.36.1", + "@es-joy/jsdoccomment": "~0.39.4", + "are-docs-informative": "^0.0.2", "comment-parser": "1.3.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", - "semver": "^7.3.8", + "esquery": "^1.5.0", + "is-builtin-module": "^3.2.1", + "semver": "^7.5.1", "spdx-expression-parse": "^3.0.1" }, "engines": { - "node": "^14 || ^16 || ^17 || ^18 || ^19" + "node": ">=16" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" @@ -4798,9 +5739,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.32.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.1.tgz", - "integrity": "sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www==", + "version": "7.32.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", + "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==", "dev": true, "dependencies": { "array-includes": "^3.1.6", @@ -4877,12 +5818,12 @@ } }, "node_modules/eslint-plugin-testing-library": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.0.tgz", - "integrity": "sha512-aTOsCAEI9trrX3TLOnsskfhe57DmsjP/yMKLPqg4ftdRvfR4qut2PGWUa8TwP7whZbwMzJjh98tgAPcE8vdHow==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.0.tgz", + "integrity": "sha512-ELY7Gefo+61OfXKlQeXNIDVVLPcvKTeiQOoMZG9TeuWa7Ln4dUNRv8JdRWBQI9Mbb427XGlVB1aa1QPZxBJM8Q==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.43.0" + "@typescript-eslint/utils": "^5.58.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0", @@ -4892,37 +5833,56 @@ "eslint": "^7.5.0 || ^8.0.0" } }, + "node_modules/eslint-plugin-typescript-sort-keys": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-typescript-sort-keys/-/eslint-plugin-typescript-sort-keys-2.3.0.tgz", + "integrity": "sha512-3LAcYulo5gNYiPWee+TksITfvWeBuBjGgcSLTacPESFVKEoy8laOQuZvJlSCwTBHT2SCGIxr3bJ56zuux+3MCQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0", + "json-schema": "^0.4.0", + "natural-compare-lite": "^1.4.0" + }, + "engines": { + "node": "12 || >= 13.9" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^1 || ^2 || ^3 || ^4 || ^5", + "eslint": "^5 || ^6 || ^7 || ^8", + "typescript": "^3 || ^4 || ^5" + } + }, "node_modules/eslint-plugin-unicorn": { - "version": "45.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-45.0.2.tgz", - "integrity": "sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw==", + "version": "47.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-47.0.0.tgz", + "integrity": "sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.19.1", - "@eslint-community/eslint-utils": "^4.1.2", - "ci-info": "^3.6.1", + "@eslint-community/eslint-utils": "^4.4.0", + "ci-info": "^3.8.0", "clean-regexp": "^1.0.0", - "esquery": "^1.4.0", + "esquery": "^1.5.0", "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.0", + "is-builtin-module": "^3.2.1", "jsesc": "^3.0.2", "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.24", - "regjsparser": "^0.9.1", + "regjsparser": "^0.10.0", "safe-regex": "^2.1.1", "semver": "^7.3.8", "strip-indent": "^3.0.0" }, "engines": { - "node": ">=14.18" + "node": ">=16" }, "funding": { "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=8.28.0" + "eslint": ">=8.38.0" } }, "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { @@ -4999,18 +5959,21 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", + "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -5018,17 +5981,20 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5051,9 +6017,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -5171,6 +6137,32 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.1.tgz", + "integrity": "sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.6.1", + "@types/node": "*", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", @@ -5202,9 +6194,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", + "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5235,7 +6227,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fast-safe-stringify": { @@ -5264,6 +6256,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, "node_modules/fetch-har": { "version": "8.1.5", "resolved": "https://registry.npmjs.org/fetch-har/-/fetch-har-8.1.5.tgz", @@ -5396,15 +6397,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -5433,19 +6425,6 @@ "is-callable": "^1.1.3" } }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/form-data-encoder": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", @@ -5477,30 +6456,10 @@ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "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/fs-extra": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", - "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", + "node_modules/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -5527,6 +6486,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -5580,15 +6540,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", @@ -5644,10 +6595,13 @@ } }, "node_modules/get-tsconfig": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.3.0.tgz", - "integrity": "sha512-YCcF28IqSay3fqpIu5y3Krg/utCBHBeoflkZyHj/QcqI2nrLPC3ZegS9CmIo+hJb8K7aiGsuUl7PwWVjNG2HQQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.2.tgz", + "integrity": "sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==", "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, "funding": { "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } @@ -5780,9 +6734,9 @@ } }, "node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5809,12 +6763,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globalyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true - }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -5835,12 +6783,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true - }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -5932,6 +6874,12 @@ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -6040,31 +6988,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/hast-util-embedded": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-2.0.0.tgz", @@ -6230,15 +7153,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -6315,9 +7229,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -6371,6 +7285,25 @@ "node": ">=8" } }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/import-meta-resolve": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.0.tgz", @@ -6506,18 +7439,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -6558,9 +7479,9 @@ } }, "node_modules/is-builtin-module": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz", - "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, "dependencies": { "builtin-modules": "^3.3.0" @@ -6634,15 +7555,15 @@ } }, "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, "bin": { "is-docker": "cli.js" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6670,6 +7591,15 @@ "node": ">=8" } }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -6691,6 +7621,24 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-installed-globally": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", @@ -6998,145 +7946,1020 @@ "get-intrinsic": "^1.1.1" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.1.tgz", + "integrity": "sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.1", + "@jest/types": "^29.6.1", + "import-local": "^3.0.2", + "jest-cli": "^29.6.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.1.tgz", + "integrity": "sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.1", + "@jest/expect": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.6.1", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "p-limit": "^3.1.0", + "pretty-format": "^29.6.1", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-cli": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.1.tgz", + "integrity": "sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.1.tgz", + "integrity": "sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.6.1", + "@jest/types": "^29.6.1", + "babel-jest": "^29.6.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.6.1", + "jest-environment-node": "^29.6.1", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-runner": "^29.6.1", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-diff": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.1.tgz", + "integrity": "sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.1.tgz", + "integrity": "sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.6.1", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-environment-node": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.1.tgz", + "integrity": "sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-mock": "^29.6.1", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-extended": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-4.0.0.tgz", + "integrity": "sha512-GMhMFdrwhYPB0y+cmI/5esz+F/Xc0OIzKbnr8SaiZ74YcWamxf7sVT78YlA15+JIQMTlpHBEgcxheyRBdHFqPA==", + "dev": true, + "dependencies": { + "jest-diff": "^29.0.0", + "jest-get-type": "^29.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "jest": ">=27.2.5" + }, + "peerDependenciesMeta": { + "jest": { + "optional": true + } + } + }, + "node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.1.tgz", + "integrity": "sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.1", + "jest-worker": "^29.6.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.1.tgz", + "integrity": "sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-matcher-utils": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz", + "integrity": "sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.6.1", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-message-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.1.tgz", + "integrity": "sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.1.tgz", + "integrity": "sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "jest-util": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.1.tgz", + "integrity": "sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.6.1", + "jest-validate": "^29.6.1", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.1.tgz", + "integrity": "sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.1.tgz", + "integrity": "sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.1", + "@jest/environment": "^29.6.1", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.6.1", + "jest-haste-map": "^29.6.1", + "jest-leak-detector": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-resolve": "^29.6.1", + "jest-runtime": "^29.6.1", + "jest-util": "^29.6.1", + "jest-watcher": "^29.6.1", + "jest-worker": "^29.6.1", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.1.tgz", + "integrity": "sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.1", + "@jest/fake-timers": "^29.6.1", + "@jest/globals": "^29.6.1", + "@jest/source-map": "^29.6.0", + "@jest/test-result": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-mock": "^29.6.1", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.6.1", + "jest-snapshot": "^29.6.1", + "jest-util": "^29.6.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.1.tgz", + "integrity": "sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.6.1", + "@jest/transform": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.6.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.6.1", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.6.1", + "jest-message-util": "^29.6.1", + "jest-util": "^29.6.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.6.1", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { - "is-docker": "^2.0.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "node_modules/jest-util": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.1.tgz", + "integrity": "sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==", "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, "engines": { - "node": ">=12" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "node_modules/jest-validate": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.1.tgz", + "integrity": "sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA==", + "dev": true, "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" + "@jest/types": "^29.6.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.6.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", "dev": true, "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-watcher": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.1.tgz", + "integrity": "sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA==", "dev": true, "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" + "@jest/test-result": "^29.6.1", + "@jest/types": "^29.6.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.6.1", + "string-length": "^4.0.1" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "node_modules/jest-worker": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.1.tgz", + "integrity": "sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA==", "dev": true, "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "@types/node": "*", + "jest-util": "^29.6.1", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-sdsl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", - "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", - "dev": true - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7154,9 +8977,9 @@ } }, "node_modules/jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, "engines": { "node": ">=12.0.0" @@ -7186,6 +9009,12 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, "node_modules/json-schema-compare": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz", @@ -7327,12 +9156,6 @@ "node": ">=4.0" } }, - "node_modules/just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", - "dev": true - }, "node_modules/kebab-case": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/kebab-case/-/kebab-case-1.0.1.tgz", @@ -7475,18 +9298,6 @@ "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==" }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -7511,6 +9322,12 @@ "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", "dev": true }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -7593,15 +9410,6 @@ "loose-envify": "cli.js" } }, - "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, "node_modules/lowercase-keys": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", @@ -7634,10 +9442,11 @@ } }, "node_modules/lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, + "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -7670,6 +9479,15 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -8875,205 +10693,56 @@ "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/minipass": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", - "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=10" + "node": "*" } }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, "engines": { - "node": ">=10" + "node": ">= 6" } }, - "node_modules/mock-require": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", - "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", - "dev": true, + "node_modules/minipass": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", + "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", "dependencies": { - "get-caller-file": "^1.0.2", - "normalize-path": "^2.1.1" + "yallist": "^4.0.0" }, "engines": { - "node": ">=4.3.0" + "node": ">=8" } }, - "node_modules/mock-require/node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/mock-require/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "dependencies": { - "remove-trailing-separator": "^1.0.1" + "minimist": "^1.2.5" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "mkdirp": "bin/cmd.js" } }, "node_modules/mri": { @@ -9099,18 +10768,6 @@ "mustache": "bin/mustache" } }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -9128,52 +10785,6 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, - "node_modules/nise": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.2.tgz", - "integrity": "sha512-+gQjFi8v+tkfCuSCxfURHLhRhniE/+IaYbIphxAN2JRR9SHKhY8hgXpaXiYfHdw+gcGe4buxgbprBQFab9FkhA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^7.0.4", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/nise/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "node_modules/nise/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "dependencies": { - "isarray": "0.0.1" - } - }, "node_modules/nlcst-is-literal": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nlcst-is-literal/-/nlcst-is-literal-2.1.0.tgz", @@ -9305,17 +10916,11 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true }, "node_modules/node-readfiles": { "version": "0.2.0", @@ -9402,189 +11007,6 @@ "node": ">=8" } }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/oas": { "version": "20.4.0", "resolved": "https://registry.npmjs.org/oas/-/oas-20.4.0.tgz", @@ -9830,17 +11252,18 @@ } }, "node_modules/open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", "dev": true, "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", "is-wsl": "^2.2.0" }, "engines": { - "node": ">=12" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9852,17 +11275,17 @@ "integrity": "sha512-XpeCy01X6L5EpP+6Hc3jWN7rMZJ+/k1lwki/kTmWzbVhdPie3jd5O2ZtedEx8Yp58icJ0osVldLMrTB/zslQXA==" }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -9938,18 +11361,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -9958,21 +11369,6 @@ "node": ">=6" } }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/package-json": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.0.tgz", @@ -10148,15 +11544,6 @@ "node": ">=8" } }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", @@ -10182,6 +11569,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -10309,6 +11705,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, + "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -10323,6 +11720,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -10345,18 +11743,6 @@ "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", "dev": true }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -10446,6 +11832,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -10532,15 +11934,6 @@ "integrity": "sha512-xW2ZcQh+AtRHdIN0RUix+gAwyfAeMBZA6SnLSblw1+YRqUx+eV4Eppg/ayDdrvSs6KegZYHYtSF6+I86Z5Owqg==", "dev": true }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -10569,7 +11962,8 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "dev": true, + "peer": true }, "node_modules/read-package-json-fast": { "version": "3.0.1", @@ -10735,18 +12129,6 @@ "node": ">= 6" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -10774,9 +12156,9 @@ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/regexp-tree": { - "version": "0.1.24", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", - "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", "dev": true, "bin": { "regexp-tree": "bin/regexp-tree" @@ -10839,9 +12221,9 @@ } }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", "dev": true, "dependencies": { "jsesc": "~0.5.0" @@ -10891,18 +12273,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/remark-frontmatter": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-4.0.1.tgz", @@ -10997,12 +12367,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, "node_modules/remove-undefined-objects": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/remove-undefined-objects/-/remove-undefined-objects-2.0.2.tgz", @@ -11027,12 +12391,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/requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -11065,6 +12423,18 @@ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "dev": true }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -11086,6 +12456,24 @@ "node": ">=8" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/responselike": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", @@ -11195,6 +12583,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11259,9 +12662,9 @@ } }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -11287,21 +12690,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "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", @@ -11387,43 +12775,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, - "node_modules/sinon": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", - "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "10.0.2", - "@sinonjs/samsam": "^7.0.1", - "diff": "^5.0.0", - "nise": "^5.1.2", - "supports-color": "^7.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, - "node_modules/sinon-chai": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", - "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "dev": true, - "peerDependencies": { - "chai": "^4.0.0", - "sinon": ">=4.0.0" - } - }, - "node_modules/sinon/node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -11453,6 +12804,16 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/space-separated-tokens": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", @@ -11528,23 +12889,6 @@ "node": ">=0.4" } }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -11729,6 +13073,27 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -11778,6 +13143,19 @@ } ] }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -11980,13 +13358,13 @@ } }, "node_modules/synckit": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.4.tgz", - "integrity": "sha512-Dn2ZkzMdSX827QbowGbU/4yjWuvNaCoScLLoMo/yKbu+P4GBR6cRGKZH27k6a9bRzdqcyd1DE96pQtQ6uNkmyw==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", "dev": true, "dependencies": { "@pkgr/utils": "^2.3.1", - "tslib": "^2.4.0" + "tslib": "^2.5.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -12056,16 +13434,24 @@ "next-tick": "1" } }, - "node_modules/tiny-glob": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", - "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", "dev": true, - "dependencies": { - "globalyzer": "0.1.0", - "globrex": "^0.1.2" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -12136,6 +13522,73 @@ "ts-toolbelt": "^9.6.0" } }, + "node_modules/ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/ts-morph": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-17.0.1.tgz", @@ -12227,9 +13680,9 @@ } }, "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==", "dev": true }, "node_modules/tsutils": { @@ -12744,6 +14197,15 @@ "node": ">= 10.0.0" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/update-notifier": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", @@ -12797,16 +14259,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/uvu": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", @@ -12849,6 +14301,30 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -13066,6 +14542,15 @@ "integrity": "sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==", "dev": true }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -13159,12 +14644,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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/which-typed-array": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", @@ -13244,21 +14723,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -13361,54 +14825,6 @@ "node": ">=10" } }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/yargs/node_modules/yargs-parser": { "version": "21.0.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz", @@ -13492,29 +14908,24 @@ "devDependencies": { "@readme/oas-examples": "^5.9.0", "@types/caseless": "^0.12.2", - "@types/chai": "^4.3.4", "@types/find-cache-dir": "^3.2.1", + "@types/jest": "^29.5.2", "@types/js-yaml": "^4.0.5", "@types/lodash.camelcase": "^4.3.7", "@types/lodash.deburr": "^4.1.7", "@types/lodash.merge": "^4.6.7", "@types/lodash.setwith": "^4.3.7", "@types/lodash.startcase": "^4.4.7", - "@types/mocha": "^10.0.1", "@types/prettier": "^2.7.2", "@types/prompts": "^2.4.2", "@types/semver": "^7.3.13", - "@types/sinon-chai": "^3.2.9", "@types/ssri": "^7.1.1", "@types/validate-npm-package-name": "^4.0.0", - "chai": "^4.3.7", "fetch-mock": "^9.11.0", - "mocha": "^10.1.0", - "mock-require": "^3.0.3", - "nyc": "^15.1.0", + "jest": "^29.6.1", + "jest-extended": "^4.0.0", "oas-normalize": "^8.3.2", - "sinon": "^15.0.0", - "sinon-chai": "^3.7.0", + "ts-jest": "^29.1.1", "type-fest": "^3.5.4", "typescript": "^4.9.5", "unique-temp-dir": "^1.0.0" @@ -13559,15 +14970,13 @@ "@readme/oas-examples": "^5.9.0", "@readme/openapi-parser": "^2.4.0", "@types/content-type": "^1.1.5", + "@types/jest": "^29.5.2", "@types/stringify-object": "^4.0.2", "api": "file:../api", - "chai": "^4.3.7", "fetch-mock": "^9.11.0", "isomorphic-fetch": "^3.0.0", - "mocha": "^10.2.0", - "nyc": "^15.1.0", - "sinon": "^15.0.1", - "sinon-chai": "^3.7.0", + "jest": "^29.6.1", + "ts-jest": "^29.1.1", "typescript": "^4.9.5" }, "engines": { diff --git a/package.json b/package.json index e5971c54..0461f079 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,11 @@ ], "prettier": "@readme/eslint-config/prettier", "devDependencies": { - "@commitlint/cli": "^17.4.2", - "@commitlint/config-conventional": "^17.4.2", - "@readme/eslint-config": "^10.5.0", + "@commitlint/cli": "^17.6.6", + "@commitlint/config-conventional": "^17.6.6", + "@readme/eslint-config": "^10.6.2", "alex": "^11.0.0", - "eslint": "^8.33.0", + "eslint": "^8.44.0", "husky": "^8.0.3", "prettier": "^2.8.0" }, diff --git a/packages/api/.gitignore b/packages/api/.gitignore index 087b09ce..b8fe8bdb 100644 --- a/packages/api/.gitignore +++ b/packages/api/.gitignore @@ -1,4 +1,4 @@ .api/ -.nyc_output/ +coverage/ dist/ node_modules/ diff --git a/packages/api/.mocharc.json b/packages/api/.mocharc.json deleted file mode 100644 index ef6ff174..00000000 --- a/packages/api/.mocharc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "require": [ - "test/helpers/init.js", - "ts-node/register" - ], - "watch-extensions": [ - "ts" - ], - "watch-files": ["src/**/*.ts", "test/**/*.ts"], - "recursive": true, - "reporter": "spec" -} diff --git a/packages/api/.npmignore b/packages/api/.npmignore index 9755dedf..e90c62bb 100644 --- a/packages/api/.npmignore +++ b/packages/api/.npmignore @@ -1,8 +1,8 @@ .api/ -.nyc_output/ +coverage/ test/ .eslint* .gitignore -.mocharc.json .prettier* +jest.config.js example.js diff --git a/packages/api/jest.config.js b/packages/api/jest.config.js new file mode 100644 index 00000000..017f5a86 --- /dev/null +++ b/packages/api/jest.config.js @@ -0,0 +1,21 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const path = require('path'); + +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + coveragePathIgnorePatterns: ['/dist', '/node_modules', '/test/__fixtures__/', '/test/datasets/', '/test/helpers/'], + modulePaths: [''], + roots: [''], + setupFilesAfterEnv: ['jest-extended/all', path.join(__dirname, 'test', 'helpers', 'jest.matchers.ts')], + testPathIgnorePatterns: ['/test/__fixtures__/', '/test/datasets/', '/test/helpers/'], + testRegex: '(/test/.*|(\\.|/)(test|spec))\\.(js?|ts?)$', + testTimeout: 20000, + transform: { + '^.+\\.[tj]s$': [ + 'ts-jest', + { + tsconfig: 'test/tsconfig.json', + }, + ], + }, +}; diff --git a/packages/api/package.json b/packages/api/package.json index 3325eb17..133ee317 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -12,8 +12,8 @@ "debug:bin": "node -r ts-node/register src/bin.ts", "prebuild": "rm -rf dist/; npm run version", "prepack": "npm run build", - "test": "nyc mocha $(find test -name '*.test.ts' -not -path '*/smoketest.test.ts')", - "test:smoke": "npx mocha test/cli/codegen/languages/typescript/smoketest.test.ts", + "test": "jest --coverage $(find test -name '*.test.ts' -not -path '*/smoketest.test.ts')", + "test:smoke": "npx jest test/cli/codegen/languages/typescript/smoketest.test.ts", "version": "node -p \"'// This file is automatically updated by the build script.\\nexport const PACKAGE_NAME = \\'' + require('./package.json').name + '\\';\\nexport const PACKAGE_VERSION = \\'' + require('./package.json').version + '\\';'\" > src/packageInfo.ts; git add src/packageInfo.ts" }, "repository": { @@ -74,38 +74,27 @@ "devDependencies": { "@readme/oas-examples": "^5.9.0", "@types/caseless": "^0.12.2", - "@types/chai": "^4.3.4", "@types/find-cache-dir": "^3.2.1", + "@types/jest": "^29.5.2", "@types/js-yaml": "^4.0.5", "@types/lodash.camelcase": "^4.3.7", "@types/lodash.deburr": "^4.1.7", "@types/lodash.merge": "^4.6.7", "@types/lodash.setwith": "^4.3.7", "@types/lodash.startcase": "^4.4.7", - "@types/mocha": "^10.0.1", "@types/prettier": "^2.7.2", "@types/prompts": "^2.4.2", "@types/semver": "^7.3.13", - "@types/sinon-chai": "^3.2.9", "@types/ssri": "^7.1.1", "@types/validate-npm-package-name": "^4.0.0", - "chai": "^4.3.7", "fetch-mock": "^9.11.0", - "mocha": "^10.1.0", - "mock-require": "^3.0.3", - "nyc": "^15.1.0", + "jest": "^29.6.1", + "jest-extended": "^4.0.0", "oas-normalize": "^8.3.2", - "sinon": "^15.0.0", - "sinon-chai": "^3.7.0", + "ts-jest": "^29.1.1", "type-fest": "^3.5.4", "typescript": "^4.9.5", "unique-temp-dir": "^1.0.0" }, - "prettier": "@readme/eslint-config/prettier", - "nyc": { - "exclude": [ - "dist/", - "test/" - ] - } + "prettier": "@readme/eslint-config/prettier" } diff --git a/packages/api/src/cache.ts b/packages/api/src/cache.ts index 7501fc18..6857b387 100644 --- a/packages/api/src/cache.ts +++ b/packages/api/src/cache.ts @@ -16,8 +16,11 @@ type CacheStore = Record< string, { hash: string; - path?: string; // Deprecated in v4.5.0 in favor of `hash`. original: string | OASDocument; + /** + * @deprecated Deprecated in v4.5.0 in favor of `hash`. + */ + path?: string; title?: string; version?: string; } diff --git a/packages/api/src/cli/codegen/languages/typescript.ts b/packages/api/src/cli/codegen/languages/typescript.ts index 7d540bcd..c478dde6 100644 --- a/packages/api/src/cli/codegen/languages/typescript.ts +++ b/packages/api/src/cli/codegen/languages/typescript.ts @@ -20,16 +20,16 @@ import CodeGeneratorLanguage from '../language'; import { docblockEscape, formatter, generateTypeName, wordWrap } from './typescript/util'; export interface TSGeneratorOptions { - outputJS?: boolean; compilerTarget?: 'cjs' | 'esm'; + outputJS?: boolean; } interface OperationTypeHousing { + operation: Operation; types: { params?: false | Record<'body' | 'formData' | 'metadata', string>; responses?: Record; }; - operation: Operation; } export default class TSGenerator extends CodeGeneratorLanguage { @@ -60,7 +60,7 @@ export default class TSGenerator extends CodeGeneratorLanguage { usesHTTPMethodRangeInterface = false; constructor(spec: Oas, specPath: string, identifier: string, opts: TSGeneratorOptions = {}) { - const options: { outputJS: boolean; compilerTarget: 'cjs' | 'esm' } = { + const options: { compilerTarget: 'cjs' | 'esm'; outputJS: boolean } = { outputJS: false, compilerTarget: 'cjs', ...opts, diff --git a/packages/api/src/cli/storage.ts b/packages/api/src/cli/storage.ts index d370af5e..0be205dd 100644 --- a/packages/api/src/cli/storage.ts +++ b/packages/api/src/cli/storage.ts @@ -207,7 +207,6 @@ export default class Storage { * ├── openapi.json * └── package.json * - * @param spec */ save(spec: OASDocument) { if (!this.identifier) { @@ -254,12 +253,13 @@ export default class Storage { } export interface Lockfile { + apis: LockfileAPI[]; + /** * The `api.json` schema version. This will only ever change if we introduce breaking changes to * this store. */ version: '1.0'; - apis: LockfileAPI[]; } export interface LockfileAPI { @@ -272,13 +272,11 @@ export interface LockfileAPI { identifier: string; /** - * The original source that was used to generate the SDK with. + * The version of `api` that was used to install this SDK. * - * @example https://raw.githubusercontent.com/readmeio/oas-examples/main/3.0/json/petstore-simple.json - * @example ./petstore.json - * @example @developers/v2.0#nysezql0wwo236 + * @example 5.0.0 */ - source: string; + installerVersion: string; /** * An integrity hash that will be used to determine on `npx api update` calls if the API has @@ -289,9 +287,11 @@ export interface LockfileAPI { integrity: string; /** - * The version of `api` that was used to install this SDK. + * The original source that was used to generate the SDK with. * - * @example 5.0.0 + * @example https://raw.githubusercontent.com/readmeio/oas-examples/main/3.0/json/petstore-simple.json + * @example ./petstore.json + * @example @developers/v2.0#nysezql0wwo236 */ - installerVersion: string; + source: string; } diff --git a/packages/api/src/core/getJSONSchemaDefaults.ts b/packages/api/src/core/getJSONSchemaDefaults.ts index fc734d1f..71684a0c 100644 --- a/packages/api/src/core/getJSONSchemaDefaults.ts +++ b/packages/api/src/core/getJSONSchemaDefaults.ts @@ -12,7 +12,6 @@ import traverse from 'json-schema-traverse'; * * @todo This is a good candidate to be moved into a core `oas` library method. * @see {@link https://github.com/mdornseif/json-schema-default} - * @param jsonSchemas */ export default function getJSONSchemaDefaults(jsonSchemas: SchemaWrapper[]) { return jsonSchemas diff --git a/packages/api/src/core/index.ts b/packages/api/src/core/index.ts index 31f01677..1e8688d5 100644 --- a/packages/api/src/core/index.ts +++ b/packages/api/src/core/index.ts @@ -26,9 +26,9 @@ export interface ConfigOptions { export interface FetchResponse { data: data; - status: status; headers: Headers; res: Response; + status: status; } // https://stackoverflow.com/a/39495173 diff --git a/packages/api/src/core/prepareAuth.ts b/packages/api/src/core/prepareAuth.ts index 452892ae..826639f7 100644 --- a/packages/api/src/core/prepareAuth.ts +++ b/packages/api/src/core/prepareAuth.ts @@ -11,8 +11,8 @@ export default function prepareAuth(authKey: (number | string)[], operation: Ope | string | number | { - user: string | number; pass: string | number; + user: string | number; } > = {}; diff --git a/packages/api/src/core/prepareParams.ts b/packages/api/src/core/prepareParams.ts index 364d5670..cb9c6199 100644 --- a/packages/api/src/core/prepareParams.ts +++ b/packages/api/src/core/prepareParams.ts @@ -76,7 +76,7 @@ function merge(src: any, target: any) { function processFile( paramName: string, file: string | ReadStream -): Promise<{ paramName: string; base64: string; filename: string; buffer: Buffer }> { +): Promise<{ base64: string; buffer: Buffer; filename: string; paramName: string }> { if (typeof file === 'string') { // In order to support relative pathed files, we need to attempt to resolve them. const resolvedFile = path.resolve(file); diff --git a/packages/api/src/core/prepareServer.ts b/packages/api/src/core/prepareServer.ts index 075a7d3f..ded62107 100644 --- a/packages/api/src/core/prepareServer.ts +++ b/packages/api/src/core/prepareServer.ts @@ -12,9 +12,6 @@ function stripTrailingSlash(url: string) { * With an SDK server config and an instance of OAS we should extract and prepare the server and * any server variables to be supplied to `@readme/oas-to-har`. * - * @param spec - * @param url - * @param variables */ export default function prepareServer(spec: Oas, url: string, variables: Record = {}) { let serverIdx; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index aa06df6e..c33fff6f 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -41,7 +41,6 @@ class Sdk { * Create dynamic accessors for every operation with a defined operation ID. If an operation * does not have an operation ID it can be accessed by its `.method('/path')` accessor instead. * - * @param spec */ function loadOperations(spec: Oas) { return Object.entries(spec.getPaths()) diff --git a/packages/api/test/.eslintrc b/packages/api/test/.eslintrc index c894b8f2..01cf1347 100644 --- a/packages/api/test/.eslintrc +++ b/packages/api/test/.eslintrc @@ -1,7 +1,6 @@ { - "extends": "@readme/eslint-config/testing-mocha", + "extends": "@readme/eslint-config/testing", "rules": { - "func-names": "off", - "global-require": "off" + "jest/no-conditional-expect": "off" } } diff --git a/packages/api/test/auth.test.ts b/packages/api/test/auth.test.ts index a45eae3e..fde4657f 100644 --- a/packages/api/test/auth.test.ts +++ b/packages/api/test/auth.test.ts @@ -1,6 +1,5 @@ import type { OASDocument } from 'oas/dist/rmoas.types'; -import { assert, expect } from 'chai'; import fetchMock from 'fetch-mock'; import uniqueTempDir from 'unique-temp-dir'; @@ -16,25 +15,25 @@ const apiKey = '123457890'; const user = 'buster'; const pass = 'hunter1'; -describe('#auth()', function () { - before(function () { +describe('#auth()', () => { + beforeAll(() => { // Set a unique cache dir so these tests won't collide with other tests and we don't need to go // through the trouble of mocking out the filesystem. Cache.setCacheDir(uniqueTempDir()); }); - beforeEach(async function () { + beforeEach(async () => { const securityOas = await loadSpec('@readme/oas-examples/3.0/json/security.json'); sdk = api(securityOas as unknown as OASDocument); }); - afterEach(function () { + afterEach(() => { fetchMock.restore(); }); - describe('API Keys', function () { - describe('in: query', function () { - it('should allow you to supply auth', async function () { + describe('API Keys', () => { + describe('in: query', () => { + it('should allow you to supply auth', async () => { fetchMock.get( { url: 'https://httpbin.org/anything/apiKey', @@ -46,48 +45,38 @@ describe('#auth()', function () { sdk.auth(apiKey); await sdk.getAnythingApikey().then(({ data }) => { - expect(data).to.equal('/anything/apiKey?apiKey=123457890'); + expect(data).toBe('/anything/apiKey?apiKey=123457890'); }); }); - it('should throw if you supply multiple auth keys', async function () { + it('should throw if you supply multiple auth keys', async () => { sdk.auth(apiKey, apiKey); - await sdk - .getAnythingApikey() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.match(/only a single token is needed/i); - }); + await expect(sdk.getAnythingApikey()).rejects.toThrow(/only a single token is needed/i); }); }); - describe('in: header', function () { - it('should allow you to supply auth', async function () { + describe('in: header', () => { + it('should allow you to supply auth', async () => { fetchMock.put('https://httpbin.org/anything/apiKey', mockResponses.headers); sdk.auth(apiKey); await sdk.putAnythingApikey().then(({ data }) => { - expect(data).to.have.deep.property('x-api-key', '123457890'); + expect(data).toHaveProperty('x-api-key', '123457890'); }); }); - it('should throw if you supply multiple auth keys', async function () { + it('should throw if you supply multiple auth keys', async () => { sdk.auth(apiKey, apiKey); - await sdk - .putAnythingApikey() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.match(/only a single token is needed/i); - }); + await expect(sdk.putAnythingApikey()).rejects.toThrow(/only a single token is needed/i); }); }); }); - describe('HTTP', function () { - describe('scheme: basic', function () { - it('should allow you to supply auth', async function () { + describe('HTTP', () => { + describe('scheme: basic', () => { + it('should allow you to supply auth', async () => { const authHeader = `Basic ${Buffer.from(`${user}:${pass}`).toString('base64')}`; fetchMock.post('https://httpbin.org/anything/basic', mockResponses.headers); @@ -95,86 +84,76 @@ describe('#auth()', function () { sdk.auth(user, pass); await sdk.postAnythingBasic().then(({ data }) => { - expect(data).to.have.deep.property('authorization', authHeader); + expect(data).toHaveProperty('authorization', authHeader); }); }); - it('should allow you to not pass in a password', async function () { + it('should allow you to not pass in a password', async () => { fetchMock.post('https://httpbin.org/anything/basic', mockResponses.headers); sdk.auth(user); await sdk.postAnythingBasic().then(({ data }) => { - expect(data).to.have.deep.property('authorization', `Basic ${Buffer.from(`${user}:`).toString('base64')}`); + expect(data).toHaveProperty('authorization', `Basic ${Buffer.from(`${user}:`).toString('base64')}`); }); }); }); - describe('scheme: bearer', function () { - it('should allow you to supply auth', async function () { + describe('scheme: bearer', () => { + it('should allow you to supply auth', async () => { fetchMock.post('https://httpbin.org/anything/bearer', mockResponses.headers); sdk.auth(apiKey); await sdk.postAnythingBearer().then(({ data }) => { - expect(data).to.have.deep.property('authorization', `Bearer ${apiKey}`); + expect(data).toHaveProperty('authorization', `Bearer ${apiKey}`); }); }); - it('should throw if you pass in multiple bearer tokens', async function () { + it('should throw if you pass in multiple bearer tokens', async () => { sdk.auth(apiKey, apiKey); - await sdk - .postAnythingBearer() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.match(/only a single token is needed/i); - }); + await expect(sdk.postAnythingBearer()).rejects.toThrow(/only a single token is needed/i); }); }); }); - describe('OAuth 2', function () { - it('should allow you to supply auth', async function () { + describe('OAuth 2', () => { + it('should allow you to supply auth', async () => { fetchMock.post('https://httpbin.org/anything/oauth2', mockResponses.headers); sdk.auth(apiKey); await sdk.postAnythingOauth2().then(({ data }) => { - expect(data).to.have.deep.property('authorization', `Bearer ${apiKey}`); + expect(data).toHaveProperty('authorization', `Bearer ${apiKey}`); }); }); - it('should throw if you pass in multiple bearer tokens', async function () { + it('should throw if you pass in multiple bearer tokens', async () => { sdk.auth(apiKey, apiKey); - await sdk - .postAnythingOauth2() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.match(/only a single token is needed/i); - }); + await expect(sdk.postAnythingOauth2()).rejects.toThrow(/only a single token is needed/i); }); }); - it('should allow multiple calls to share an API key', async function () { - let calls = 0; + it('should allow multiple calls to share an API key', async () => { + const endpointCall = jest.fn(); fetchMock.get( { url: 'https://httpbin.org/anything/apiKey', query: { apiKey }, }, () => { - calls += 1; - return { calls }; + endpointCall(); + return {}; } ); sdk.auth(apiKey); - await sdk.getAnythingApikey().then(({ data }) => expect(data.calls).to.equal(1)); - await sdk.getAnythingApikey().then(({ data }) => expect(data.calls).to.equal(2)); + await sdk.getAnythingApikey().then(() => expect(endpointCall).toHaveBeenCalledOnce()); + await sdk.getAnythingApikey().then(() => expect(endpointCall).toHaveBeenCalledTimes(2)); }); - it('should allow auth to be called again to change the key', async function () { + it('should allow auth to be called again to change the key', async () => { const apiKey1 = '12345'; const apiKey2 = '67890'; @@ -197,45 +176,46 @@ describe('#auth()', function () { ); sdk.auth(apiKey1); - await sdk.getAnythingApikey().then(({ data }) => expect(data).to.equal('/anything/apiKey?apiKey=12345')); + await sdk.getAnythingApikey().then(({ data }) => expect(data).toBe('/anything/apiKey?apiKey=12345')); sdk.auth(apiKey2); - await sdk.getAnythingApikey().then(({ data }) => expect(data).to.equal('/anything/apiKey?apiKey=67890')); + await sdk.getAnythingApikey().then(({ data }) => expect(data).toBe('/anything/apiKey?apiKey=67890')); }); - describe('quirks', function () { + describe('quirks', () => { let quirks; - before(async function () { + beforeAll(async () => { const authQuirksOas = await loadSpec(require.resolve('./__fixtures__/definitions/auth-quirks.json')); quirks = api(authQuirksOas as unknown as OASDocument); // Because the `POST /anything` operation allows either an OAuth2 token or Basic Auth the // quirks case we're testing is that you should be able to supply either a single OAuth2 token // or a username+password and it should be able to intelligently handle both. - expect(authQuirksOas.paths['/anything'].post.security).to.deep.equal([ + // eslint-disable-next-line jest/no-standalone-expect + expect(authQuirksOas.paths['/anything'].post.security).toStrictEqual([ { oauth2: ['write:things'] }, { basicAuth: [] }, ]); }); - it('should support an operation that has OR auth requirements (supplying Basic Auth)', async function () { + it('should support an operation that has OR auth requirements (supplying Basic Auth)', async () => { const authHeader = `Basic ${Buffer.from(`${user}:${pass}`).toString('base64')}`; fetchMock.post('https://httpbin.org/anything', mockResponses.headers); quirks.auth(user, pass); await quirks.postAnything().then(({ data }) => { - expect(data).to.have.deep.property('authorization', authHeader); + expect(data).toHaveProperty('authorization', authHeader); }); }); - it('should support an operation that has OR auth requirements (supplying an OAuth2 token)', async function () { + it('should support an operation that has OR auth requirements (supplying an OAuth2 token)', async () => { fetchMock.post('https://httpbin.org/anything', mockResponses.headers); quirks.auth(apiKey); await quirks.postAnything().then(({ data }) => { - expect(data).to.have.deep.property('authorization', `Bearer ${apiKey}`); + expect(data).toHaveProperty('authorization', `Bearer ${apiKey}`); }); }); }); diff --git a/packages/api/test/cache-custom.test.ts b/packages/api/test/cache-custom.test.ts index be965666..79728368 100644 --- a/packages/api/test/cache-custom.test.ts +++ b/packages/api/test/cache-custom.test.ts @@ -1,7 +1,6 @@ import fs from 'fs/promises'; import path from 'path'; -import { expect } from 'chai'; import fetchMock from 'fetch-mock'; import api from '../src'; @@ -9,11 +8,11 @@ import Cache from '../src/cache'; import loadSpec from './helpers/load-spec'; -describe('cache (custom directory)', function () { +describe('cache (custom directory)', () => { let cacheDir; let originalCacheDir; - beforeEach(async function () { + beforeEach(async () => { originalCacheDir = Cache.dir; cacheDir = path.join(__dirname, '..', '.api-test'); @@ -21,7 +20,7 @@ describe('cache (custom directory)', function () { await fs.mkdir(cacheDir, { recursive: true }); }); - afterEach(async function () { + afterEach(async () => { await fs.rmdir(cacheDir, { recursive: true }); Cache.setCacheDir(originalCacheDir); @@ -29,11 +28,11 @@ describe('cache (custom directory)', function () { fetchMock.restore(); }); - it('should support supplying a custom cache directory', async function () { + it('should support supplying a custom cache directory', async () => { const uspto = await loadSpec('@readme/oas-examples/3.0/json/uspto.json'); // Our custom caching directory should be empty. - expect(await fs.readdir(cacheDir)).to.have.length(0); + await expect(fs.readdir(cacheDir)).resolves.toHaveLength(0); fetchMock.get('https://example.com/openapi.json', uspto); fetchMock.get('https://developer.uspto.gov/ds-api/', { status: 200 }); @@ -44,10 +43,10 @@ describe('cache (custom directory)', function () { // Our custom caching directory should have our cached spec in it. const files = [...(await fs.readdir(cacheDir)), ...(await fs.readdir(path.join(cacheDir, 'specs')))]; - expect(files).to.deep.equal(['cache.json', 'specs', 'f2068ebf6ce28b51a8467bf7ac53bbae.json']); + expect(files).toStrictEqual(['cache.json', 'specs', 'f2068ebf6ce28b51a8467bf7ac53bbae.json']); const cache = await fs.readFile(path.join(cacheDir, 'cache.json'), 'utf8').then(JSON.parse); - expect(cache).to.deep.equal({ + expect(cache).toStrictEqual({ bcace67532514a49e663e471602b7be6: { hash: 'f2068ebf6ce28b51a8467bf7ac53bbae', original: 'https://example.com/openapi.json', diff --git a/packages/api/test/cache-tmp.test.ts b/packages/api/test/cache-tmp.test.ts index e51bdb1b..a0cdedb1 100644 --- a/packages/api/test/cache-tmp.test.ts +++ b/packages/api/test/cache-tmp.test.ts @@ -1,27 +1,24 @@ import os from 'os'; -import { expect } from 'chai'; -import mockRequire from 'mock-require'; - -mockRequire('find-cache-dir', () => undefined); - -// We need to load `Cache` here after `find-cache-dir` in order for that mock to get picked up. -// eslint-disable-next-line import/first import Cache from '../src/cache'; -describe('cache (temp dir handling)', function () { +jest.mock('find-cache-dir', () => { + return () => undefined; +}); + +describe('cache (temp dir handling)', () => { // Since this test is mocking out the `find-cache-dir` module for a single test, it needs to be // run separately from the rest of the cache tests, otherwise all of those tests would use this // mocked out version. - it('should fallback to an os-level temp directory if a cache directory cannot be determined', async function () { + it('should fallback to an os-level temp directory if a cache directory cannot be determined', async () => { await Cache.reset(); const dir = os.tmpdir(); // eslint-disable-next-line no-new new Cache('http://example.com/readme.json'); - expect(Cache.dir).to.match(new RegExp(dir)); - expect(Cache.cacheStore).to.match(new RegExp(dir)); - expect(Cache.specsCache).to.match(new RegExp(dir)); + expect(Cache.dir).toMatch(new RegExp(dir)); + expect(Cache.cacheStore).toMatch(new RegExp(dir)); + expect(Cache.specsCache).toMatch(new RegExp(dir)); }); }); diff --git a/packages/api/test/cache.test.ts b/packages/api/test/cache.test.ts index c5ef902f..abedb38c 100644 --- a/packages/api/test/cache.test.ts +++ b/packages/api/test/cache.test.ts @@ -3,22 +3,18 @@ import type { OASDocument } from 'oas/dist/rmoas.types'; import fs from 'fs/promises'; import path from 'path'; -import chai, { assert, expect } from 'chai'; import fetchMock from 'fetch-mock'; import uniqueTempDir from 'unique-temp-dir'; import Cache from '../src/cache'; -import chaiPlugins from './helpers/chai-plugins'; import loadSpec from './helpers/load-spec'; -chai.use(chaiPlugins); - let petstoreSpec; let readmeSpec; -describe('cache', function () { - before(async function () { +describe('cache', () => { + beforeAll(async () => { petstoreSpec = await loadSpec('@readme/oas-examples/3.0/json/petstore.json'); readmeSpec = await loadSpec('@readme/oas-examples/3.0/json/readme.json'); @@ -27,47 +23,47 @@ describe('cache', function () { Cache.setCacheDir(uniqueTempDir()); }); - describe('#load', function () { - describe('raw object', function () { - it('should return a raw object if a JSON object was initially supplied', async function () { + describe('#load', () => { + describe('raw object', () => { + it('should return a raw object if a JSON object was initially supplied', async () => { const res = await new Cache(readmeSpec as unknown as OASDocument).load(); - expect(res).to.deep.equal(readmeSpec); + expect(res).toStrictEqual(readmeSpec); }); - it('should return a raw object if supplied, but still validate and dereference it', async function () { + it('should return a raw object if supplied, but still validate and dereference it', async () => { const res = await new Cache(petstoreSpec as unknown as OASDocument).load(); - expect(Object.keys((res.paths['/pet'].post as any).requestBody.content)).to.deep.equal([ + expect(Object.keys((res.paths['/pet'].post as any).requestBody.content)).toStrictEqual([ 'application/json', 'application/xml', ]); }); }); - describe('ReadMe registry UUID', function () { - it('should resolve the shorthand `@petstore/v1.0#uuid` syntax to the ReadMe API', function () { - expect(new Cache('@petstore/v1.0#n6kvf10vakpemvplx').uri).to.equal( + describe('ReadMe registry UUID', () => { + it('should resolve the shorthand `@petstore/v1.0#uuid` syntax to the ReadMe API', () => { + expect(new Cache('@petstore/v1.0#n6kvf10vakpemvplx').uri).toBe( 'https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplx' ); }); - it('should resolve the shorthand `@petstore#uuid` syntax to the ReadMe API', function () { - expect(new Cache('@petstore#n6kvf10vakpemvplx').uri).to.equal( + it('should resolve the shorthand `@petstore#uuid` syntax to the ReadMe API', () => { + expect(new Cache('@petstore#n6kvf10vakpemvplx').uri).toBe( 'https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplx' ); }); - it("shouldn't try to resolve improperly formatted shorthand accessors to the ReadMe API", function () { - expect(new Cache('n6kvf10vakpemvplx').uri).to.equal('n6kvf10vakpemvplx'); + it("shouldn't try to resolve improperly formatted shorthand accessors to the ReadMe API", () => { + expect(new Cache('n6kvf10vakpemvplx').uri).toBe('n6kvf10vakpemvplx'); }); - it('should be able to load a definition', async function () { + it('should be able to load a definition', async () => { fetchMock.get('https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplxn', readmeSpec); const cacheStore = new Cache('@readme/v1.0#n6kvf10vakpemvplxn'); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); - expect(await cacheStore.load()).to.have.deep.property('info', { + await expect(cacheStore.load()).resolves.toHaveProperty('info', { description: 'Create beautiful product and API documentation with our developer friendly platform.', version: '2.0.0', title: 'API Endpoints', @@ -78,20 +74,20 @@ describe('cache', function () { }, }); - expect(cacheStore.get().paths['/api-specification'].get.parameters).to.be.dereferenced; - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.get().paths['/api-specification'].get.parameters).toBeDereferenced(); + expect(cacheStore.isCached()).toBe(true); fetchMock.restore(); }); }); - describe('URL', function () { - it('should be able to load a definition', async function () { + describe('URL', () => { + it('should be able to load a definition', async () => { fetchMock.get('http://example.com/readme.json', readmeSpec); const cacheStore = new Cache('http://example.com/readme.json'); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); - expect(await cacheStore.load()).to.have.deep.property('info', { + await expect(cacheStore.load()).resolves.toHaveProperty('info', { description: 'Create beautiful product and API documentation with our developer friendly platform.', version: '2.0.0', title: 'API Endpoints', @@ -102,27 +98,22 @@ describe('cache', function () { }, }); - expect(cacheStore.get().paths['/api-specification'].get.parameters).to.be.dereferenced; - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.get().paths['/api-specification'].get.parameters).toBeDereferenced(); + expect(cacheStore.isCached()).toBe(true); fetchMock.restore(); }); - it('should error if the url cannot be reached', async function () { + it('should error if the url cannot be reached', async () => { fetchMock.get('https://example.com/unknown.json', { status: 404 }); - await new Cache('https://example.com/unknown.json') - .load() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal( - 'Unable to retrieve URL (https://example.com/unknown.json). Reason: Not Found' - ); - }); + await expect(new Cache('https://example.com/unknown.json').load()).rejects.toThrow( + 'Unable to retrieve URL (https://example.com/unknown.json). Reason: Not Found' + ); fetchMock.restore(); }); - it('should convert yaml to json', async function () { + it('should convert yaml to json', async () => { const spec = await fs.readFile(require.resolve('@readme/oas-examples/3.0/yaml/readme.yaml'), 'utf8'); fetchMock.get('https://example.com/readme.yaml', spec); @@ -130,130 +121,124 @@ describe('cache', function () { const cacheStore = new Cache(definition); const hash = Cache.getCacheHash(definition); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); await cacheStore.load(); - expect(cacheStore.get().paths['/api-specification'].get.parameters).to.be.dereferenced; - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.get().paths['/api-specification'].get.parameters).toBeDereferenced(); + expect(cacheStore.isCached()).toBe(true); fetchMock.restore(); const cached = cacheStore.getCache(); - expect(cached).to.have.property(hash); + expect(cached).toHaveProperty(hash); }); }); - describe('file', function () { - it('should be able to load a definition', async function () { + describe('file', () => { + it('should be able to load a definition', async () => { const cacheStore = new Cache(require.resolve('@readme/oas-examples/3.0/json/readme.json')); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); await cacheStore.load(); - expect(cacheStore.get().paths['/api-specification'].get.parameters).to.be.dereferenced; - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.get().paths['/api-specification'].get.parameters).toBeDereferenced(); + expect(cacheStore.isCached()).toBe(true); }); - it('should be able to handle a relative path', async function () { + it('should be able to handle a relative path', async () => { const cacheStore = new Cache('../api/test/__fixtures__/oas.json'); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); await cacheStore.load(); - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.isCached()).toBe(true); }); - it('should convert yaml to json', async function () { + it('should convert yaml to json', async () => { const file = require.resolve('@readme/oas-examples/3.0/yaml/readme.yaml'); const cacheStore = new Cache(file); const hash = Cache.getCacheHash(file); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); await cacheStore.load(); - expect(cacheStore.get().paths['/api-specification'].get.parameters).to.be.dereferenced; - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.get().paths['/api-specification'].get.parameters).toBeDereferenced(); + expect(cacheStore.isCached()).toBe(true); const cached = cacheStore.getCache(); - expect(cached).to.have.property(hash); + expect(cached).toHaveProperty(hash); }); }); }); - describe('#save()', function () { - it('should error if definition is a swagger file', async function () { - await new Cache(require.resolve('@readme/oas-examples/2.0/json/petstore.json')) - .load() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal('Sorry, this module only supports OpenAPI definitions.'); - }); + describe('#save()', () => { + it('should error if definition is a swagger file', async () => { + await expect(new Cache(require.resolve('@readme/oas-examples/2.0/json/petstore.json')).load()).rejects.toThrow( + 'Sorry, this module only supports OpenAPI definitions.' + ); }); - it('should error if definition is not a valid openapi file', async function () { - await new Cache(require.resolve('../package.json')) - .load() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal("Sorry, that doesn't look like a valid OpenAPI definition."); - }); + it('should error if definition is not a valid openapi file', async () => { + await expect(new Cache(require.resolve('../package.json')).load()).rejects.toThrow( + "Sorry, that doesn't look like a valid OpenAPI definition." + ); }); - it('should cache a new file', async function () { + it('should cache a new file', async () => { await Cache.reset(); const file = require.resolve('@readme/oas-examples/3.0/json/readme.json'); const cacheStore = new Cache(file); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); await cacheStore.load(); - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.isCached()).toBe(true); }); - it('should be able to cache a definition that contains a circular reference', async function () { + it('should be able to cache a definition that contains a circular reference', async () => { const file = require.resolve('@readme/oas-examples/3.0/json/circular'); const cacheStore = new Cache(file); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); await cacheStore.load(); - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.isCached()).toBe(true); }); - it('should be able to load and cache an OpenAPI 3.1 definition', async function () { + it('should be able to load and cache an OpenAPI 3.1 definition', async () => { const file = require.resolve('@readme/oas-examples/3.1/json/petstore.json'); const cacheStore = new Cache(file); - expect(cacheStore.isCached()).to.be.false; + expect(cacheStore.isCached()).toBe(false); await cacheStore.load(); - expect(cacheStore.isCached()).to.be.true; + expect(cacheStore.isCached()).toBe(true); }); }); - describe('#get', function () { - it('should return an object if the current uri is an object (used for unit testing)', function () { + describe('#get', () => { + it('should return an object if the current uri is an object (used for unit testing)', () => { const loaded = new Cache(readmeSpec as unknown as OASDocument).get(); - expect(loaded).to.deep.equal(readmeSpec); + expect(loaded).toStrictEqual(readmeSpec); }); - it('should load a file out of cache', async function () { + it('should load a file out of cache', async () => { const file = require.resolve('@readme/oas-examples/3.0/json/readme.json'); const cacheStore = new Cache(file); await cacheStore.load(); const loaded = cacheStore.get(); - expect(loaded).to.have.property('components'); - expect(loaded).to.have.property('info'); - expect(loaded).to.have.property('paths'); - expect(loaded).to.have.property('servers'); + expect(loaded).toHaveProperty('components'); + expect(loaded).toHaveProperty('info'); + expect(loaded).toHaveProperty('paths'); + expect(loaded).toHaveProperty('servers'); }); - it('should support the legacy `path` property in the cache store', async function () { + it('should support the legacy `path` property in the cache store', async () => { await Cache.reset(); const file = require.resolve('@readme/oas-examples/3.0/yaml/readme.yaml'); @@ -266,22 +251,22 @@ describe('cache', function () { delete cache[cacheKey].hash; - expect(Object.keys(cache)).to.have.length(1); + expect(Object.keys(cache)).toHaveLength(1); const loaded = cacheStore.get(); - expect(loaded).to.have.property('components'); - expect(loaded).to.have.property('info'); - expect(loaded).to.have.property('paths'); - expect(loaded).to.have.property('servers'); + expect(loaded).toHaveProperty('components'); + expect(loaded).toHaveProperty('info'); + expect(loaded).toHaveProperty('paths'); + expect(loaded).toHaveProperty('servers'); }); - it('should error if the file is not cached', function () { + it('should error if the file is not cached', () => { const file = require.resolve('@readme/oas-examples/3.0/json/security.json'); const cacheStore = new Cache(file); expect(() => { return cacheStore.get(); - }).to.throw(`${file} has not been cached yet and must do so before being retrieved.`); + }).toThrow(`${file} has not been cached yet and must do so before being retrieved.`); }); }); }); diff --git a/packages/api/test/cli/codegen/languages/typescript.test.ts b/packages/api/test/cli/codegen/languages/typescript.test.ts index b9cf87c3..720e580f 100644 --- a/packages/api/test/cli/codegen/languages/typescript.test.ts +++ b/packages/api/test/cli/codegen/languages/typescript.test.ts @@ -1,55 +1,85 @@ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "assertSDKFixture"] }] */ import type { TSGeneratorOptions } from '../../../../src/cli/codegen/languages/typescript'; import { promises as fs } from 'fs'; import path from 'path'; -import chai, { assert, expect } from 'chai'; import fetchMock from 'fetch-mock'; import Oas from 'oas'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; import uniqueTempDir from 'unique-temp-dir'; import TSGenerator from '../../../../src/cli/codegen/languages/typescript'; import Storage from '../../../../src/cli/storage'; -import chaiPlugins from '../../../helpers/chai-plugins'; +import * as packageInfo from '../../../../src/packageInfo'; import { responses as mockResponse } from '../../../helpers/fetch-mock'; import loadSpec from '../../../helpers/load-spec'; -chai.use(chaiPlugins); -chai.use(sinonChai); - function assertSDKFixture(file: string, fixture: string, opts: TSGeneratorOptions = {}) { - return async function () { + return async () => { const oas = await loadSpec(require.resolve(file)).then(Oas.init); await oas.dereference({ preserveRefAsJSONSchemaTitle: true }); const ts = new TSGenerator(oas, file, fixture, opts); - expect(await ts.generator()).toMatchSDKFixture(fixture); + const actualFiles = await ts.generator(); + + // Determine if the generated code matches what we've got in our fixture. + const dir = path.resolve(path.join(__dirname, '..', '..', '..', '__fixtures__', 'sdk', fixture)); + + let expectedFiles: string[]; + try { + expectedFiles = await fs.readdir(dir); + } catch (err) { + /** + * @todo it'd be cool if we could supply this with a `--update` arg to create the fixture dir + */ + throw new Error(`No SDK fixture directory exists for "${fixture}"`); + } + + // Assert that the files we're generating are what we're expecting in the fixture directory. + // We're sorting this data because `index.d.ts` files are generated last but are first in the + // filesystem. + const sortedActualFiles = Object.keys(actualFiles); + sortedActualFiles.sort(); + expect(sortedActualFiles).toStrictEqual(expectedFiles); + + // Assert that each generated file is the same as in the fixture. + await Promise.all( + expectedFiles.map(filename => { + const actual = actualFiles[filename]; + + // We have to wrap in our current package version into the `<>` placeholder so + // we don't need to worry about committing package versions into source control or trying + // to mock out our `packageInfo` library, potentially causing sideeffects in other tests. + return new Promise((resolve, reject) => { + fs.readFile(path.join(dir, filename), 'utf8') + .then(expected => expected.replace('<>', packageInfo.PACKAGE_VERSION)) + .then(expected => { + expect(actual).toBe(expected); + resolve(true); + }) + .catch(reject); + }); + }) + ); // Make sure that we can load the SDK without any TS compilation errors. const sdk = await import(`../../../__fixtures__/sdk/${fixture}`).then(r => r.default); - expect(sdk.constructor.name).to.equal('SDK'); + expect(sdk.constructor.name).toBe('SDK'); }; } -describe('typescript', function () { - beforeEach(function () { - // Package installation and codegen can take a bit. - this.currentTest.timeout(20000); - }); - - describe('#installer', function () { - beforeEach(function () { +describe('typescript', () => { + describe('#installer', () => { + beforeEach(() => { Storage.setStorageDir(uniqueTempDir()); }); - afterEach(function () { + afterEach(() => { Storage.reset(); }); - it('should install a `package.json` and the required packages', async function () { - const logger = sinon.spy(); + it('should install a `package.json` and the required packages', async () => { + const logger = jest.fn(); const file = require.resolve('@readme/oas-examples/3.0/json/petstore.json'); const oas = await loadSpec(file).then(Oas.init); @@ -65,14 +95,14 @@ describe('typescript', function () { .readFile(path.join(storage.getIdentifierStorageDir(), 'package.json'), 'utf-8') .then(JSON.parse); - expect(pkgJson).to.deep.equal({ + expect(pkgJson).toStrictEqual({ name: '@api/petstore', version: '1.0.0', main: './index.ts', types: './index.d.ts', }); - expect(logger).to.be.calledWith('npm install --save --dry-run api json-schema-to-ts@beta oas'); + expect(logger).toHaveBeenCalledWith('npm install --save --dry-run api json-schema-to-ts@beta oas'); /** * NPM has an incredibly difficult time trying to resolve this temp dir when installing @@ -85,10 +115,10 @@ describe('typescript', function () { * @fixme */ // expect(logger).to.be.calledWith(`npm install --save --dry-run ${storage.getIdentifierStorageDir()}`); - }); + }, 20000); }); - describe('#generator', function () { + describe('#generator', () => { it( 'should generate typescript (by default)', assertSDKFixture('../../../__fixtures__/definitions/simple.json', 'simple-ts') @@ -114,14 +144,14 @@ describe('typescript', function () { assertSDKFixture('../../../__fixtures__/definitions/response-title-quirks.json', 'response-title-quirks') ); - it.skip('should handle a operations with a `default` response'); + it.todo('should handle a operations with a `default` response'); it( 'should handle an api that has discriminators and no operation ids', assertSDKFixture('../../../__fixtures__/definitions/alby.json', 'alby') ); - describe('javascript generation', function () { + describe('javascript generation', () => { it( 'should generate a CommonJS library', assertSDKFixture('../../../__fixtures__/definitions/simple.json', 'simple-js-cjs', { outputJS: true }) @@ -136,64 +166,64 @@ describe('typescript', function () { ); }); - describe('integration', function () { - afterEach(function () { + describe('integration', () => { + afterEach(() => { fetchMock.restore(); }); - it('should be able to make an API request (TS)', async function () { + it('should be able to make an API request (TS)', async () => { const sdk = await import('../../../__fixtures__/sdk/simple-ts').then(r => r.default); fetchMock.get('http://petstore.swagger.io/v2/pet/findByStatus?status=available', mockResponse.searchParams); await sdk.findPetsByStatus({ status: ['available'] }).then(({ data, status, headers, res }) => { - expect(data).to.equal('/v2/pet/findByStatus?status=available'); - expect(status).to.equal(200); - expect(headers).to.have.deep.property('constructor').to.have.deep.property('name', 'Headers'); - expect(res).to.have.deep.property('constructor').to.have.deep.property('name', 'Response'); + expect(data).toBe('/v2/pet/findByStatus?status=available'); + expect(status).toBe(200); + expect(headers.constructor.name).toBe('Headers'); + expect(res.constructor.name).toBe('Response'); }); }); - it('should be able to make an API request with an `accept` header`', async function () { + it('should be able to make an API request with an `accept` header`', async () => { const sdk = await import('../../../__fixtures__/sdk/simple-ts').then(r => r.default); fetchMock.get('http://petstore.swagger.io/v2/pet/findByStatus?status=available', mockResponse.headers); await sdk .findPetsByStatus({ status: ['available'], accept: 'application/xml' }) .then(({ data, status, headers, res }) => { - expect(data).to.have.deep.property('accept', 'application/xml'); - expect(status).to.equal(200); - expect(headers).to.have.deep.property('constructor').to.have.deep.property('name', 'Headers'); - expect(res).to.have.deep.property('constructor').to.have.deep.property('name', 'Response'); + expect(data).toHaveProperty('accept', 'application/xml'); + expect(status).toBe(200); + expect(headers.constructor.name).toBe('Headers'); + expect(res.constructor.name).toBe('Response'); }); }); - it('should be able to make an API request (JS + CommonJS)', async function () { + it('should be able to make an API request (JS + CommonJS)', async () => { const sdk = await import('../../../__fixtures__/sdk/simple-js-cjs').then(r => r.default); fetchMock.get('http://petstore.swagger.io/v2/pet/findByStatus?status=available', mockResponse.searchParams); await sdk.findPetsByStatus({ status: ['available'] }).then(({ data, status, headers, res }) => { - expect(data).to.equal('/v2/pet/findByStatus?status=available'); - expect(status).to.equal(200); - expect(headers).to.have.deep.property('constructor').to.have.deep.property('name', 'Headers'); - expect(res).to.have.deep.property('constructor').to.have.deep.property('name', 'Response'); + expect(data).toBe('/v2/pet/findByStatus?status=available'); + expect(status).toBe(200); + expect(headers.constructor.name).toBe('Headers'); + expect(res.constructor.name).toBe('Response'); }); }); - it('should be able to make an API request (JS + ESM)', async function () { + it('should be able to make an API request (JS + ESM)', async () => { const sdk = await import('../../../__fixtures__/sdk/simple-js-esm').then(r => r.default); fetchMock.get('http://petstore.swagger.io/v2/pet/findByStatus?status=available', mockResponse.searchParams); await sdk.findPetsByStatus({ status: ['available'] }).then(({ data, status, headers, res }) => { - expect(data).to.equal('/v2/pet/findByStatus?status=available'); - expect(status).to.equal(200); - expect(headers).to.have.deep.property('constructor').to.have.deep.property('name', 'Headers'); - expect(res).to.have.deep.property('constructor').to.have.deep.property('name', 'Response'); + expect(data).toBe('/v2/pet/findByStatus?status=available'); + expect(status).toBe(200); + expect(headers.constructor.name).toBe('Headers'); + expect(res.constructor.name).toBe('Response'); }); }); }); - describe('error handling', function () { - it('should fail on an API definition that has no `paths`', async function () { + describe('error handling', () => { + it('should fail on an API definition that has no `paths`', async () => { const oas = Oas.init({ openapi: '3.0.3', info: { @@ -204,29 +234,20 @@ describe('typescript', function () { }); const ts = new TSGenerator(oas, 'no-paths', './no-paths.json'); - await ts - .generator() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal( - 'Sorry, this OpenAPI definition does not have any operation paths to generate an SDK for.' - ); - }); + await expect(ts.generator()).rejects.toThrow( + 'Sorry, this OpenAPI definition does not have any operation paths to generate an SDK for.' + ); }); - it('should fail on an API definition that contains circular references', async function () { + it('should fail on an API definition that contains circular references', async () => { const oas = await loadSpec('@readme/oas-examples/3.0/json/circular.json').then(Oas.init); await oas.dereference({ preserveRefAsJSONSchemaTitle: true }); - try { - // eslint-disable-next-line no-new - new TSGenerator(oas, 'circular', './circular.json'); - assert.fail(); - } catch (err) { - expect(err.message).to.equal( - 'Sorry, this library does not yet support generating an SDK for an OpenAPI definition that contains circular references.' - ); - } + expect(() => { + return new TSGenerator(oas, 'circular', './circular.json'); + }).toThrow( + 'Sorry, this library does not yet support generating an SDK for an OpenAPI definition that contains circular references.' + ); }); }); }); diff --git a/packages/api/test/cli/codegen/languages/typescript/smoketest.test.ts b/packages/api/test/cli/codegen/languages/typescript/smoketest.test.ts index 39f30742..b4ad3b06 100644 --- a/packages/api/test/cli/codegen/languages/typescript/smoketest.test.ts +++ b/packages/api/test/cli/codegen/languages/typescript/smoketest.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable mocha/no-setup-in-describe */ /** * With this smoketest suite you can run SDK codegen assertions a number of different ways: * @@ -16,7 +15,6 @@ * @example Everything * npm run test:smoke */ -import { expect } from 'chai'; import Oas from 'oas'; import OASNormalize from 'oas-normalize'; @@ -26,7 +24,7 @@ import realWorldAPIs from '../../../../datasets/real-world-apis.json'; // These APIs don't have any schemas so they should only be generating an `index.ts`. const APIS_WITHOUT_SCHEMAS = ['poemist.com']; -const args: { chunks?: string; chunk?: string; random?: boolean } = Object.fromEntries( +const args: { chunk?: string; chunks?: string; random?: boolean } = Object.fromEntries( process.argv .filter(a => a.startsWith('--')) .map(a => { @@ -55,16 +53,11 @@ if (args.chunks && args.chunk) { dataset = realWorldAPIs; } -describe('typescript smoketest', function () { - beforeEach(function () { - // Test timeout is huge here because CI can be slow, some API definitions are huge can take a - // while to download + codegen. - this.currentTest.timeout(180000); // 3 minutes - this.currentTest.slow(5000); - }); - +describe('typescript smoketest', () => { dataset.forEach(({ name, url }) => { - it(`should generate an SDK for \`${name}\``, async function () { + // The test timeout is huge on this because CI can be slow as some API definitions are huge and + // can take a while to download + codegen. + it(`should generate an SDK for \`${name}\``, async () => { const spec = await new OASNormalize(url).validate({ convertToLatest: true }).catch(err => { // If this fails for any reason we should know. Catching and re-throwing here for the sake // of test verbosity. @@ -78,10 +71,10 @@ describe('typescript smoketest', function () { const res = await ts.generator(); if (APIS_WITHOUT_SCHEMAS.includes(name)) { - expect(Object.keys(res)).to.deep.equal(['index.ts']); + expect(Object.keys(res)).toStrictEqual(['index.ts']); } else { - expect(Object.keys(res)).to.deep.equal(['index.ts', 'schemas.ts', 'types.ts']); + expect(Object.keys(res)).toStrictEqual(['index.ts', 'schemas.ts', 'types.ts']); } - }); + }, 180000); }); }); diff --git a/packages/api/test/cli/codegen/languages/typescript/utils.test.ts b/packages/api/test/cli/codegen/languages/typescript/utils.test.ts index 3929d20a..fa2e532b 100644 --- a/packages/api/test/cli/codegen/languages/typescript/utils.test.ts +++ b/packages/api/test/cli/codegen/languages/typescript/utils.test.ts @@ -1,59 +1,57 @@ -import { expect } from 'chai'; - import { docblockEscape, generateTypeName, wordWrap } from '../../../../../src/cli/codegen/languages/typescript/util'; -describe('ts codegen utils', function () { - describe('#docblockEscape', function () { - it('should not touch a safe string', function () { - expect(docblockEscape('This is a short sentence.')).to.equal('This is a short sentence.'); +describe('ts codegen utils', () => { + describe('#docblockEscape', () => { + it('should not touch a safe string', () => { + expect(docblockEscape('This is a short sentence.')).toBe('This is a short sentence.'); }); - it('should escape an unsafe docblock', function () { - expect(docblockEscape('/* this in a docblock will break a JS file */')).to.equal( + it('should escape an unsafe docblock', () => { + expect(docblockEscape('/* this in a docblock will break a JS file */')).toBe( '/\\* this in a docblock will break a JS file *\\/' ); - expect(docblockEscape('/** this in a docblock will break a JS file **/')).to.equal( + expect(docblockEscape('/** this in a docblock will break a JS file **/')).toBe( '/\\** this in a docblock will break a JS file **\\/' ); - expect(docblockEscape('**/myfiles/some_folder**')).to.equal('**\\/myfiles/some_folder**'); + expect(docblockEscape('**/myfiles/some_folder**')).toBe('**\\/myfiles/some_folder**'); }); }); - describe('#generateTypeName', function () { - it('should generate safe names', function () { - expect(generateTypeName('a')).to.equal('A'); - expect(generateTypeName('abc')).to.equal('Abc'); - expect(generateTypeName('ABcd')).to.equal('ABcd'); - expect(generateTypeName('$Abc_123')).to.equal('Abc123'); - expect(generateTypeName('123_$Abc')).to.equal('$123Abc'); - expect(generateTypeName('Abc-de-f')).to.equal('AbcDeF'); + describe('#generateTypeName', () => { + it('should generate safe names', () => { + expect(generateTypeName('a')).toBe('A'); + expect(generateTypeName('abc')).toBe('Abc'); + expect(generateTypeName('ABcd')).toBe('ABcd'); + expect(generateTypeName('$Abc_123')).toBe('Abc123'); + expect(generateTypeName('123_$Abc')).toBe('$123Abc'); + expect(generateTypeName('Abc-de-f')).toBe('AbcDeF'); }); - it('should generate a safe name from the string to constant work we have in codegen for $ref pointers', function () { - expect(generateTypeName('::convert::Pet')).to.equal('ConvertPet'); + it('should generate a safe name from the string to constant work we have in codegen for $ref pointers', () => { + expect(generateTypeName('::convert::Pet')).toBe('ConvertPet'); }); - it('should sanitize reserved words', function () { - expect(generateTypeName('const')).to.equal('$Const'); - expect(generateTypeName('delete')).to.equal('$Delete'); - expect(generateTypeName('let')).to.equal('$Let'); - expect(generateTypeName('new')).to.equal('$New'); + it('should sanitize reserved words', () => { + expect(generateTypeName('const')).toBe('$Const'); + expect(generateTypeName('delete')).toBe('$Delete'); + expect(generateTypeName('let')).toBe('$Let'); + expect(generateTypeName('new')).toBe('$New'); }); }); - describe('#wordwrap', function () { - it('should not touch a short string', function () { - expect(wordWrap('This is a short sentence.')).to.equal('This is a short sentence.'); + describe('#wordwrap', () => { + it('should not touch a short string', () => { + expect(wordWrap('This is a short sentence.')).toBe('This is a short sentence.'); }); - it('should wrap a long string', function () { + it('should wrap a long string', () => { expect( wordWrap( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla feugiat ante sed porta viverra. Sed sagittis urna odio, id tempus massa facilisis non. Fusce a elit ante. Sed non velit at sapien posuere semper' ) - ).to.equal( + ).toBe( [ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla feugiat ante sed porta', 'viverra. Sed sagittis urna odio, id tempus massa facilisis non. Fusce a elit ante. Sed', diff --git a/packages/api/test/cli/storage.test.ts b/packages/api/test/cli/storage.test.ts index 6fa727bf..c343568c 100644 --- a/packages/api/test/cli/storage.test.ts +++ b/packages/api/test/cli/storage.test.ts @@ -1,68 +1,70 @@ import type { OASDocument } from 'oas/dist/rmoas.types'; +import assert from 'assert'; import fs from 'fs/promises'; import path from 'path'; -import chai, { assert, expect } from 'chai'; import fetchMock from 'fetch-mock'; import 'isomorphic-fetch'; import uniqueTempDir from 'unique-temp-dir'; import Storage from '../../src/cli/storage'; import { PACKAGE_VERSION } from '../../src/packageInfo'; -import chaiPlugins from '../helpers/chai-plugins'; import loadSpec from '../helpers/load-spec'; -chai.use(chaiPlugins); - let petstoreSimple; -describe('storage', function () { - before(async function () { +describe('storage', () => { + beforeAll(async () => { petstoreSimple = await loadSpec('@readme/oas-examples/3.0/json/petstore-simple.json'); }); - beforeEach(function () { + beforeEach(() => { Storage.setStorageDir(uniqueTempDir()); }); - afterEach(function () { - Storage.reset(); + afterEach(async () => { + await Storage.reset().catch(() => { + // We can do our best to try to clean up after ourselves here but if removing any of the + // storage directories fails it's likely because the OS already cleaned them up, in which + // case we shouldn't fail these tests. + }); + fetchMock.restore(); }); - describe('#generateIntegrityHash', function () { - it('should generate an integrity hash for an API definition', function () { - expect(Storage.generateIntegrityHash(petstoreSimple as OASDocument)).to.equal( + describe('#generateIntegrityHash', () => { + it('should generate an integrity hash for an API definition', () => { + expect(Storage.generateIntegrityHash(petstoreSimple as OASDocument)).toBe( 'sha512-otRF5TLMeDczSJlrmWLNDHLfmXg+C98oa/I/X2WWycwngh+a6WsbnjTbfwKGRU5DFbagOn2qX2SRvtBGOBRVGg==' ); }); }); - describe('#setIdentifier', function () { - it('should be able to update the identifier', function () { + describe('#setIdentifier', () => { + it('should be able to update the identifier', () => { const storage = new Storage('@petstore#n6kvf10vakpemvplx'); - expect(storage.identifier).to.be.undefined; + expect(storage.identifier).toBeUndefined(); storage.setIdentifier('petstore'); - expect(storage.identifier).to.equal('petstore'); + expect(storage.identifier).toBe('petstore'); }); }); - describe('#isInLockFile', function () { - it('should be able to look up in the lockfile by a given source', async function () { + describe('#isInLockFile', () => { + it('should be able to look up in the lockfile by a given source', async () => { fetchMock.get('https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplx', petstoreSimple); const source = '@petstore/v1.0#n6kvf10vakpemvplx'; const storage = new Storage(source, 'petstore'); - expect(Storage.isInLockFile({ source })).to.be.false; + expect(Storage.isInLockFile({ source })).toBe(false); await storage.load(); - expect(Storage.isInLockFile({ source })).to.deep.equal({ + expect(Storage.isInLockFile({ source })).toStrictEqual({ identifier: 'petstore', source, integrity: 'sha512-otRF5TLMeDczSJlrmWLNDHLfmXg+C98oa/I/X2WWycwngh+a6WsbnjTbfwKGRU5DFbagOn2qX2SRvtBGOBRVGg==', @@ -70,17 +72,17 @@ describe('storage', function () { }); }); - it('should be able to look up in the lockfile by a given identifier', async function () { + it('should be able to look up in the lockfile by a given identifier', async () => { fetchMock.get('https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplx', petstoreSimple); const source = '@petstore/v1.0#n6kvf10vakpemvplx'; const storage = new Storage(source, 'petstore'); - expect(Storage.isInLockFile({ identifier: 'petstore' })).to.be.false; + expect(Storage.isInLockFile({ identifier: 'petstore' })).toBe(false); await storage.load(); - expect(Storage.isInLockFile({ identifier: 'petstore' })).to.deep.equal({ + expect(Storage.isInLockFile({ identifier: 'petstore' })).toStrictEqual({ identifier: 'petstore', source, integrity: 'sha512-otRF5TLMeDczSJlrmWLNDHLfmXg+C98oa/I/X2WWycwngh+a6WsbnjTbfwKGRU5DFbagOn2qX2SRvtBGOBRVGg==', @@ -89,8 +91,8 @@ describe('storage', function () { }); }); - describe('#load', function () { - it('should throw an error when a non-HTTP(S) url is supplied', async function () { + describe('#load', () => { + it('should throw an error when a non-HTTP(S) url is supplied', async () => { await new Storage('htt://example.com/openapi.json', 'invalid-url') .load() .then(() => assert.fail()) @@ -100,39 +102,36 @@ describe('storage', function () { // the `node-fetch` error message. const isNode18 = Number(process.versions.node.split('.')[0]) >= 18; if (isNode18) { - expect(err.message).to.equal('fetch failed'); - expect(err.cause.message).to.equal('unknown scheme'); + expect(err.message).toBe('fetch failed'); + expect(err.cause.message).toBe('unknown scheme'); } else { - expect(err.message).to.equal('Only HTTP(S) protocols are supported'); + expect(err.message).toBe('Only HTTP(S) protocols are supported'); } }); }); - it('should throw an error if neither a url or file are detected', async function () { - await new Storage('/this/is/not/a/real/path.json', 'nonexistent-path') - .load() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.match(/supply a URL or a path on your filesystem/); - }); + it('should throw an error if neither a url or file are detected', async () => { + await expect(new Storage('/this/is/not/a/real/path.json', 'nonexistent-path').load()).rejects.toThrow( + /supply a URL or a path on your filesystem/ + ); }); - describe('ReadMe registry UUID', function () { - it('should resolve the shorthand `@petstore/v1.0#uuid` syntax to the ReadMe API', async function () { + describe('ReadMe registry UUID', () => { + it('should resolve the shorthand `@petstore/v1.0#uuid` syntax to the ReadMe API', async () => { fetchMock.get('https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplx', petstoreSimple); const storage = new Storage('@petstore/v1.0#n6kvf10vakpemvplx', 'petstore'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); - expect(await storage.load()).to.have.deep.property('info', { + await expect(storage.load()).resolves.toHaveProperty('info', { version: '1.0.0', title: 'Single Path', description: 'This is a slimmed down single path version of the Petstore definition.', }); - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'petstore', source: '@petstore/v1.0#n6kvf10vakpemvplx', integrity: 'sha512-otRF5TLMeDczSJlrmWLNDHLfmXg+C98oa/I/X2WWycwngh+a6WsbnjTbfwKGRU5DFbagOn2qX2SRvtBGOBRVGg==', @@ -140,20 +139,20 @@ describe('storage', function () { }); }); - it('should resolve the shorthand `@petstore#uuid` syntax to the ReadMe API', async function () { + it('should resolve the shorthand `@petstore#uuid` syntax to the ReadMe API', async () => { fetchMock.get('https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplx', petstoreSimple); const storage = new Storage('@petstore#n6kvf10vakpemvplx', 'petstore'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); - expect(await storage.load()).to.have.deep.property('info', { + await expect(storage.load()).resolves.toHaveProperty('info', { version: '1.0.0', title: 'Single Path', description: 'This is a slimmed down single path version of the Petstore definition.', }); - expect(storage.getAPIDefinition().paths['/pet/{id}'].get).to.deep.equal({ + expect(storage.getAPIDefinition().paths['/pet/{id}'].get).toStrictEqual({ tags: ['pet'], summary: 'Find a pet', description: 'This operation will find a pet in the database.', @@ -165,8 +164,8 @@ describe('storage', function () { security: [], }); - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'petstore', source: '@petstore#n6kvf10vakpemvplx', integrity: 'sha512-otRF5TLMeDczSJlrmWLNDHLfmXg+C98oa/I/X2WWycwngh+a6WsbnjTbfwKGRU5DFbagOn2qX2SRvtBGOBRVGg==', @@ -174,39 +173,39 @@ describe('storage', function () { }); }); - it("shouldn't try to resolve improperly formatted shorthand accessors to the ReadMe API", async function () { + it("shouldn't try to resolve improperly formatted shorthand accessors to the ReadMe API", async () => { const storage = new Storage('n6kvf10vakpemvplx', 'petstore'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage .load() .then(() => assert.fail()) .catch(err => { - expect(err.message).to.contain('n6kvf10vakpemvplx'); - expect(err.message).to.match( + expect(err.message).toContain('n6kvf10vakpemvplx'); + expect(err.message).toMatch( /Sorry, we were unable to load an API definition from (.*). Please either supply a URL or a path on your filesystem/ ); }); }); }); - describe('URL', function () { - it('should be able to load a definition', async function () { + describe('URL', () => { + it('should be able to load a definition', async () => { fetchMock.get('http://example.com/readme.json', petstoreSimple); const storage = new Storage('http://example.com/readme.json', 'petstore'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); - expect(await storage.load()).to.have.deep.property('info', { + await expect(storage.load()).resolves.toHaveProperty('info', { version: '1.0.0', title: 'Single Path', description: 'This is a slimmed down single path version of the Petstore definition.', }); - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'petstore', source: 'http://example.com/readme.json', integrity: 'sha512-otRF5TLMeDczSJlrmWLNDHLfmXg+C98oa/I/X2WWycwngh+a6WsbnjTbfwKGRU5DFbagOn2qX2SRvtBGOBRVGg==', @@ -214,30 +213,27 @@ describe('storage', function () { }); }); - it('should error if the url cannot be reached', async function () { + it('should error if the url cannot be reached', async () => { fetchMock.get('http://example.com/unknown.json', { status: 404 }); - await new Storage('http://example.com/unknown.json', '404ing-url') - .load() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal('Unable to retrieve URL (http://example.com/unknown.json). Reason: Not Found'); - }); + await expect(new Storage('http://example.com/unknown.json', '404ing-url').load()).rejects.toThrow( + 'Unable to retrieve URL (http://example.com/unknown.json). Reason: Not Found' + ); }); - it('should convert yaml to json', async function () { + it('should convert yaml to json', async () => { const spec = await fs.readFile(require.resolve('@readme/oas-examples/3.0/yaml/readme.yaml'), 'utf8'); fetchMock.get('http://example.com/readme.yaml', spec); const storage = new Storage('http://example.com/readme.yaml', 'readme-yaml'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage.load(); - expect(storage.getAPIDefinition().paths['/api-specification'].get.parameters).to.be.dereferenced; - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.getAPIDefinition().paths['/api-specification'].get.parameters).toBeDereferenced(); + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'readme-yaml', source: 'http://example.com/readme.yaml', integrity: 'sha512-UFZZJXO5wbz/bx6qLgZOMih0Qxd78fRRCjaSV1uSjOzpmV5AGWPXte508GMCQOYOEENESqtgpTyHAkzC1lJWWQ==', @@ -246,18 +242,18 @@ describe('storage', function () { }); }); - describe('file', function () { - it('should be able to load a definition', async function () { + describe('file', () => { + it('should be able to load a definition', async () => { const file = require.resolve('@readme/oas-examples/3.0/json/readme.json'); const storage = new Storage(file, 'readme'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage.load(); - expect(storage.getAPIDefinition().paths['/api-specification'].get.parameters).to.be.dereferenced; - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.getAPIDefinition().paths['/api-specification'].get.parameters).toBeDereferenced(); + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'readme', source: file, integrity: 'sha512-UFZZJXO5wbz/bx6qLgZOMih0Qxd78fRRCjaSV1uSjOzpmV5AGWPXte508GMCQOYOEENESqtgpTyHAkzC1lJWWQ==', @@ -265,22 +261,22 @@ describe('storage', function () { }); }); - it('should be able to handle a relative path', async function () { + it('should be able to handle a relative path', async () => { const file = '../api/test/__fixtures__/oas.json'; const storage = new Storage(file, 'relative-path'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage.load(); - expect(storage.isInLockfile()).to.be.true; - expect(storage.getAPIDefinition().info).to.deep.equal({ + expect(storage.isInLockfile()).toBe(true); + expect(storage.getAPIDefinition().info).toStrictEqual({ version: '1.0.0', title: 'Single Path', description: 'This is a slimmed down single path version of the Petstore definition.', }); - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'relative-path', source: file, integrity: 'sha512-Qi5BB9mfzkRqHe0rMvjRmKunNJ21zILF0e4KzYKi2hMw+zLfi2idmmn0lAngdRwqYdGIKTXUWhJNn0i3iDqUUg==', @@ -288,17 +284,17 @@ describe('storage', function () { }); }); - it('should convert yaml to json', async function () { + it('should convert yaml to json', async () => { const file = require.resolve('@readme/oas-examples/3.0/yaml/readme.yaml'); const storage = new Storage(file, 'readme-yaml'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage.load(); - expect(storage.getAPIDefinition().paths['/api-specification'].get.parameters).to.be.dereferenced; - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.getAPIDefinition().paths['/api-specification'].get.parameters).toBeDereferenced(); + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'readme-yaml', source: file, integrity: 'sha512-UFZZJXO5wbz/bx6qLgZOMih0Qxd78fRRCjaSV1uSjOzpmV5AGWPXte508GMCQOYOEENESqtgpTyHAkzC1lJWWQ==', @@ -308,35 +304,29 @@ describe('storage', function () { }); }); - describe('#save()', function () { - it('should error if definition is a swagger file', async function () { - await new Storage(require.resolve('@readme/oas-examples/2.0/json/petstore.json'), 'petstore') - .load() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal('Sorry, this module only supports OpenAPI definitions.'); - }); + describe('#save()', () => { + it('should error if definition is a swagger file', async () => { + await expect( + new Storage(require.resolve('@readme/oas-examples/2.0/json/petstore.json'), 'petstore').load() + ).rejects.toThrow('Sorry, this module only supports OpenAPI definitions.'); }); - it('should error if definition is not a valid openapi file', async function () { - await new Storage(require.resolve('../../package.json'), 'invalid') - .load() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal("Sorry, that doesn't look like a valid OpenAPI definition."); - }); + it('should error if definition is not a valid openapi file', async () => { + await expect(new Storage(require.resolve('../../package.json'), 'invalid').load()).rejects.toThrow( + "Sorry, that doesn't look like a valid OpenAPI definition." + ); }); - it('should save a new SDK', async function () { + it('should save a new SDK', async () => { const file = require.resolve('@readme/oas-examples/3.0/json/petstore-simple.json'); const storage = new Storage(file, 'petstore-simple'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage.load(); - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'petstore-simple', source: file, integrity: 'sha512-otRF5TLMeDczSJlrmWLNDHLfmXg+C98oa/I/X2WWycwngh+a6WsbnjTbfwKGRU5DFbagOn2qX2SRvtBGOBRVGg==', @@ -344,16 +334,16 @@ describe('storage', function () { }); }); - it('should be able to cache a definition that contains a circular reference', async function () { + it('should be able to cache a definition that contains a circular reference', async () => { const file = require.resolve('@readme/oas-examples/3.0/json/circular.json'); const storage = new Storage(file, 'circular'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage.load(); - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'circular', source: file, integrity: 'sha512-bxLv3OTzVucsauZih1VCprHQ7/e0iB/yzeuWdp1E1iq8o3MOYFAig+aMUkTqD71BNf/1/6B7NTkyjJXfrXgumA==', @@ -361,16 +351,16 @@ describe('storage', function () { }); }); - it('should be able to load and cache an OpenAPI 3.1 definition', async function () { + it('should be able to load and cache an OpenAPI 3.1 definition', async () => { const file = require.resolve('@readme/oas-examples/3.1/json/petstore.json'); const storage = new Storage(file, 'petstore'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage.load(); - expect(storage.isInLockfile()).to.be.true; - expect(storage.getFromLockfile()).to.deep.equal({ + expect(storage.isInLockfile()).toBe(true); + expect(storage.getFromLockfile()).toStrictEqual({ identifier: 'petstore', source: file, integrity: 'sha512-P1xkfSiktRFJUZdN90JslLk8FOecNZFypZOnDqh/Xcgw69iiO17dHXwaV6ENqnYGwxd1t4hwXpaXq/4V5AY3NQ==', @@ -379,12 +369,12 @@ describe('storage', function () { }); }); - describe('#saveSourceFiles()', function () { - it('should save source files into the storage identifiers directory', async function () { + describe('#saveSourceFiles()', () => { + it('should save source files into the storage identifiers directory', async () => { const file = require.resolve('@readme/oas-examples/3.0/json/petstore-simple.json'); const storage = new Storage(file, 'petstore-simple'); - expect(storage.isInLockfile()).to.be.false; + expect(storage.isInLockfile()).toBe(false); await storage.load(); @@ -392,30 +382,30 @@ describe('storage', function () { storage.saveSourceFiles(files); const sourceFile = await fs.readFile(path.join(storage.getIdentifierStorageDir(), 'index.js'), 'utf-8'); - expect(sourceFile).to.equal('// I am a source file'); + expect(sourceFile).toBe('// I am a source file'); }); }); - describe('#getAPIDefinition', function () { - it('should load a API definition out of storage', async function () { + describe('#getAPIDefinition', () => { + it('should load a API definition out of storage', async () => { const file = require.resolve('@readme/oas-examples/3.0/json/readme.json'); const storage = new Storage(file, 'readme'); await storage.load(); const spec = storage.getAPIDefinition(); - expect(spec).to.have.property('components'); - expect(spec).to.have.property('info'); - expect(spec).to.have.property('paths'); - expect(spec).to.have.property('servers'); + expect(spec).toHaveProperty('components'); + expect(spec).toHaveProperty('info'); + expect(spec).toHaveProperty('paths'); + expect(spec).toHaveProperty('servers'); }); - it('should error if the file is not saved', function () { + it('should error if the file is not saved', () => { const file = require.resolve('@readme/oas-examples/3.0/json/security.json'); const storage = new Storage(file, 'security'); expect(() => { return storage.getAPIDefinition(); - }).to.throw(`${file} has not been saved to storage yet and must do so before being retrieved.`); + }).toThrow(`${file} has not been saved to storage yet and must do so before being retrieved.`); }); }); }); diff --git a/packages/api/test/config.test.ts b/packages/api/test/config.test.ts index a8437de4..9f3340ee 100644 --- a/packages/api/test/config.test.ts +++ b/packages/api/test/config.test.ts @@ -1,6 +1,5 @@ import type { OASDocument } from 'oas/dist/rmoas.types'; -import { assert, expect } from 'chai'; import fetchMock from 'fetch-mock'; import uniqueTempDir from 'unique-temp-dir'; @@ -14,8 +13,8 @@ let petstore; let sdk; const petId = 123; -describe('#config()', function () { - before(async function () { +describe('#config()', () => { + beforeAll(async () => { petstore = await loadSpec('@readme/oas-examples/3.0/json/petstore.json'); // Set a unique cache dir so these tests won't collide with other tests and we don't need to go @@ -23,35 +22,30 @@ describe('#config()', function () { Cache.setCacheDir(uniqueTempDir()); }); - describe('timeout', function () { - beforeEach(function () { + describe('timeout', () => { + beforeEach(() => { sdk = api(petstore as unknown as OASDocument); }); - afterEach(function () { + afterEach(() => { fetchMock.restore(); }); - it('should override the default `fetch` timeout if present and fail if request takes too long', async function () { + it('should override the default `fetch` timeout if present and fail if request takes too long', async () => { fetchMock.delete(`http://petstore.swagger.io/v2/pet/${petId}`, mockResponses.delay(response, 500)); sdk.config({ timeout: 100 }); - await sdk - .deletePet({ petId }) - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal('The operation was aborted.'); - }); + await expect(sdk.deletePet({ petId })).rejects.toThrow('The operation was aborted.'); }); - it('should override the default `fetch` timeout and return if request is quick', async function () { + it('should override the default `fetch` timeout and return if request is quick', async () => { fetchMock.delete(`http://petstore.swagger.io/v2/pet/${petId}`, mockResponses.delay(response, 100)); sdk.config({ timeout: 500 }); await sdk.deletePet({ petId }).then(({ data }) => { - expect(data).to.deep.equal(response); + expect(data).toStrictEqual(response); }); }); }); diff --git a/packages/api/test/core/getJSONSchemaDefaults.test.ts b/packages/api/test/core/getJSONSchemaDefaults.test.ts index e0e2d69b..800ee510 100644 --- a/packages/api/test/core/getJSONSchemaDefaults.test.ts +++ b/packages/api/test/core/getJSONSchemaDefaults.test.ts @@ -1,18 +1,17 @@ -import { expect } from 'chai'; import Oas from 'oas'; import getJSONSchemaDefaults from '../../src/core/getJSONSchemaDefaults'; import loadSpec from '../helpers/load-spec'; -describe('#getJSONSchemaDefaults()', function () { - it('should get defaults off an operation', async function () { +describe('#getJSONSchemaDefaults()', () => { + it('should get defaults off an operation', async () => { const oas = await loadSpec('@readme/oas-examples/3.0/json/uspto.json').then(Oas.init); await oas.dereference(); const operation = oas.operation('/{dataset}/{version}/records', 'post'); const defaults = getJSONSchemaDefaults(operation.getParametersAsJSONSchema()); - expect(defaults).to.deep.equal({ + expect(defaults).toStrictEqual({ path: { version: 'v1', dataset: 'oa_citations', @@ -23,14 +22,14 @@ describe('#getJSONSchemaDefaults()', function () { }); }); - it('should be able to handle nested objects', async function () { + it('should be able to handle nested objects', async () => { const oas = await loadSpec('../__fixtures__/definitions/nested-defaults.json').then(Oas.init); await oas.dereference(); const operation = oas.operation('/pet', 'post'); const defaults = getJSONSchemaDefaults(operation.getParametersAsJSONSchema()); - expect(defaults).to.deep.equal({ + expect(defaults).toStrictEqual({ body: { name: 'buster', category: { @@ -40,15 +39,15 @@ describe('#getJSONSchemaDefaults()', function () { }); }); - it.skip('should be able to handle arrays with defaults'); + it.todo('should be able to handle arrays with defaults'); - it('shouldnt add empty objects where there are no required defaults', async function () { + it('shouldnt add empty objects where there are no required defaults', async () => { const oas = await loadSpec('@readme/oas-examples/3.1/json/parameters-style.json').then(Oas.init); await oas.dereference(); const operation = oas.operation('/cookies', 'get'); const defaults = getJSONSchemaDefaults(operation.getParametersAsJSONSchema()); - expect(defaults).to.deep.equal({}); + expect(defaults).toStrictEqual({}); }); }); diff --git a/packages/api/test/core/index.test.ts b/packages/api/test/core/index.test.ts index 162f901e..ba7745d9 100644 --- a/packages/api/test/core/index.test.ts +++ b/packages/api/test/core/index.test.ts @@ -1,18 +1,14 @@ -import chai, { assert, expect } from 'chai'; +import assert from 'assert'; + import fetchMock from 'fetch-mock'; import Oas from 'oas'; import APICore from '../../src/core'; import FetchError from '../../src/core/errors/fetchError'; -import chaiPlugins from '../helpers/chai-plugins'; import { responses as mockResponse } from '../helpers/fetch-mock'; import loadSpec from '../helpers/load-spec'; -chai.use(chaiPlugins); - -chai.use(chaiPlugins); - -describe('APICore', function () { +describe('APICore', () => { let petstore: APICore; let readme: APICore; let security: APICore; @@ -24,7 +20,7 @@ describe('APICore', function () { name: 'Buster', }; - beforeEach(async function () { + beforeEach(async () => { petstore = await loadSpec('@readme/oas-examples/3.0/json/petstore-expanded.json') .then(Oas.init) .then(oas => new APICore(oas)); @@ -42,12 +38,12 @@ describe('APICore', function () { .then(oas => new APICore(oas)); }); - afterEach(function () { + afterEach(() => { fetchMock.restore(); }); - describe('#fetchOperation', function () { - it('should make a request for a given operation with body + metadata parameters', async function () { + describe('#fetchOperation', () => { + it('should make a request for a given operation with body + metadata parameters', async () => { const slug = 'new-release'; const body = { title: 'revised title', @@ -60,7 +56,7 @@ describe('APICore', function () { readme.setServer('https://dash.readme.com/api/v1'); await readme.fetchOperation(operation, body, { slug }).then(({ data }) => { - expect(data).to.deep.equal({ + expect(data).toStrictEqual({ uri: '/api/v1/changelogs/new-release', requestBody: body, }); @@ -68,9 +64,9 @@ describe('APICore', function () { }); }); - describe('#fetch', function () { - describe('error handling', function () { - it('should reject for error-level status codes', async function () { + describe('#fetch', () => { + describe('error handling', () => { + it('should reject for error-level status codes', async () => { fetchMock.delete(`http://petstore.swagger.io/api/pets/${petId}`, { body: 'Could not find that pet.', status: 404, @@ -80,35 +76,35 @@ describe('APICore', function () { .fetch('/pets/{id}', 'delete', undefined, { id: petId }) .then(() => assert.fail()) .catch(err => { - expect(err).to.be.an.instanceOf(FetchError); - expect(err.status).to.equal(404); - expect(err.data).to.equal('Could not find that pet.'); - expect(err.headers).to.have.header('content-type', /text\/plain/); - expect(err.res).to.have.deep.property('constructor').to.have.deep.property('name', 'Response'); + expect(err).toBeInstanceOf(FetchError); + expect(err.status).toBe(404); + expect(err.data).toBe('Could not find that pet.'); + expect(err.headers).toHaveHeader('content-type', /text\/plain/); + expect(err.res.constructor.name).toBe('Response'); }); }); }); - describe('payload delivery', function () { - it('should pass through body for method + path', async function () { + describe('payload delivery', () => { + it('should pass through body for method + path', async () => { const body = { name: 'Buster' }; fetchMock.post('http://petstore.swagger.io/api/pets', mockResponse.real(body)); - await petstore.fetch('/pets', 'post', body).then(({ data }) => expect(data).to.deep.equal(body)); + await petstore.fetch('/pets', 'post', body).then(({ data }) => expect(data).toStrictEqual(body)); }); - it('should pass through parameters for method + path', async function () { + it('should pass through parameters for method + path', async () => { const slug = 'new-release'; fetchMock.put(`https://dash.readme.com/api/v1/changelogs/${slug}`, mockResponse.url('pathname')); readme.setServer('https://dash.readme.com/api/v1'); await readme.fetch('/changelogs/{slug}', 'put', undefined, { slug }).then(({ data }) => { - expect(data).to.equal('/api/v1/changelogs/new-release'); + expect(data).toBe('/api/v1/changelogs/new-release'); }); }); - it('should pass through parameters and body for method + path', async function () { + it('should pass through parameters and body for method + path', async () => { const slug = 'new-release'; const body = { title: 'revised title', @@ -119,17 +115,17 @@ describe('APICore', function () { readme.setServer('https://dash.readme.com/api/v1'); await readme.fetch('/changelogs/{slug}', 'put', body, { slug }).then(({ data }) => { - expect(data).to.deep.equal({ + expect(data).toStrictEqual({ uri: '/api/v1/changelogs/new-release', requestBody: body, }); }); }); - describe('query parameter encoding', function () { + describe('query parameter encoding', () => { let queryEncoding: APICore; - beforeEach(function () { + beforeEach(() => { queryEncoding = new APICore( Oas.init({ servers: [{ url: 'https://httpbin.org/' }], @@ -152,7 +148,7 @@ describe('APICore', function () { ); }); - it('should encode query parameters', async function () { + it('should encode query parameters', async () => { const params = { stringPound: 'something¬hing=true', stringHash: 'hash#data', @@ -168,13 +164,13 @@ describe('APICore', function () { fetchMock.get('glob:https://*.*', mockResponse.searchParams); await queryEncoding.fetch('/anything', 'get', undefined, params).then(({ data }) => { - expect(data).to.deep.equal( + expect(data).toBe( '/anything?stringPound=something%26nothing%3Dtrue&stringHash=hash%23data&stringArray=where%5B4%5D%3D10&stringWeird=properties%5B%22%24email%22%5D%20%3D%3D%20%22testing%22&array=something%26nothing%3Dtrue&array=nothing%26something%3Dfalse&array=another%20item' ); }); }); - it("should not double encode query params if they're already encoded", async function () { + it("should not double encode query params if they're already encoded", async () => { const params = { stringPound: encodeURIComponent('something¬hing=true'), stringHash: encodeURIComponent('hash#data'), @@ -190,7 +186,7 @@ describe('APICore', function () { fetchMock.get('glob:https://*.*', mockResponse.searchParams); await queryEncoding.fetch('/anything', 'get', undefined, params).then(({ data }) => { - expect(data).to.deep.equal( + expect(data).toBe( '/anything?stringPound=something%26nothing%3Dtrue&stringHash=hash%23data&stringArray=where%5B4%5D%3D10&stringWeird=properties%5B%22%24email%22%5D%20%3D%3D%20%22testing%22&array=something%26nothing%3Dtrue&array=nothing%26something%3Dfalse&array=another%20item' ); }); @@ -199,8 +195,8 @@ describe('APICore', function () { }); }); - describe('#setUserAgent()', function () { - it('should contain a custom user agent for the library in requests', async function () { + describe('#setUserAgent()', () => { + it('should contain a custom user agent for the library in requests', async () => { const userAgent = 'customUserAgent 1.0'; fetchMock.delete(`http://petstore.swagger.io/api/pets/${petId}`, mockResponse.headers); @@ -209,13 +205,13 @@ describe('APICore', function () { .setUserAgent(userAgent) .fetch('/pets/{id}', 'delete', undefined, { id: petId }) .then(({ data }) => { - expect(data).to.have.deep.property('user-agent', userAgent); + expect(data).toHaveProperty('user-agent', userAgent); }); }); }); - describe('#setAuth()', function () { - it('should pass along auth in the request', async function () { + describe('#setAuth()', () => { + it('should pass along auth in the request', async () => { const user = 'buster'; const pass = 'hunter1'; @@ -226,21 +222,21 @@ describe('APICore', function () { .setAuth(user, pass) .fetch('/anything/basic', 'post') .then(({ data }) => { - expect(data).to.have.deep.property('authorization', authHeader); + expect(data).toHaveProperty('authorization', authHeader); }); }); }); - describe('#setServer()', function () { - it('should support supplying a full server url', async function () { + describe('#setServer()', () => { + it('should support supplying a full server url', async () => { fetchMock.post('https://buster.example.com:3000/v14/', mockResponse.real(response)); serverVariables.setServer('https://buster.example.com:3000/v14'); - await serverVariables.fetch('/', 'post').then(({ data }) => expect(data).to.deep.equal(response)); + await serverVariables.fetch('/', 'post').then(({ data }) => expect(data).toStrictEqual(response)); }); - it('should support supplying a server url with server variables', async function () { + it('should support supplying a server url with server variables', async () => { fetchMock.post('http://dev.local/v14/', mockResponse.real(response)); serverVariables.setServer('http://{name}.local/{basePath}', { @@ -248,11 +244,11 @@ describe('APICore', function () { basePath: 'v14', }); - await serverVariables.fetch('/', 'post').then(({ data }) => expect(data).to.deep.equal(response)); + await serverVariables.fetch('/', 'post').then(({ data }) => expect(data).toStrictEqual(response)); }); - it.skip('should be able to supply a url on an OAS that has no servers defined'); + it.todo('should be able to supply a url on an OAS that has no servers defined'); - it.skip("should be able to supply a url that doesn't match any defined server"); + it.todo("should be able to supply a url that doesn't match any defined server"); }); }); diff --git a/packages/api/test/core/parseResponse.test.ts b/packages/api/test/core/parseResponse.test.ts index d3c7479f..b4b610af 100644 --- a/packages/api/test/core/parseResponse.test.ts +++ b/packages/api/test/core/parseResponse.test.ts @@ -1,10 +1,6 @@ -import chai, { expect } from 'chai'; import 'isomorphic-fetch'; import parseResponse from '../../src/core/parseResponse'; -import chaiPlugins from '../helpers/chai-plugins'; - -chai.use(chaiPlugins); const responseBody = JSON.stringify({ id: 9205436248879918000, @@ -16,8 +12,8 @@ const responseBody = JSON.stringify({ let response; -describe('#parseResponse', function () { - beforeEach(function () { +describe('#parseResponse', () => { + beforeEach(() => { response = new Response(responseBody, { status: 200, headers: { @@ -27,28 +23,28 @@ describe('#parseResponse', function () { }); }); - it('should parse `application/json` response as json', async function () { + it('should parse `application/json` response as json', async () => { const { data, status, headers, res } = await parseResponse(response); - expect(data).to.deep.equal(JSON.parse(responseBody)); - expect(status).to.equal(200); - expect(headers).to.have.header('content-type', 'application/json'); - expect(headers).to.have.header('x-custom-header', 'buster'); - expect(res).to.be.a('Response'); + expect(data).toStrictEqual(JSON.parse(responseBody)); + expect(status).toBe(200); + expect(headers).toHaveHeader('content-type', 'application/json'); + expect(headers).toHaveHeader('x-custom-header', 'buster'); + expect(res).toBeInstanceOf(Response); }); - it('should parse `application/vnd.api+json` as json', async function () { + it('should parse `application/vnd.api+json` as json', async () => { response.headers.set('Content-Type', 'application/vnd.api+json'); const { data, status, headers, res } = await parseResponse(response); - expect(data).to.deep.equal(JSON.parse(responseBody)); - expect(status).to.equal(200); - expect(headers).to.have.header('content-type', 'application/vnd.api+json'); - expect(headers).to.have.header('x-custom-header', 'buster'); - expect(res).to.be.a('Response'); + expect(data).toStrictEqual(JSON.parse(responseBody)); + expect(status).toBe(200); + expect(headers).toHaveHeader('content-type', 'application/vnd.api+json'); + expect(headers).toHaveHeader('x-custom-header', 'buster'); + expect(res).toBeInstanceOf(Response); }); - it('should parse non-json response as text', async function () { + it('should parse non-json response as text', async () => { const nonJsonResponseBody = ''; const nonJsonResponse = new Response('', { status: 202, @@ -59,13 +55,13 @@ describe('#parseResponse', function () { const { data, status, headers, res } = await parseResponse(nonJsonResponse); - expect(data).to.equal(nonJsonResponseBody); - expect(status).to.equal(202); - expect(headers).to.have.header('content-type', 'application/xml'); - expect(res).to.be.a('Response'); + expect(data).toBe(nonJsonResponseBody); + expect(status).toBe(202); + expect(headers).toHaveHeader('content-type', 'application/xml'); + expect(res).toBeInstanceOf(Response); }); - it('should not error if invalid json is returned', async function () { + it('should not error if invalid json is returned', async () => { // `JSON.parse('plain text')` will throw an exception, but if that happens we should just treat // the content as plain text. const invalidJsonResponse = new Response('plain text', { @@ -77,13 +73,13 @@ describe('#parseResponse', function () { const { data, status, headers, res } = await parseResponse(invalidJsonResponse); - expect(data).to.equal('plain text'); - expect(status).to.equal(404); - expect(headers).to.have.header('content-type', 'application/json'); - expect(res).to.be.a('Response'); + expect(data).toBe('plain text'); + expect(status).toBe(404); + expect(headers).toHaveHeader('content-type', 'application/json'); + expect(res).toBeInstanceOf(Response); }); - it('should default to JSON with wildcard content-type', async function () { + it('should default to JSON with wildcard content-type', async () => { const wildcardResponse = new Response(responseBody, { headers: { 'Content-Type': '*/*', @@ -92,13 +88,13 @@ describe('#parseResponse', function () { const { data, status, headers, res } = await parseResponse(wildcardResponse); - expect(data).to.deep.equal(JSON.parse(responseBody)); - expect(status).to.equal(200); - expect(headers).to.have.header('content-type', '*/*'); - expect(res).to.be.a('Response'); + expect(data).toStrictEqual(JSON.parse(responseBody)); + expect(status).toBe(200); + expect(headers).toHaveHeader('content-type', '*/*'); + expect(res).toBeInstanceOf(Response); }); - it('should return with empty string if there is no response', async function () { + it('should return with empty string if there is no response', async () => { const emptyResponse = new Response(null, { status: 204, headers: { @@ -108,9 +104,9 @@ describe('#parseResponse', function () { const { data, status, headers, res } = await parseResponse(emptyResponse); - expect(data).to.equal(''); - expect(status).to.equal(204); - expect(headers).to.have.header('content-type', 'application/json'); - expect(res).to.be.a('Response'); + expect(data).toBe(''); + expect(status).toBe(204); + expect(headers).toHaveHeader('content-type', 'application/json'); + expect(res).toBeInstanceOf(Response); }); }); diff --git a/packages/api/test/core/prepareAuth.test.ts b/packages/api/test/core/prepareAuth.test.ts index a04d425d..cda51375 100644 --- a/packages/api/test/core/prepareAuth.test.ts +++ b/packages/api/test/core/prepareAuth.test.ts @@ -1,6 +1,5 @@ import type { OASDocument } from 'oas/dist/rmoas.types'; -import { expect } from 'chai'; import Oas from 'oas'; import prepareAuth from '../../src/core/prepareAuth'; @@ -8,94 +7,94 @@ import loadSpec from '../helpers/load-spec'; let oas: Oas; -describe('#prepareAuth()', function () { - before(async function () { +describe('#prepareAuth()', () => { + beforeAll(async () => { oas = await loadSpec('@readme/oas-examples/3.0/json/security.json').then(Oas.init); }); - it('should not do anything if the operation has no auth', async function () { + it('should not do anything if the operation has no auth', async () => { const uspto = await loadSpec('@readme/oas-examples/3.0/json/uspto.json').then(Oas.init); const operation = uspto.operation('/', 'get'); const authKeys = ['12345']; - expect(prepareAuth(authKeys, operation)).to.deep.equal({}); + expect(prepareAuth(authKeys, operation)).toStrictEqual({}); }); - describe('single auth setups', function () { - describe('apiKey', function () { + describe('single auth setups', () => { + describe('apiKey', () => { const apiKey = '123457890'; - describe('in: query', function () { - it('should support query auth', function () { + describe('in: query', () => { + it('should support query auth', () => { const operation = oas.operation('/anything/apiKey', 'get'); const authKeys = [apiKey]; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ apiKey_query: '123457890', }); }); - it('should throw if you supply multiple auth keys', function () { + it('should throw if you supply multiple auth keys', () => { const operation = oas.operation('/anything/apiKey', 'get'); const authKeys = [apiKey, apiKey]; expect(() => { prepareAuth(authKeys, operation); - }).to.throw('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); + }).toThrow('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); }); }); - describe('in: header', function () { - it('should support header auth', function () { + describe('in: header', () => { + it('should support header auth', () => { const operation = oas.operation('/anything/apiKey', 'put'); const authKeys = [apiKey]; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ apiKey_header: '123457890', }); }); - it('should throw if you supply multiple auth keys', function () { + it('should throw if you supply multiple auth keys', () => { const operation = oas.operation('/anything/apiKey', 'put'); const authKeys = [apiKey, apiKey]; expect(() => { prepareAuth(authKeys, operation); - }).to.throw('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); + }).toThrow('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); }); }); - describe('in: cookie', function () { - it('should support cookie auth', function () { + describe('in: cookie', () => { + it('should support cookie auth', () => { const operation = oas.operation('/anything/apiKey', 'post'); const authKeys = [apiKey]; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ apiKey_cookie: '123457890', }); }); - it('should throw if you supply multiple auth keys', function () { + it('should throw if you supply multiple auth keys', () => { const operation = oas.operation('/anything/apiKey', 'post'); const authKeys = [apiKey, apiKey]; expect(() => { prepareAuth(authKeys, operation); - }).to.throw('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); + }).toThrow('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); }); }); }); - describe('HTTP', function () { - describe('scheme: basic', function () { + describe('HTTP', () => { + describe('scheme: basic', () => { const user = 'buster'; const pass = 'hunter1'; - it('should support basic auth', function () { + it('should support basic auth', () => { const operation = oas.operation('/anything/basic', 'post'); const authKeys = [user, pass]; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ basic: { user: 'buster', pass: 'hunter1', @@ -103,11 +102,11 @@ describe('#prepareAuth()', function () { }); }); - it('should allow you to not pass in a password', function () { + it('should allow you to not pass in a password', () => { const operation = oas.operation('/anything/basic', 'post'); const authKeys = [user]; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ basic: { user: 'buster', pass: '', @@ -116,90 +115,90 @@ describe('#prepareAuth()', function () { }); }); - describe('scheme: bearer', function () { + describe('scheme: bearer', () => { const apiKey = '123457890'; - it('should support bearer auth', function () { + it('should support bearer auth', () => { const operation = oas.operation('/anything/bearer', 'post'); const authKeys = [apiKey]; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ bearer: '123457890', }); }); - it('should throw if you pass in multiple bearer tokens', function () { + it('should throw if you pass in multiple bearer tokens', () => { const operation = oas.operation('/anything/bearer', 'post'); const authKeys = [apiKey, apiKey]; expect(() => { prepareAuth(authKeys, operation); - }).to.throw('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); + }).toThrow('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); }); }); }); - describe('OAuth 2', function () { + describe('OAuth 2', () => { const apiKey = '123457890'; - it('should support oauth2 auth', function () { + it('should support oauth2 auth', () => { const operation = oas.operation('/anything/oauth2', 'post'); const authKeys = [apiKey]; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ oauth2: '123457890', }); }); - it('should throw if you pass in multiple bearer tokens', function () { + it('should throw if you pass in multiple bearer tokens', () => { const operation = oas.operation('/anything/oauth2', 'post'); const authKeys = [apiKey, apiKey]; expect(() => { prepareAuth(authKeys, operation); - }).to.throw('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); + }).toThrow('Multiple auth tokens were supplied for this endpoint but only a single token is needed.'); }); }); }); - describe('multi auth configurations', function () { + describe('multi auth configurations', () => { let authQuirksOas; let securityMultipleOas; - before(async function () { + beforeAll(async () => { authQuirksOas = await loadSpec(require.resolve('../__fixtures__/definitions/auth-quirks.json')); securityMultipleOas = await loadSpec('@readme/oas-examples/3.0/json/security-multiple.json'); }); - describe('AND', function () { - it('should throw an exception on an operation that requires two forms of auth', function () { + describe('AND', () => { + it('should throw an exception on an operation that requires two forms of auth', () => { const multipleAuth = Oas.init(securityMultipleOas as unknown as OASDocument); const operation = multipleAuth.operation('/anything/and', 'post'); const authKeys = ['buster', 'hunter1']; expect(() => { prepareAuth(authKeys, operation); - }).to.throw( + }).toThrow( "Sorry, this operation currently requires multiple forms of authentication which this library doesn't yet support." ); }); - it('should allow usage if an operation has an AND config but one is a single token', function () { + it('should allow usage if an operation has an AND config but one is a single token', () => { const multipleAuth = Oas.init(securityMultipleOas as unknown as OASDocument); const operation = multipleAuth.operation('/anything/many-and-or', 'post'); const authKeys = ['123457890']; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ bearer_jwt: '123457890', }); }); - it('should allow usage if an operation has an AND config but one is username + password', function () { + it('should allow usage if an operation has an AND config but one is username + password', () => { const multipleAuth = Oas.init(securityMultipleOas as unknown as OASDocument); const operation = multipleAuth.operation('/anything/many-and-or', 'post'); const authKeys = ['buster', 'hunter1']; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ basic: { user: 'buster', pass: 'hunter1', @@ -208,23 +207,23 @@ describe('#prepareAuth()', function () { }); }); - describe('OR', function () { - it('should throw an exception on an operation that requires two forms of auth', function () { + describe('OR', () => { + it('should throw an exception on an operation that requires two forms of auth', () => { const authQuirks = Oas.init(authQuirksOas as unknown as OASDocument); const operation = authQuirks.operation('/anything/or-and', 'post'); const authKeys = ['buster', 'hunter1']; expect(() => { prepareAuth(authKeys, operation); - }).to.throw(/Credentials for Basic Authentication were supplied/); + }).toThrow(/Credentials for Basic Authentication were supplied/); }); - it('should support supplying username+password credentials to an operation that allows OAuth 2 or Basic', function () { + it('should support supplying username+password credentials to an operation that allows OAuth 2 or Basic', () => { const authQuirks = Oas.init(authQuirksOas as unknown as OASDocument); const operation = authQuirks.operation('/anything', 'post'); const authKeys = ['buster', 'hunter1']; - expect(prepareAuth(authKeys, operation)).to.deep.equal({ + expect(prepareAuth(authKeys, operation)).toStrictEqual({ basicAuth: { user: 'buster', pass: 'hunter1', diff --git a/packages/api/test/core/prepareParams.test.ts b/packages/api/test/core/prepareParams.test.ts index 0790faa9..cd7356f1 100644 --- a/packages/api/test/core/prepareParams.test.ts +++ b/packages/api/test/core/prepareParams.test.ts @@ -1,18 +1,17 @@ import fs from 'fs'; -import { assert, expect } from 'chai'; import Oas from 'oas'; import prepareParams from '../../src/core/prepareParams'; import payloadExamples from '../__fixtures__/definitions/payloads.json'; import loadSpec from '../helpers/load-spec'; -describe('#prepareParams', function () { +describe('#prepareParams', () => { let fileUploads: Oas; let readmeSpec: Oas; let usptoSpec: Oas; - beforeEach(async function () { + beforeEach(async () => { fileUploads = await loadSpec('@readme/oas-examples/3.0/json/file-uploads.json').then(Oas.init); await fileUploads.dereference(); @@ -23,29 +22,25 @@ describe('#prepareParams', function () { await usptoSpec.dereference(); }); - it('should throw an error if the operation has no parameters or request bodies and a body/metadata was supplied', async function () { + it('should throw an error if the operation has no parameters or request bodies and a body/metadata was supplied', async () => { const spec = await loadSpec('@readme/oas-examples/3.0/json/security.json').then(Oas.init); await spec.dereference(); const operation = spec.operation('/apiKey', 'get'); - await prepareParams(operation, {}, {}) - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal( - "You supplied metadata and/or body data for this operation but it doesn't have any documented parameters or request payloads. If you think this is an error please contact support for the API you're using." - ); - }); + await expect(prepareParams(operation, {}, {})).rejects.toThrow( + "You supplied metadata and/or body data for this operation but it doesn't have any documented parameters or request payloads. If you think this is an error please contact support for the API you're using." + ); }); - it('should prepare nothing if nothing was supplied (and the operation has no required defaults)', async function () { + it('should prepare nothing if nothing was supplied (and the operation has no required defaults)', async () => { const operation = readmeSpec.operation('/api-specification', 'post'); - expect(await prepareParams(operation)).to.deep.equal({}); - expect(await prepareParams(operation, {}, {})).to.deep.equal({}); + await expect(prepareParams(operation)).resolves.toStrictEqual({}); + await expect(prepareParams(operation, {}, {})).resolves.toStrictEqual({}); }); - it('should prepare body and metadata when both are supplied', async function () { + it('should prepare body and metadata when both are supplied', async () => { const operation = readmeSpec.operation('/api-specification', 'post'); const body = { spec: 'this is the contents of an api specification', @@ -55,7 +50,7 @@ describe('#prepareParams', function () { 'x-readme-version': '1.0', }; - expect(await prepareParams(operation, body, metadata)).to.deep.equal({ + await expect(prepareParams(operation, body, metadata)).resolves.toStrictEqual({ body: { spec: 'this is the contents of an api specification', }, @@ -65,16 +60,16 @@ describe('#prepareParams', function () { }); }); - it('should prepare body if body is a primitive', async function () { + it('should prepare body if body is a primitive', async () => { const operation = Oas.init(payloadExamples).operation('/primitiveBody', 'put'); const body = 'Brie cheeseburger ricotta.'; - expect(await prepareParams(operation, body, {})).to.deep.equal({ + await expect(prepareParams(operation, body, {})).resolves.toStrictEqual({ body, }); }); - it('should prepare body if body is an array', async function () { + it('should prepare body if body is an array', async () => { const operation = Oas.init(payloadExamples).operation('/arraySchema', 'put'); const body = [ { @@ -82,12 +77,12 @@ describe('#prepareParams', function () { }, ]; - expect(await prepareParams(operation, body, {})).to.deep.equal({ + await expect(prepareParams(operation, body, {})).resolves.toStrictEqual({ body, }); }); - it('should ignore supplied body data if the request has no request body', async function () { + it('should ignore supplied body data if the request has no request body', async () => { const spec = await loadSpec('@readme/oas-examples/3.0/json/petstore.json').then(Oas.init); await spec.dereference(); @@ -98,12 +93,12 @@ describe('#prepareParams', function () { petId: 1234, }; - expect(await prepareParams(operation, body, metadata)).to.deep.equal({ + await expect(prepareParams(operation, body, metadata)).resolves.toStrictEqual({ path: { petId: 1234 }, }); }); - it('should ignore a supplied second parameter if its an empty object', async function () { + it('should ignore a supplied second parameter if its an empty object', async () => { const spec = await loadSpec('@readme/oas-examples/3.0/json/petstore.json').then(Oas.init); await spec.dereference(); @@ -113,16 +108,16 @@ describe('#prepareParams', function () { status: ['available'], }; - expect(await prepareParams(operation, metadata, {})).to.deep.equal({ + await expect(prepareParams(operation, metadata, {})).resolves.toStrictEqual({ query: { status: ['available'], }, }); }); - describe('content types', function () { - describe('application/x-www-form-urlencoded', function () { - it('should support preparing formData payloads', async function () { + describe('content types', () => { + describe('application/x-www-form-urlencoded', () => { + it('should support preparing formData payloads', async () => { const operation = usptoSpec.operation('/{dataset}/{version}/records', 'post'); const body = { criteria: '*:*', @@ -133,7 +128,7 @@ describe('#prepareParams', function () { version: 'oa_citations', }; - expect(await prepareParams(operation, body, metadata)).to.deep.equal({ + await expect(prepareParams(operation, body, metadata)).resolves.toStrictEqual({ path: { dataset: 'v1', version: 'oa_citations', @@ -146,7 +141,7 @@ describe('#prepareParams', function () { // Since we're only sending `metadata` here we want to make sure that the path parameters in // it don't also get sent as `formData`. - it('should should filter out metadata parameters from being sent twice', async function () { + it('should should filter out metadata parameters from being sent twice', async () => { const operation = usptoSpec.operation('/{dataset}/{version}/records', 'post'); const metadata = { @@ -154,7 +149,7 @@ describe('#prepareParams', function () { version: 'oa_citations', }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ formData: { criteria: '*:*', }, @@ -166,88 +161,84 @@ describe('#prepareParams', function () { }); }); - describe('image/png', function () { - it('should support a file path payload', async function () { + describe('image/png', () => { + it('should support a file path payload', async () => { const operation = fileUploads.operation('/anything/image-png', 'post'); const body = `${__dirname}/../__fixtures__/owlbert.png`; const res = await prepareParams(operation, body); - expect(res.body).to.contain('data:image/png;name=owlbert.png;base64,'); - expect(res.files).to.have.property('owlbert.png').and.be.an.instanceOf(Buffer); + expect(res.body).toContain('data:image/png;name=owlbert.png;base64,'); + expect(res.files['owlbert.png']).toBeInstanceOf(Buffer); }); - it('should support a file stream payload', async function () { + it('should support a file stream payload', async () => { const operation = fileUploads.operation('/anything/image-png', 'post'); const body = fs.createReadStream('./test/__fixtures__/owlbert.png'); const res = await prepareParams(operation, body); - expect(res.body).to.contain('data:image/png;name=owlbert.png;base64,'); - expect(res.files).to.have.property('owlbert.png').and.be.an.instanceOf(Buffer); + expect(res.body).toContain('data:image/png;name=owlbert.png;base64,'); + expect(res.files['owlbert.png']).toBeInstanceOf(Buffer); }); }); - describe('multipart/form-data', function () { - it('should handle a multipart body when a property is a file path', async function () { + describe('multipart/form-data', () => { + it('should handle a multipart body when a property is a file path', async () => { const operation = fileUploads.operation('/anything/multipart-formdata', 'post'); const body = { documentFile: require.resolve('@readme/oas-examples/3.0/json/readme.json'), }; const res = await prepareParams(operation, body); - expect(res.body).to.have.property('documentFile').and.contain('data:application/json;name=readme.json;base64,'); - expect(res.files).to.have.property('readme.json').and.be.an.instanceOf(Buffer); + expect(res.body.documentFile).toContain('data:application/json;name=readme.json;base64,'); + expect(res.files['readme.json']).toBeInstanceOf(Buffer); }); - it('should handle when the file path is relative', async function () { + it('should handle when the file path is relative', async () => { const operation = fileUploads.operation('/anything/multipart-formdata', 'post'); const body = { documentFile: './test/__fixtures__/owlbert.png', }; const res = await prepareParams(operation, body); - expect(res.body).to.have.property('documentFile').and.contain('data:image/png;name=owlbert.png;base64,'); - expect(res.files).to.have.property('owlbert.png').and.be.an.instanceOf(Buffer); + expect(res.body.documentFile).toContain('data:image/png;name=owlbert.png;base64,'); + expect(res.files['owlbert.png']).toBeInstanceOf(Buffer); }); - it('should handle a multipart body when a property is a file stream', async function () { + it('should handle a multipart body when a property is a file stream', async () => { const operation = fileUploads.operation('/anything/multipart-formdata', 'post'); const body = { documentFile: fs.createReadStream('./test/__fixtures__/owlbert.png'), }; const res = await prepareParams(operation, body); - expect(res.body).to.have.property('documentFile').and.contain('data:image/png;name=owlbert.png;base64,'); - expect(res.files).to.have.property('owlbert.png').and.be.an.instanceOf(Buffer); + expect(res.body.documentFile).toContain('data:image/png;name=owlbert.png;base64,'); + expect(res.files['owlbert.png']).toBeInstanceOf(Buffer); }); }); }); - describe('file handling', function () { - it('should reject unknown file handlers', async function () { + describe('file handling', () => { + it('should reject unknown file handlers', async () => { const operation = fileUploads.operation('/anything/multipart-formdata', 'post'); const body = { documentFile: ['this is not a file handler'], }; - await prepareParams(operation, body) - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal( - 'The data supplied for the `documentFile` request body parameter is not a file handler that we support.' - ); - }); + await expect(prepareParams(operation, body)).rejects.toThrow( + 'The data supplied for the `documentFile` request body parameter is not a file handler that we support.' + ); }); // This test sounds weird but we don't have a great way to know if a string we have is a path // to a file that doesn't exist or the string contents of a file, so we're just passing along // file paths that don't exist right now. - it("should not reject files that don't exist", async function () { + it("should not reject files that don't exist", async () => { const operation = fileUploads.operation('/anything/multipart-formdata', 'post'); const body = { documentFile: './test/__fixtures__/owlbert.jpg', }; - expect(await prepareParams(operation, body)).to.deep.equal({ + await expect(prepareParams(operation, body)).resolves.toStrictEqual({ body: { documentFile: './test/__fixtures__/owlbert.jpg', }, @@ -255,28 +246,28 @@ describe('#prepareParams', function () { }); }); - describe('supplying just a body or metadata', function () { - it('should handle if supplied is a body', async function () { + describe('supplying just a body or metadata', () => { + it('should handle if supplied is a body', async () => { const operation = fileUploads.operation('/anything/multipart-formdata', 'post'); const body = { documentFile: 'this is the contents of a document', }; - expect(await prepareParams(operation, body)).to.deep.equal({ + await expect(prepareParams(operation, body)).resolves.toStrictEqual({ body, }); }); - it('should prepare a body if supplied is primitive', async function () { + it('should prepare a body if supplied is primitive', async () => { const operation = fileUploads.operation('/anything/image-png', 'post'); const body = 'this is a primitive value'; - expect(await prepareParams(operation, body)).to.deep.equal({ + await expect(prepareParams(operation, body)).resolves.toStrictEqual({ body, }); }); - it('should prepare just a body if supplied argument is an array', async function () { + it('should prepare just a body if supplied argument is an array', async () => { const operation = Oas.init(payloadExamples).operation('/arraySchema', 'put'); const body = [ { @@ -284,12 +275,12 @@ describe('#prepareParams', function () { }, ]; - expect(await prepareParams(operation, body)).to.deep.equal({ + await expect(prepareParams(operation, body)).resolves.toStrictEqual({ body, }); }); - it('should prepare metadata if more than 25% of the supplied argument lines up with known parameters', async function () { + it('should prepare metadata if more than 25% of the supplied argument lines up with known parameters', async () => { const operation = usptoSpec.operation('/{dataset}/{version}/records', 'post'); const body = { version: 'v1', @@ -297,7 +288,7 @@ describe('#prepareParams', function () { randomUnknownParameter: true, }; - expect(await prepareParams(operation, body)).to.deep.equal({ + await expect(prepareParams(operation, body)).resolves.toStrictEqual({ path: { version: 'v1', dataset: 'oa_citations', @@ -309,7 +300,7 @@ describe('#prepareParams', function () { }); }); - it('should prepare metadata if less than 25% of the supplied argument lines up with known parameters', async function () { + it('should prepare metadata if less than 25% of the supplied argument lines up with known parameters', async () => { const operation = usptoSpec.operation('/{dataset}/{version}/records', 'post'); const body = { randomUnknownParameter: true, @@ -319,7 +310,7 @@ describe('#prepareParams', function () { version: 'v1', // This a known parameter, but the others aren't and should be treated as body payload data. }; - expect(await prepareParams(operation, body)).to.deep.equal({ + await expect(prepareParams(operation, body)).resolves.toStrictEqual({ formData: { criteria: '*:*', randomUnknownParameter: true, @@ -335,13 +326,13 @@ describe('#prepareParams', function () { }); }); - it('should prepare just metadata if supplied is metadata', async function () { + it('should prepare just metadata if supplied is metadata', async () => { const operation = readmeSpec.operation('/api-specification', 'post'); const metadata = { 'x-readme-version': '1.0', }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ header: { 'x-readme-version': '1.0', }, @@ -349,56 +340,53 @@ describe('#prepareParams', function () { }); }); - describe('parameter types', function () { + describe('parameter types', () => { let parameterStyle; - beforeEach(async function () { + beforeEach(async () => { parameterStyle = await loadSpec('@readme/oas-examples/3.1/json/parameters-style.json').then(Oas.init); await parameterStyle.dereference(); }); - // eslint-disable-next-line mocha/no-setup-in-describe - [ + it.each([ ['cookies', '/cookies', 'get', 'cookie'], ['headers', '/anything/headers', 'get', 'header'], ['query', '/anything/query', 'get', 'query'], - ].forEach(([_, path, method, paramName]) => { - it(`should support ${_}`, async function () { - const operation = parameterStyle.operation(path, method); - const metadata = { - primitive: 'buster', - }; + ])('should support %s', async (_, path, method, paramName) => { + const operation = parameterStyle.operation(path, method); + const metadata = { + primitive: 'buster', + }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ - [paramName]: { - primitive: 'buster', - }, - }); + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ + [paramName]: { + primitive: 'buster', + }, }); }); - it('should support matching on case-insensitive header parameters', async function () { + it('should support matching on case-insensitive header parameters', async () => { const operation = parameterStyle.operation('/anything/headers', 'get'); const metadata = { PrimItive: 'buster', }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ header: { primitive: 'buster', }, }); }); - describe('`accept` header overrides', function () { - it('should support supplying an `accept` header parameter', async function () { + describe('`accept` header overrides', () => { + it('should support supplying an `accept` header parameter', async () => { const operation = parameterStyle.operation('/anything/headers', 'get'); const metadata = { primitive: 'buster', accept: 'application/json', }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ header: { primitive: 'buster', accept: 'application/json', @@ -406,14 +394,14 @@ describe('#prepareParams', function () { }); }); - it('should support supplying a case-insensitive `accept` header parameter', async function () { + it('should support supplying a case-insensitive `accept` header parameter', async () => { const operation = parameterStyle.operation('/anything/headers', 'get'); const metadata = { primitive: 'buster', ACCept: 'application/json', }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ header: { primitive: 'buster', accept: 'application/json', @@ -421,13 +409,13 @@ describe('#prepareParams', function () { }); }); - it('should support supplying **only** an `accept` header parameter', async function () { + it('should support supplying **only** an `accept` header parameter', async () => { const operation = parameterStyle.operation('/anything/headers', 'get'); const metadata = { accept: 'application/json', }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ header: { accept: 'application/json', }, @@ -435,7 +423,7 @@ describe('#prepareParams', function () { }); }); - it('should support path parameters', async function () { + it('should support path parameters', async () => { const operation = parameterStyle.operation('/anything/path/{primitive}/{array}/{object}', 'get'); const metadata = { primitive: 'buster', @@ -446,7 +434,7 @@ describe('#prepareParams', function () { }, }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ path: { primitive: 'buster', array: ['buster'], @@ -456,13 +444,13 @@ describe('#prepareParams', function () { }); }); - describe('defaults', function () { - it('should prefill defaults for required body parameters if not supplied', async function () { + describe('defaults', () => { + it('should prefill defaults for required body parameters if not supplied', async () => { const oas = await loadSpec('../__fixtures__/definitions/nested-defaults.json').then(Oas.init); await oas.dereference(); const operation = oas.operation('/pet', 'post'); - expect(await prepareParams(operation, { id: 404 })).to.deep.equal({ + await expect(prepareParams(operation, { id: 404 })).resolves.toStrictEqual({ body: { id: 404, category: { name: 'dog' }, @@ -471,14 +459,14 @@ describe('#prepareParams', function () { }); }); - it('should prefill defaults for required body parameters (on formData-used operations) if not supplied', async function () { + it('should prefill defaults for required body parameters (on formData-used operations) if not supplied', async () => { const operation = usptoSpec.operation('/{dataset}/{version}/records', 'post'); const metadata = { version: 'v2', dataset: 'dog_treats', }; - expect(await prepareParams(operation, metadata)).to.deep.equal({ + await expect(prepareParams(operation, metadata)).resolves.toStrictEqual({ formData: { criteria: '*:*', }, @@ -489,10 +477,10 @@ describe('#prepareParams', function () { }); }); - it('should prefill defaults for required metadata parameters if not supplied', async function () { + it('should prefill defaults for required metadata parameters if not supplied', async () => { const operation = usptoSpec.operation('/{dataset}/{version}/records', 'post'); - expect(await prepareParams(operation)).to.deep.equal({ + await expect(prepareParams(operation)).resolves.toStrictEqual({ formData: { criteria: '*:*', }, @@ -503,12 +491,12 @@ describe('#prepareParams', function () { }); }); - it('should not override any user-provided data with defaults', async function () { + it('should not override any user-provided data with defaults', async () => { const operation = usptoSpec.operation('/{dataset}/{version}/records', 'post'); const body = { criteria: 'query:dogs' }; const metadata = { version: 'v2', dataset: 'dog_treats' }; - expect(await prepareParams(operation, body, metadata)).to.deep.equal({ + await expect(prepareParams(operation, body, metadata)).resolves.toStrictEqual({ formData: { criteria: 'query:dogs', }, diff --git a/packages/api/test/datasets/real-world-apis.json b/packages/api/test/datasets/real-world-apis.json index caf910ec..f2189b6e 100644 --- a/packages/api/test/datasets/real-world-apis.json +++ b/packages/api/test/datasets/real-world-apis.json @@ -4469,21 +4469,6 @@ "version": "1.0.0", "url": "https://api.apis.guru/v2/specs/cnab-online.herokuapp.com/1.0.0/swagger.json" }, - { - "name": "codat.io:accounting", - "version": "2.1.0", - "url": "https://api.apis.guru/v2/specs/codat.io/accounting/2.1.0/openapi.json" - }, - { - "name": "codat.io:assess", - "version": "1.0", - "url": "https://api.apis.guru/v2/specs/codat.io/assess/1.0/openapi.json" - }, - { - "name": "codat.io:bank-feeds", - "version": "2.1.0", - "url": "https://api.apis.guru/v2/specs/codat.io/bank-feeds/2.1.0/openapi.json" - }, { "name": "codat.io:banking", "version": "2.1.0", @@ -4529,11 +4514,6 @@ "version": "v2", "url": "https://api.apis.guru/v2/specs/combell.com/v2/openapi.json" }, - { - "name": "configcat.com", - "version": "v1", - "url": "https://api.apis.guru/v2/specs/configcat.com/v1/openapi.json" - }, { "name": "conjur.local", "version": "5.3.0", diff --git a/packages/api/test/datasets/refresh-dataset b/packages/api/test/datasets/refresh-dataset index bb9d8405..c5b65e64 100755 --- a/packages/api/test/datasets/refresh-dataset +++ b/packages/api/test/datasets/refresh-dataset @@ -241,6 +241,10 @@ fetch('https://api.apis.guru/v2/list.json') delete apis['callfire.com']; delete apis['canada-holidays.ca']; delete apis['clickmeter.com']; + delete apis['codat.io:accounting']; + delete apis['codat.io:assess']; + delete apis['codat.io:bank-feeds']; + delete apis['configcat.com']; delete apis['corrently.io']; delete apis['cpy.re:peertube']; delete apis['credas.co.uk:pi']; diff --git a/packages/api/test/dist.test.ts b/packages/api/test/dist.test.ts index d466824e..8d457038 100644 --- a/packages/api/test/dist.test.ts +++ b/packages/api/test/dist.test.ts @@ -1,6 +1,5 @@ import type { OASDocument } from 'oas/dist/rmoas.types'; -import { expect } from 'chai'; import fetchMock from 'fetch-mock'; import uniqueTempDir from 'unique-temp-dir'; @@ -10,29 +9,29 @@ import Cache from '../src/cache'; import { responses as mockResponses } from './helpers/fetch-mock'; import loadSpec from './helpers/load-spec'; -describe('typescript dist verification', function () { - before(function () { +describe('typescript dist verification', () => { + beforeAll(() => { // Set a unique cache dir so these tests won't collide with other tests and we don't need to go // through the trouble of mocking out the filesystem. Cache.setCacheDir(uniqueTempDir()); }); - afterEach(function () { + afterEach(() => { fetchMock.restore(); }); - it('should be able to use the transpiled dist', async function () { + it('should be able to use the transpiled dist', async () => { fetchMock.post('https://developer.uspto.gov/ds-api/oa_citations/v1/records', mockResponses.url('pathname')); const uspto = await loadSpec('@readme/oas-examples/3.0/json/uspto.json'); const sdk = api(uspto as unknown as OASDocument); await sdk.performSearch().then(({ data }) => { - expect(data).to.equal('/ds-api/oa_citations/v1/records'); + expect(data).toBe('/ds-api/oa_citations/v1/records'); }); }); - it('should be able to set an auth token', async function () { + it('should be able to set an auth token', async () => { const user = 'buster'; const pass = 'hunter1'; @@ -44,7 +43,7 @@ describe('typescript dist verification', function () { sdk.auth(user, pass); await sdk.postAnythingBasic().then(({ data }) => { - expect(data).to.have.deep.property('authorization', authHeader); + expect(data).toHaveProperty('authorization', authHeader); }); }); }); diff --git a/packages/api/test/fetcher.test.ts b/packages/api/test/fetcher.test.ts index b9e82d74..ad2e3380 100644 --- a/packages/api/test/fetcher.test.ts +++ b/packages/api/test/fetcher.test.ts @@ -1,82 +1,80 @@ +import assert from 'assert'; import fs from 'fs/promises'; -import chai, { assert, expect } from 'chai'; import fetchMock from 'fetch-mock'; import Fetcher from '../src/fetcher'; -import chaiPlugins from './helpers/chai-plugins'; import loadSpec from './helpers/load-spec'; -chai.use(chaiPlugins); - let readmeSpec; -describe('fetcher', function () { - before(async function () { +describe('fetcher', () => { + beforeAll(async () => { readmeSpec = await loadSpec('@readme/oas-examples/3.0/json/readme.json'); }); - describe('#isAPIRegistryUUID', function () { - it('should detect the shorthand `@petstore/v1.0#uuid` syntax', function () { - expect(Fetcher.isAPIRegistryUUID('@petstore/v1.0#n6kvf10vakpemvplx')).to.be.true; + describe('#isAPIRegistryUUID', () => { + it('should detect the shorthand `@petstore/v1.0#uuid` syntax', () => { + expect(Fetcher.isAPIRegistryUUID('@petstore/v1.0#n6kvf10vakpemvplx')).toBe(true); }); - it('should detect the shorthand `@petstore#uuid` syntax', function () { - expect(Fetcher.isAPIRegistryUUID('@petstore#n6kvf10vakpemvplx')).to.be.true; + it('should detect the shorthand `@petstore#uuid` syntax', () => { + expect(Fetcher.isAPIRegistryUUID('@petstore#n6kvf10vakpemvplx')).toBe(true); }); - it("shouldn't detect improperly formatted shorthand registry accessors", function () { - expect(Fetcher.isAPIRegistryUUID('n6kvf10vakpemvplx')).to.be.false; + it("shouldn't detect improperly formatted shorthand registry accessors", () => { + expect(Fetcher.isAPIRegistryUUID('n6kvf10vakpemvplx')).toBe(false); }); - it("shouldn't detect urls as registry accessors", function () { - expect(Fetcher.isAPIRegistryUUID('https://example.com/openapi.json')).to.be.false; + it("shouldn't detect urls as registry accessors", () => { + expect(Fetcher.isAPIRegistryUUID('https://example.com/openapi.json')).toBe(false); }); - it("shouldn't detect absolute file paths as registry accessors", function () { + it("shouldn't detect absolute file paths as registry accessors", () => { const file = require.resolve('@readme/oas-examples/3.0/json/petstore-simple.json'); - expect(Fetcher.isAPIRegistryUUID(file)).to.be.false; + expect(Fetcher.isAPIRegistryUUID(file)).toBe(false); }); - it("shouldn't detect relative file paths as registry accessors", function () { - expect(Fetcher.isAPIRegistryUUID('../petstore.json')).to.be.false; + it("shouldn't detect relative file paths as registry accessors", () => { + expect(Fetcher.isAPIRegistryUUID('../petstore.json')).toBe(false); }); }); - describe('#isGitHubBlobURL', function () { - it('should detect GitHub blob URLs', function () { - expect(Fetcher.isGitHubBlobURL('https://github.com/readmeio/oas-examples/blob/main/3.1/json/petstore.json')).to.be - .true; + describe('#isGitHubBlobURL', () => { + it('should detect GitHub blob URLs', () => { + expect(Fetcher.isGitHubBlobURL('https://github.com/readmeio/oas-examples/blob/main/3.1/json/petstore.json')).toBe( + true + ); }); - it('should detect a schemeless GitHub blob URL as one', function () { - expect(Fetcher.isGitHubBlobURL('//github.com/readmeio/oas-examples/blob/main/3.1/json/petstore.json')).to.be.true; + it('should detect a schemeless GitHub blob URL as one', () => { + expect(Fetcher.isGitHubBlobURL('//github.com/readmeio/oas-examples/blob/main/3.1/json/petstore.json')).toBe(true); }); - it("shouldn't detect raw GitHub URLs as a blob URL", function () { + it("shouldn't detect raw GitHub URLs as a blob URL", () => { expect( Fetcher.isGitHubBlobURL('https://raw.githubusercontent.com/readmeio/oas-examples/main/3.1/json/petstore.json') - ).to.be.false; + ).toBe(false); }); }); - describe('#getProjectPrefixFromRegistryUUID', function () { - it('should retrieve the project prefix from the shorthand `@petstore/v1.0#uuid` syntax', function () { - expect(Fetcher.getProjectPrefixFromRegistryUUID('@petstore/v1.0#n6kvf10vakpemvplx')).to.equal('petstore'); + describe('#getProjectPrefixFromRegistryUUID', () => { + it('should retrieve the project prefix from the shorthand `@petstore/v1.0#uuid` syntax', () => { + expect(Fetcher.getProjectPrefixFromRegistryUUID('@petstore/v1.0#n6kvf10vakpemvplx')).toBe('petstore'); }); - it('should retrieve the project prefix from the shorthand `@petstore#uuid` syntax', function () { - expect(Fetcher.getProjectPrefixFromRegistryUUID('@petstore#n6kvf10vakpemvplx')).to.equal('petstore'); + it('should retrieve the project prefix from the shorthand `@petstore#uuid` syntax', () => { + expect(Fetcher.getProjectPrefixFromRegistryUUID('@petstore#n6kvf10vakpemvplx')).toBe('petstore'); }); - it("shouldn't return undefined on an improperly formatted shorthand registry accessor", function () { - expect(Fetcher.getProjectPrefixFromRegistryUUID('n6kvf10vakpemvplx')).to.be.undefined; + it("shouldn't return undefined on an improperly formatted shorthand registry accessor", () => { + expect(Fetcher.getProjectPrefixFromRegistryUUID('n6kvf10vakpemvplx')).toBeUndefined(); }); }); - describe('#load', function () { - it('should throw an error when a non-HTTP(S) url is supplied', async function () { + describe('#load', () => { + it('should throw an error when a non-HTTP(S) url is supplied', async () => { await new Fetcher('htt://example.com/openapi.json') .load() .then(() => assert.fail()) @@ -86,60 +84,60 @@ describe('fetcher', function () { // the `node-fetch` error message. const isNode18 = Number(process.versions.node.split('.')[0]) >= 18; if (isNode18) { - expect(err.message).to.equal('fetch failed'); - expect(err.cause.message).to.equal('unknown scheme'); + expect(err.message).toBe('fetch failed'); + expect(err.cause.message).toBe('unknown scheme'); } else { - expect(err.message).to.equal('Only HTTP(S) protocols are supported'); + expect(err.message).toBe('Only HTTP(S) protocols are supported'); } }); }); - it('should throw an error if neither a url or file are detected', async function () { + it('should throw an error if neither a url or file are detected', async () => { await new Fetcher('/this/is/not/a/real/path.json') .load() .then(() => assert.fail()) .catch(err => { - expect(err.message).to.match(/supply a URL or a path on your filesystem/); + expect(err.message).toMatch(/supply a URL or a path on your filesystem/); }); }); - describe('GitHub URLs', function () { - it('should resolve a GitHub blob URL to its accessible raw counterpart', function () { - expect(new Fetcher('https://github.com/readmeio/oas-examples/blob/main/3.1/json/petstore.json').uri).to.equal( + describe('GitHub URLs', () => { + it('should resolve a GitHub blob URL to its accessible raw counterpart', () => { + expect(new Fetcher('https://github.com/readmeio/oas-examples/blob/main/3.1/json/petstore.json').uri).toBe( 'https://raw.githubusercontent.com/readmeio/oas-examples/main/3.1/json/petstore.json' ); }); - it('should leave an already raw GitHub URL alone', function () { + it('should leave an already raw GitHub URL alone', () => { expect( new Fetcher('https://raw.githubusercontent.com/readmeio/oas-examples/main/3.1/json/petstore.json').uri - ).to.equal('https://raw.githubusercontent.com/readmeio/oas-examples/main/3.1/json/petstore.json'); + ).toBe('https://raw.githubusercontent.com/readmeio/oas-examples/main/3.1/json/petstore.json'); }); }); - describe('ReadMe registry UUID', function () { - it('should resolve the shorthand `@petstore/v1.0#uuid` syntax to the ReadMe API', function () { - expect(new Fetcher('@petstore/v1.0#n6kvf10vakpemvplx').uri).to.equal( + describe('ReadMe registry UUID', () => { + it('should resolve the shorthand `@petstore/v1.0#uuid` syntax to the ReadMe API', () => { + expect(new Fetcher('@petstore/v1.0#n6kvf10vakpemvplx').uri).toBe( 'https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplx' ); }); - it('should resolve the shorthand `@petstore#uuid` syntax to the ReadMe API', function () { - expect(new Fetcher('@petstore#n6kvf10vakpemvplx').uri).to.equal( + it('should resolve the shorthand `@petstore#uuid` syntax to the ReadMe API', () => { + expect(new Fetcher('@petstore#n6kvf10vakpemvplx').uri).toBe( 'https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplx' ); }); - it("shouldn't try to resolve improperly formatted shorthand accessors to the ReadMe API", function () { - expect(new Fetcher('n6kvf10vakpemvplx').uri).to.equal('n6kvf10vakpemvplx'); + it("shouldn't try to resolve improperly formatted shorthand accessors to the ReadMe API", () => { + expect(new Fetcher('n6kvf10vakpemvplx').uri).toBe('n6kvf10vakpemvplx'); }); - it('should be able to load a definition', async function () { + it('should be able to load a definition', async () => { fetchMock.get('https://dash.readme.com/api/v1/api-registry/n6kvf10vakpemvplxn', readmeSpec); const fetcher = new Fetcher('@readme/v1.0#n6kvf10vakpemvplxn'); - expect(await fetcher.load()).to.have.deep.property('info', { + await expect(fetcher.load()).resolves.toHaveProperty('info', { description: 'Create beautiful product and API documentation with our developer friendly platform.', version: '2.0.0', title: 'API Endpoints', @@ -154,12 +152,12 @@ describe('fetcher', function () { }); }); - describe('URL', function () { - it('should be able to load a definition', async function () { + describe('URL', () => { + it('should be able to load a definition', async () => { fetchMock.get('http://example.com/readme.json', readmeSpec); const fetcher = new Fetcher('http://example.com/readme.json'); - expect(await fetcher.load()).to.have.deep.property('info', { + await expect(fetcher.load()).resolves.toHaveProperty('info', { description: 'Create beautiful product and API documentation with our developer friendly platform.', version: '2.0.0', title: 'API Endpoints', @@ -173,27 +171,24 @@ describe('fetcher', function () { fetchMock.restore(); }); - it('should error if the url cannot be reached', async function () { + it('should error if the url cannot be reached', async () => { fetchMock.get('http://example.com/unknown.json', { status: 404 }); - await new Fetcher('http://example.com/unknown.json') - .load() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.equal('Unable to retrieve URL (http://example.com/unknown.json). Reason: Not Found'); - }); + await expect(new Fetcher('http://example.com/unknown.json').load()).rejects.toThrow( + 'Unable to retrieve URL (http://example.com/unknown.json). Reason: Not Found' + ); fetchMock.restore(); }); - it('should convert yaml to json', async function () { + it('should convert yaml to json', async () => { const spec = await fs.readFile(require.resolve('@readme/oas-examples/3.0/yaml/readme.yaml'), 'utf8'); fetchMock.get('http://example.com/readme.yaml', spec); const definition = 'http://example.com/readme.yaml'; const fetcher = new Fetcher(definition); - expect(await fetcher.load()).to.have.deep.property('info', { + await expect(fetcher.load()).resolves.toHaveProperty('info', { description: 'Create beautiful product and API documentation with our developer friendly platform.', version: '2.0.0', title: 'API Endpoints', @@ -208,30 +203,30 @@ describe('fetcher', function () { }); }); - describe('file', function () { - it('should be able to load a definition', async function () { + describe('file', () => { + it('should be able to load a definition', async () => { const fetcher = new Fetcher(require.resolve('@readme/oas-examples/3.0/json/readme.json')); const res = await fetcher.load(); - expect(res.paths['/api-specification'].get.parameters).to.be.dereferenced; + expect(res.paths['/api-specification'].get.parameters).toBeDereferenced(); }); - it('should be able to handle a relative path', async function () { + it('should be able to handle a relative path', async () => { const fetcher = new Fetcher('../api/test/__fixtures__/oas.json'); - expect(await fetcher.load()).to.have.deep.property('info', { + await expect(fetcher.load()).resolves.toHaveProperty('info', { version: '1.0.0', title: 'Single Path', description: 'This is a slimmed down single path version of the Petstore definition.', }); }); - it('should convert yaml to json', async function () { + it('should convert yaml to json', async () => { const file = require.resolve('@readme/oas-examples/3.0/yaml/readme.yaml'); const fetcher = new Fetcher(file); const res = await fetcher.load(); - expect(res.paths['/api-specification'].get.parameters).to.be.dereferenced; + expect(res.paths['/api-specification'].get.parameters).toBeDereferenced(); }); }); }); diff --git a/packages/api/test/global.d.ts b/packages/api/test/global.d.ts new file mode 100644 index 00000000..fd0a4cd6 --- /dev/null +++ b/packages/api/test/global.d.ts @@ -0,0 +1,3 @@ +import 'jest-extended'; + +import './helpers/jest.matchers'; diff --git a/packages/api/test/helpers/chai-plugins.ts b/packages/api/test/helpers/chai-plugins.ts deleted file mode 100644 index 69a362b5..00000000 --- a/packages/api/test/helpers/chai-plugins.ts +++ /dev/null @@ -1,122 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -import fs from 'fs'; -import path from 'path'; - -import caseless from 'caseless'; -import chai from 'chai'; - -import * as packageInfo from '../../src/packageInfo'; - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Chai { - interface Assertion { - /** - * Assert that a Response headers object has a custom API-identifying `User Agent` header. - */ - customUserAgent: void; - - /** - * Assert that a given array within an OpenAPI definition has been dereferenced. - */ - dereferenced: void; - - /** - * Assert that the contents of a given SDK match what we're expecting against a specific - * fixture. - * - * @param fixture Fixture directory in `test/__fixtures__/sdk/`. - */ - toMatchSDKFixture: (fixture: string) => void; - - /** - * Assert that a given HAR `headers` array has a given header matching a specific value. - */ - header: (header: string, expected: string | RegExp) => void; - } - } -} - -export default function chaiPlugins(_chai, utils) { - utils.addProperty(chai.Assertion.prototype, 'customUserAgent', function () { - const userAgent = this._obj['user-agent']; - - this.assert( - userAgent.match(/^api \(node\)\/(\d+.\d+(.\d+|unit-testing))$/), - `expected "${userAgent}" to be a custom user agent`, - `expected "${userAgent}" to not be a custom user agent` - ); - }); - - utils.addProperty(chai.Assertion.prototype, 'dereferenced', function () { - this.assert( - !this._obj.filter(obj => '$ref' in obj).length, - 'expected #{this} to be dereferenced', - 'expected #{this} to not dereferenced' - ); - }); - - utils.addMethod(chai.Assertion.prototype, 'toMatchSDKFixture', function (fixture: string) { - const dir = path.resolve(`test/__fixtures__/sdk/${fixture}`); - const actualFiles: Record = this._obj; - - let expectedFiles; - try { - expectedFiles = fs.readdirSync(dir); - } catch (err) { - // @todo it'd be cool if we could supply this with a `--update` arg to create the fixture dir - throw new Error(`No SDK fixture directory exists for "${fixture}"`); - } - - // Assert that the files we're generating are what we're expecting in the fixture directory. - const sortedActualFiles = Object.keys(actualFiles); - sortedActualFiles.sort(); // `index.d.ts` files are generated last but are first in the filesystem - - new chai.Assertion( - sortedActualFiles, - "The generated files do not line up with what's in the fixture directory." - ).to.be.deep.equal(expectedFiles); - - // Assert that each generated file is the same as in the fixture. - expectedFiles.forEach(file => { - const actual = actualFiles[file]; - - // We have to wrap in our current package version into the `<>` placeholder so we - // don't need to worry about committing package versions into source control or trying to mock - // out our `packageInfo` library, potentially causing sideeffects in other tests. - const expected = fs - .readFileSync(path.join(dir, file), 'utf8') - .replace('<>', packageInfo.PACKAGE_VERSION); - - new chai.Assertion(actual, `${file} does not match`).to.equal(expected); - }); - }); - - /** - * Determine if a given `Headers` object has a given header matching a specific value. - * - * @example should match a value - * expect(request.headers).to.have.header('connection', 'close'); - * - * @example should match a regex - * expect(response.headers).to.have.header('content-type', /application\/json(;\s?charset=utf-8)?/); - * - * @example should match one of many values - * expect(request.headers).to.have.header('connection', ['close', 'keep-alive']); - * - * @param {string} header - * @param {string|RegExp} expected - */ - utils.addMethod(chai.Assertion.prototype, 'header', function (header, expected) { - const obj = utils.flag(this, 'object') as Headers; - const headers = caseless(Object.fromEntries(Array.from(obj.entries()))); - - if (expected.constructor.name === 'RegExp') { - new chai.Assertion(headers.get(header)).to.match(expected); - } else if (Array.isArray(expected)) { - new chai.Assertion(headers.get(header)).to.oneOf(expected.map(e => e.toString())); - } else { - new chai.Assertion(headers.get(header)).to.equal(expected.toString()); - } - }); -} diff --git a/packages/api/test/helpers/init.js b/packages/api/test/helpers/init.js deleted file mode 100644 index 107f45fb..00000000 --- a/packages/api/test/helpers/init.js +++ /dev/null @@ -1,5 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const path = require('path'); - -process.env.TS_NODE_PROJECT = path.resolve('test/tsconfig.json'); -process.env.NODE_ENV = 'development'; diff --git a/packages/api/test/helpers/jest.matchers.ts b/packages/api/test/helpers/jest.matchers.ts new file mode 100644 index 00000000..5b6a4193 --- /dev/null +++ b/packages/api/test/helpers/jest.matchers.ts @@ -0,0 +1,121 @@ +import type { ParameterObject } from 'oas/dist/rmoas.types'; + +import caseless from 'caseless'; + +interface CustomMatchers { + /** + * Assert that a given array within an OpenAPI definition has been dereferenced. + */ + toBeDereferenced(): R; + + /** + * Assert that a Response headers object has a custom API-identifying `User Agent` header. + */ + toHaveCustomUserAgent(): R; + + /** + * Determine if a given `Headers` object has a given header matching a specific value. + * + * @example should match a value + * expect(request.headers).to.have.header('connection', 'close'); + * + * @example should match a regex + * expect(response.headers).to.have.header('content-type', /application\/json(;\s?charset=utf-8)?/); + * + * @example should match one of many values + * expect(request.headers).to.have.header('connection', ['close', 'keep-alive']); + * + */ + toHaveHeader(header: string, expected: RegExp | (string | number)[] | string): R; +} + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace jest { + // eslint-disable-next-line @typescript-eslint/no-empty-interface + interface Matchers extends CustomMatchers {} + } +} + +expect.extend({ + toBeDereferenced(this: jest.MatcherUtils, spec: ParameterObject[]) { + const pass = !spec.filter(obj => '$ref' in obj).length; + if (!pass) { + return { + message: () => 'expected the spec to be dereferenced', + pass: false, + }; + } + + return { + message: () => 'expected the spec to not be dereferenced', + pass: true, + }; + }, + + toHaveCustomUserAgent(this: jest.MatcherUtils, headers: string[]) { + const { printReceived } = this.utils; + const userAgent = headers['user-agent']; + const pass = userAgent.match(/^api \(node\)\/(\d+.\d+(.\d+|unit-testing))$/); + + if (!pass) { + return { + message: () => `expected a custom \`user-agent\` header to be present.\n\n${printReceived(userAgent)}`, + pass: false, + }; + } + + return { + message: () => `expected a custom \`user-agent\` header to not be present\n\n${printReceived(userAgent)}`, + pass: true, + }; + }, + + toHaveHeader(this: jest.MatcherUtils, obj: Headers, header: string, expected: RegExp | (string | number)[] | string) { + const { printReceived } = this.utils; + const headers = caseless(Object.fromEntries(Array.from(obj.entries()))); + + // Header value should match a given regex. + if (expected instanceof RegExp) { + if (!expected.test(headers.get(header))) { + return { + message: () => `expected header to match ${expected.source}\n\n${printReceived(header)}`, + pass: false, + }; + } + + return { + message: () => `expected header to not match ${expected.source}\n\n${printReceived(header)}`, + pass: true, + }; + } + + // Header value should exist in a given list. + if (Array.isArray(expected)) { + if (!expected.some(h => h === headers.get(header))) { + return { + message: () => `expected header to be one of the following: ${expected}\n\n${printReceived(header)}`, + pass: false, + }; + } + + return { + message: () => `expected header to not be one of the following: ${expected}\n\n${printReceived(header)}`, + pass: true, + }; + } + + // Header value should match a given value. + if (headers.get(header) !== expected) { + return { + message: () => `expected header to be ${expected}\n\n${printReceived(header)}`, + pass: false, + }; + } + + return { + message: () => `expected header not to be ${expected}\n\n${printReceived(header)}`, + pass: true, + }; + }, +}); diff --git a/packages/api/test/index.test.ts b/packages/api/test/index.test.ts index a903a49f..292f1acf 100644 --- a/packages/api/test/index.test.ts +++ b/packages/api/test/index.test.ts @@ -1,6 +1,7 @@ import type { OASDocument } from 'oas/dist/rmoas.types'; -import { assert, expect } from 'chai'; +import assert from 'assert'; + import fetchMock from 'fetch-mock'; import uniqueTempDir from 'unique-temp-dir'; @@ -14,16 +15,16 @@ import loadSpec from './helpers/load-spec'; let petstoreSDK; let readmeSDK; let operationIDQuirksSDK; -const petstoreServerUrl = 'http://petstore.swagger.io/api'; +const petstoreServerURL = 'http://petstore.swagger.io/api'; -describe('api', function () { - before(function () { +describe('api', () => { + beforeAll(() => { // Set a unique cache dir so these tests won't collide with other tests and we don't need to go // through the trouble of mocking out the filesystem. Cache.setCacheDir(uniqueTempDir()); }); - beforeEach(async function () { + beforeEach(async () => { const petstore = require.resolve('@readme/oas-examples/3.0/json/petstore-expanded.json'); await new Cache(petstore).load(); petstoreSDK = api(petstore); @@ -37,35 +38,35 @@ describe('api', function () { operationIDQuirksSDK = api(operationIDQuirks); }); - afterEach(function () { + afterEach(() => { fetchMock.restore(); }); - describe('#preloading', function () { + describe('#preloading', () => { let uspto; - beforeEach(function () { + beforeEach(() => { uspto = require.resolve('@readme/oas-examples/3.0/json/uspto.json'); }); - it('should proxy an sdk for the first time', async function () { + it('should proxy an sdk for the first time', async () => { fetchMock.get('https://developer.uspto.gov/ds-api/', mockResponses.url('pathname')); fetchMock.get('https://developer.uspto.gov/ds-api/two', mockResponses.url('pathname')); // Asserting that we have not previously loaded this API. - expect(new Cache(uspto).isCached()).to.be.false; + expect(new Cache(uspto).isCached()).toBe(false); const sdk = api(uspto); // SDK should still not be loaded since we haven't officially called it yet. - expect(new Cache(uspto).isCached()).to.be.false; - expect(Object.keys(sdk)).to.deep.equal(['auth', 'config', 'server']); + expect(new Cache(uspto).isCached()).toBe(false); + expect(Object.keys(sdk)).toStrictEqual(['auth', 'config', 'server']); - await sdk.listDataSets().then(({ data }) => expect(data).to.equal('/ds-api/')); + await sdk.listDataSets().then(({ data }) => expect(data).toBe('/ds-api/')); // Now that we've called something on the SDK, it should now be fully loaded. - expect(new Cache(uspto).isCached()).to.be.true; - expect(Object.keys(sdk)).to.deep.equal([ + expect(new Cache(uspto).isCached()).toBe(true); + expect(Object.keys(sdk)).toStrictEqual([ 'auth', 'config', 'server', @@ -78,123 +79,118 @@ describe('api', function () { ]); // Calling the same method again should also work as expected. - await sdk.listDataSets().then(({ data }) => expect(data).to.equal('/ds-api/')); + await sdk.listDataSets().then(({ data }) => expect(data).toBe('/ds-api/')); }); }); - describe('#accessors', function () { - it('should have a function for each http method', function () { + describe('#accessors', () => { + it('should have a function for each http method', () => { ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'].forEach(method => { - expect(petstoreSDK[method]).to.be.a('function'); + expect(petstoreSDK[method]).toBeFunction(); }); }); - describe('#operationId()', function () { - it('should work for operationId', async function () { - fetchMock.get(`${petstoreServerUrl}/pets`, mockResponses.real('it worked!')); + describe('#operationId()', () => { + it('should work for operationId', async () => { + fetchMock.get(`${petstoreServerURL}/pets`, mockResponses.real('it worked!')); - await petstoreSDK.findPets().then(({ data }) => expect(data).to.equal('it worked!')); + await petstoreSDK.findPets().then(({ data }) => expect(data).toBe('it worked!')); }); - it('should work with operationIds that have contain spaces', async function () { - fetchMock.get(`${petstoreServerUrl}/pets/1234`, mockResponses.real('it worked!')); + it('should work with operationIds that have contain spaces', async () => { + fetchMock.get(`${petstoreServerURL}/pets/1234`, mockResponses.real('it worked!')); - await petstoreSDK['find pet by id']({ id: 1234 }).then(({ data }) => expect(data).to.equal('it worked!')); + await petstoreSDK['find pet by id']({ id: 1234 }).then(({ data }) => expect(data).toBe('it worked!')); // Because we don't want people using ugly `operationID` accessors like the above we // transform them into JS-friendly method accessors also. - await petstoreSDK.findPetById({ id: 1234 }).then(({ data }) => expect(data).to.equal('it worked!')); + await petstoreSDK.findPetById({ id: 1234 }).then(({ data }) => expect(data).toBe('it worked!')); }); - it('should work with operationIds that contain hyphens', async function () { + it('should work with operationIds that contain hyphens', async () => { fetchMock.get('https://httpbin.org/anything/hyphenated-operation-id', mockResponses.real('it worked!')); - await operationIDQuirksSDK['hyphenated-operation-id']().then(({ data }) => expect(data).to.equal('it worked!')); - await operationIDQuirksSDK.hyphenatedOperationId().then(({ data }) => expect(data).to.equal('it worked!')); + await operationIDQuirksSDK['hyphenated-operation-id']().then(({ data }) => expect(data).toBe('it worked!')); + await operationIDQuirksSDK.hyphenatedOperationId().then(({ data }) => expect(data).toBe('it worked!')); }); - it('should support an operationId that was dynamically cleaned up within `Operation.getOperationId', async function () { + it('should support an operationId that was dynamically cleaned up within `Operation.getOperationId', async () => { const petstore = await loadSpec('@readme/oas-examples/3.0/json/petstore-expanded.json'); // `GET /pets/{id}` in this petstore SDK has an operationID of `find pet by id` but the // `camelCase` option on `Operation.getOperationId()` should transform it into // `findPetById`. - expect(petstore.paths['/pets/{id}'].get.operationId).to.equal('find pet by id'); - expect(petstoreSDK.findPetById).to.be.a('function'); + expect(petstore.paths['/pets/{id}'].get.operationId).toBe('find pet by id'); + expect(petstoreSDK.findPetById).toBeFunction(); }); - it('should work for other methods', async function () { - fetchMock.post(`${petstoreServerUrl}/pets`, mockResponses.real('it worked!')); + it('should work for other methods', async () => { + fetchMock.post(`${petstoreServerURL}/pets`, mockResponses.real('it worked!')); - await petstoreSDK.addPet().then(({ data }) => expect(data).to.equal('it worked!')); + await petstoreSDK.addPet().then(({ data }) => expect(data).toBe('it worked!')); }); - it.skip('should allow operationId to be the same as a http method'); + it.todo('should allow operationId to be the same as a http method'); - it('should error if an operationId does not exist', async function () { - await petstoreSDK - .findPetz() - .then(() => assert.fail()) - .catch(err => { - expect(err.message).to.match(/does not appear to be a valid operation/); - }); + it('should error if an operationId does not exist', async () => { + await expect(petstoreSDK.findPetz()).rejects.toThrow(/does not appear to be a valid operation/); }); }); }); - describe('#fetch', function () { + describe('#fetch', () => { const petId = 123; - it('should reject for error-level status codes', async function () { + it('should reject for error-level status codes', async () => { const response = { error: 'ENDPOINT_NOTFOUND', message: `The endpoint you called (GET /pets/${petId}) doesn't exist`, }; - fetchMock.delete(`${petstoreServerUrl}/pets/${petId}`, { body: response, status: 404 }); + fetchMock.delete(`${petstoreServerURL}/pets/${petId}`, { body: response, status: 404 }); await petstoreSDK .deletePet({ id: petId }) .then(() => assert.fail()) .catch(({ data, status }) => { - expect(status).to.equal(404); - expect(data).to.deep.equal(response); + expect(status).toBe(404); + expect(data).toStrictEqual(response); }); }); - it('should contain a custom user agent for the library in requests', async function () { + it('should contain a custom user agent for the library in requests', async () => { const userAgent = `${pkg.name} (node)/${pkg.version}`; - fetchMock.delete(`${petstoreServerUrl}/pets/${petId}`, mockResponses.headers, { + fetchMock.delete(`${petstoreServerURL}/pets/${petId}`, mockResponses.headers, { headers: { 'User-Agent': userAgent, }, }); await petstoreSDK.deletePet({ id: petId }).then(({ data }) => { - expect(data).to.have.deep.property('user-agent', userAgent); + expect(data).toHaveProperty('user-agent', userAgent); }); }); - describe('operationId', function () { - it('should pass through parameters for operationId', async function () { + describe('operationId', () => { + it('should pass through parameters for operationId', async () => { const response = { id: petId, name: 'Buster', }; - fetchMock.delete(`${petstoreServerUrl}/pets/${petId}`, response); + fetchMock.delete(`${petstoreServerURL}/pets/${petId}`, response); - await petstoreSDK.deletePet({ id: petId }).then(({ data }) => expect(data).to.deep.equal(response)); + await petstoreSDK.deletePet({ id: petId }).then(({ data }) => expect(data).toStrictEqual(response)); }); - it('should pass through body for operationId', async function () { + it('should pass through body for operationId', async () => { const body = { name: 'Buster' }; - fetchMock.post(`${petstoreServerUrl}/pets`, body, { body }); + fetchMock.post(`${petstoreServerURL}/pets`, body, { body }); - await petstoreSDK.addPet(body).then(({ data }) => expect(data).to.deep.equal(body)); + await petstoreSDK.addPet(body).then(({ data }) => expect(data).toStrictEqual(body)); }); - it('should pass through parameters and body for operationId', async function () { + it('should pass through parameters and body for operationId', async () => { const slug = 'new-release'; const body = { title: 'revised title', @@ -205,7 +201,7 @@ describe('api', function () { readmeSDK.server('https://dash.readme.com/api/v1'); await readmeSDK.updateChangelog(body, { slug }).then(({ data }) => { - expect(data).to.deep.equal({ + expect(data).toStrictEqual({ requestBody: body, uri: '/api/v1/changelogs/new-release', }); @@ -213,10 +209,10 @@ describe('api', function () { }); }); - describe('query parameter encoding', function () { + describe('query parameter encoding', () => { let queryEncoding; - beforeEach(function () { + beforeEach(() => { queryEncoding = api({ openapi: '3.1.0', info: { @@ -242,7 +238,7 @@ describe('api', function () { } as unknown as OASDocument); }); - it('should encode query parameters', async function () { + it('should encode query parameters', async () => { const params = { stringPound: 'something¬hing=true', stringHash: 'hash#data', @@ -258,13 +254,13 @@ describe('api', function () { fetchMock.get('glob:https://*.*', mockResponses.searchParams); await queryEncoding.getAnything(params).then(({ data }) => { - expect(data).to.equal( + expect(data).toBe( '/anything?stringPound=something%26nothing%3Dtrue&stringHash=hash%23data&stringArray=where%5B4%5D%3D10&stringWeird=properties%5B%22%24email%22%5D%20%3D%3D%20%22testing%22&array=something%26nothing%3Dtrue&array=nothing%26something%3Dfalse&array=another%20item' ); }); }); - it("should not double encode query params if they're already encoded", async function () { + it("should not double encode query params if they're already encoded", async () => { const params = { stringPound: encodeURIComponent('something¬hing=true'), stringHash: encodeURIComponent('hash#data'), @@ -280,7 +276,7 @@ describe('api', function () { fetchMock.get('glob:https://*.*', mockResponses.searchParams); await queryEncoding.getAnything(params).then(({ data }) => { - expect(data).to.deep.equal( + expect(data).toBe( '/anything?stringPound=something%26nothing%3Dtrue&stringHash=hash%23data&stringArray=where%5B4%5D%3D10&stringWeird=properties%5B%22%24email%22%5D%20%3D%3D%20%22testing%22&array=something%26nothing%3Dtrue&array=nothing%26something%3Dfalse&array=another%20item' ); }); diff --git a/packages/api/test/integration.test.ts b/packages/api/test/integration.test.ts index e22834bd..5f9175dc 100644 --- a/packages/api/test/integration.test.ts +++ b/packages/api/test/integration.test.ts @@ -1,6 +1,5 @@ import type { OASDocument } from 'oas/dist/rmoas.types'; -import chai, { expect } from 'chai'; import datauri from 'datauri'; import fetchMock from 'fetch-mock'; import uniqueTempDir from 'unique-temp-dir'; @@ -8,19 +7,16 @@ import uniqueTempDir from 'unique-temp-dir'; import api from '../src'; import Cache from '../src/cache'; -import chaiPlugins from './helpers/chai-plugins'; import { responses as mockResponse } from './helpers/fetch-mock'; import loadSpec from './helpers/load-spec'; -chai.use(chaiPlugins); - let fileUploads; let parametersStyle; let petstore; let security; -describe('integration tests', function () { - before(async function () { +describe('integration tests', () => { + beforeAll(async () => { fileUploads = await loadSpec('@readme/oas-examples/3.0/json/file-uploads.json'); parametersStyle = await loadSpec('@readme/oas-examples/3.1/json/parameters-style.json'); petstore = await loadSpec('@readme/oas-examples/3.0/json/petstore.json'); @@ -31,14 +27,14 @@ describe('integration tests', function () { Cache.setCacheDir(uniqueTempDir()); }); - afterEach(function () { + afterEach(() => { fetchMock.restore(); }); - describe('`application/x-www-form-urlencoded`', function () { + describe('`application/x-www-form-urlencoded`', () => { let usptoSpec; - beforeEach(async function () { + beforeEach(async () => { usptoSpec = await loadSpec('@readme/oas-examples/3.0/json/uspto.json').then(spec => { // eslint-disable-next-line no-param-reassign spec.servers[0].url = '{scheme}://httpbin.org/anything'; @@ -46,7 +42,7 @@ describe('integration tests', function () { }); }); - it('should support `application/x-www-form-urlencoded` requests', async function () { + it('should support `application/x-www-form-urlencoded` requests', async () => { fetchMock.post('https://httpbin.org/anything/v1/oa_citations/records', mockResponse.all); const body = { @@ -59,13 +55,13 @@ describe('integration tests', function () { }; const { data } = await api(usptoSpec).performSearch(body, metadata); - expect(data.uri).to.equal('/anything/v1/oa_citations/records'); - expect(data.requestBody).to.equal('criteria=propertyName%3Avalue'); - expect(data.headers).to.have.deep.property('content-type', 'application/x-www-form-urlencoded'); - expect(data.headers).to.have.be.a.customUserAgent; + expect(data.uri).toBe('/anything/v1/oa_citations/records'); + expect(data.requestBody).toBe('criteria=propertyName%3Avalue'); + expect(data.headers).toHaveProperty('content-type', 'application/x-www-form-urlencoded'); + expect(data.headers).toHaveCustomUserAgent(); }); - // it.skip('should send along required parameters if not supplied', async function () { + // it.skip('should send along required parameters if not supplied', async () => { // const metadata = { // dataset: 'v1', // version: 'oa_citations', @@ -91,21 +87,21 @@ describe('integration tests', function () { // }); }); - it('should support `image/png` requests', async function () { + it('should support `image/png` requests', async () => { fetchMock.post('https://httpbin.org/anything/image-png', mockResponse.datauri); const file = `${__dirname}/__fixtures__/owlbert.png`; const { data } = await api(fileUploads as unknown as OASDocument).postAnythingImagePng(file); - expect(data.uri).to.equal('/anything/image-png'); - expect(data.requestBody).to.equal(await datauri(file)); - expect(data.headers).to.have.deep.property('content-type', 'image/png'); - expect(data.headers).to.have.a.customUserAgent; + expect(data.uri).toBe('/anything/image-png'); + expect(data.requestBody).toBe(await datauri(file)); + expect(data.headers).toHaveProperty('content-type', 'image/png'); + expect(data.headers).toHaveCustomUserAgent(); }); - describe('header handling', function () { - describe('`authorization`', function () { - it('should support supplying an `authorization` header', async function () { + describe('header handling', () => { + describe('`authorization`', () => { + it('should support supplying an `authorization` header', async () => { fetchMock.post('http://petstore.swagger.io/v2/pet', mockResponse.all); const body = { @@ -122,13 +118,13 @@ describe('integration tests', function () { sdk.auth('buster'); const { data } = await sdk.addPet(body, metadata); - expect(data.uri).to.equal('/v2/pet'); - expect(data.requestBody).to.equal('{"id":1234,"name":"buster"}'); - expect(data.headers).to.have.deep.property('authorization', 'bearer 12345'); - expect(data.headers).to.have.a.customUserAgent; + expect(data.uri).toBe('/v2/pet'); + expect(data.requestBody).toBe('{"id":1234,"name":"buster"}'); + expect(data.headers).toHaveProperty('authorization', 'bearer 12345'); + expect(data.headers).toHaveCustomUserAgent(); }); - it('should support supplying an `authorization` header (on an operation that has no params)', async function () { + it('should support supplying an `authorization` header (on an operation that has no params)', async () => { fetchMock.post('https://httpbin.org/anything/bearer', mockResponse.headers); const metadata = { @@ -142,13 +138,13 @@ describe('integration tests', function () { await securityApi.postAnythingBearer(metadata).then(({ data }) => { // `authorization: bearer buster` should not be here because we manually supplied // `authorization: bearer 12345` to the metadata. - expect(data).to.have.deep.property('authorization', 'bearer 12345'); + expect(data).toHaveProperty('authorization', 'bearer 12345'); }); }); }); - describe('`accept`', function () { - it('should support supplying an `accept` header', async function () { + describe('`accept`', () => { + it('should support supplying an `accept` header', async () => { fetchMock.post('http://petstore.swagger.io/v2/pet', mockResponse.all); const body = { @@ -161,13 +157,13 @@ describe('integration tests', function () { }; const { data } = await api(petstore as unknown as OASDocument).addPet(body, metadata); - expect(data.uri).to.equal('/v2/pet'); - expect(data.requestBody).to.equal('{"id":1234,"name":"buster"}'); - expect(data.headers).to.have.deep.property('accept', 'text/xml'); - expect(data.headers).to.have.a.customUserAgent; + expect(data.uri).toBe('/v2/pet'); + expect(data.requestBody).toBe('{"id":1234,"name":"buster"}'); + expect(data.headers).toHaveProperty('accept', 'text/xml'); + expect(data.headers).toHaveCustomUserAgent(); }); - it('should support supplying **only** an `accept` header', async function () { + it('should support supplying **only** an `accept` header', async () => { fetchMock.post('http://petstore.swagger.io/v2/pet', mockResponse.all); const metadata = { @@ -175,13 +171,13 @@ describe('integration tests', function () { }; const { data } = await api(petstore as unknown as OASDocument).addPet(metadata); - expect(data.uri).to.equal('/v2/pet'); - expect(data.requestBody).to.be.undefined; - expect(data.headers).to.have.deep.property('accept', 'text/xml'); - expect(data.headers).to.have.a.customUserAgent; + expect(data.uri).toBe('/v2/pet'); + expect(data.requestBody).toBeUndefined(); + expect(data.headers).toHaveProperty('accept', 'text/xml'); + expect(data.headers).toHaveCustomUserAgent(); }); - it('should support supplying an `authorization` header (on an operation that has no params)', async function () { + it('should support supplying an `authorization` header (on an operation that has no params)', async () => { fetchMock.post('https://httpbin.org/anything/bearer', mockResponse.headers); const metadata = { @@ -189,13 +185,13 @@ describe('integration tests', function () { }; const { data } = await api(security as unknown as OASDocument).postAnythingBearer(metadata); - expect(data).to.have.deep.property('accept', 'application/buster+json'); + expect(data).toHaveProperty('accept', 'application/buster+json'); }); }); }); - describe('multipart/form-data', function () { - it('should support `multipart/form-data` requests', async function () { + describe('multipart/form-data', () => { + it('should support `multipart/form-data` requests', async () => { fetchMock.post('https://httpbin.org/anything/form-data/form', mockResponse.multipart); const body = { @@ -208,21 +204,21 @@ describe('integration tests', function () { }; const { data } = await api(parametersStyle as unknown as OASDocument).formData_form_nonExploded(body); - expect(data.uri).to.equal('/anything/form-data/form'); - expect(data.requestBody.split(`--${data.boundary}`).filter(Boolean)).to.deep.equal([ + expect(data.uri).toBe('/anything/form-data/form'); + expect(data.requestBody.split(`--${data.boundary}`).filter(Boolean)).toStrictEqual([ '\r\nContent-Disposition: form-data; name="primitive"\r\n\r\nstring\r\n', '\r\nContent-Disposition: form-data; name="array"\r\n\r\nstring\r\n', '\r\nContent-Disposition: form-data; name="object"\r\n\r\nfoo,foo-string,bar,bar-string\r\n', '--\r\n\r\n', ]); - expect(data.headers).to.have.deep.property('content-type', `multipart/form-data; boundary=${data.boundary}`); - expect(data.headers).to.have.deep.property('content-length', '356'); - expect(data.headers).to.have.a.customUserAgent; + expect(data.headers).toHaveProperty('content-type', `multipart/form-data; boundary=${data.boundary}`); + expect(data.headers).toHaveProperty('content-length', '356'); + expect(data.headers).toHaveCustomUserAgent(); }); - describe('files', function () { - it('should support plaintext files', async function () { + describe('files', () => { + it('should support plaintext files', async () => { fetchMock.post('https://httpbin.org/anything/multipart-formdata', mockResponse.multipart); const body = { @@ -232,20 +228,20 @@ describe('integration tests', function () { }; const { data } = await api(fileUploads as unknown as OASDocument).postAnythingMultipartFormdata(body); - expect(data.uri).to.equal('/anything/multipart-formdata'); - expect(data.requestBody.split(`--${data.boundary}`).filter(Boolean)).to.deep.equal([ + expect(data.uri).toBe('/anything/multipart-formdata'); + expect(data.requestBody.split(`--${data.boundary}`).filter(Boolean)).toStrictEqual([ '\r\nContent-Disposition: form-data; name="orderId"\r\n\r\n1234\r\n', '\r\nContent-Disposition: form-data; name="userId"\r\n\r\n5678\r\n', '\r\nContent-Disposition: form-data; name="documentFile"; filename="hello.txt"\r\nContent-Type: text/plain\r\n\r\nHello world!\n\r\n', '--\r\n\r\n', ]); - expect(data.headers).to.have.deep.property('content-type', `multipart/form-data; boundary=${data.boundary}`); - expect(data.headers).to.have.deep.property('content-length', '389'); - expect(data.headers).to.have.a.customUserAgent; + expect(data.headers).toHaveProperty('content-type', `multipart/form-data; boundary=${data.boundary}`); + expect(data.headers).toHaveProperty('content-length', '389'); + expect(data.headers).toHaveCustomUserAgent(); }); - it('should support plaintext files containing unicode characters', async function () { + it('should support plaintext files containing unicode characters', async () => { fetchMock.post('https://httpbin.org/anything/multipart-formdata', mockResponse.multipart); const body = { @@ -253,19 +249,19 @@ describe('integration tests', function () { }; const { data } = await api(fileUploads as unknown as OASDocument).postAnythingMultipartFormdata(body); - expect(data.uri).to.equal('/anything/multipart-formdata'); - expect(data.requestBody.split(`--${data.boundary}`).filter(Boolean)).to.deep.equal([ + expect(data.uri).toBe('/anything/multipart-formdata'); + expect(data.requestBody.split(`--${data.boundary}`).filter(Boolean)).toStrictEqual([ '\r\nContent-Disposition: form-data; name="documentFile"; filename="hello.jp.txt"\r\nContent-Type: text/plain\r\n\r\n速い茶色のキツネは怠惰な犬を飛び越えます\n\r\n', '--\r\n\r\n', ]); - expect(data.headers).to.have.deep.property('content-type', `multipart/form-data; boundary=${data.boundary}`); - expect(data.headers).to.have.deep.property('content-length', '251'); - expect(data.headers).to.have.a.customUserAgent; + expect(data.headers).toHaveProperty('content-type', `multipart/form-data; boundary=${data.boundary}`); + expect(data.headers).toHaveProperty('content-length', '251'); + expect(data.headers).toHaveCustomUserAgent(); }); }); - // it.skip('should support `multipart/form-data` requests with an array of files', async function () { + // it.skip('should support `multipart/form-data` requests with an array of files', async () => { // const body = [ // `${__dirname}/__fixtures__/owlbert.png`, // `${__dirname}/__fixtures__/owlbert-shrub.png`, diff --git a/packages/api/test/server.test.ts b/packages/api/test/server.test.ts index 7b99bcd9..e57af6bf 100644 --- a/packages/api/test/server.test.ts +++ b/packages/api/test/server.test.ts @@ -1,4 +1,3 @@ -import { expect } from 'chai'; import fetchMock from 'fetch-mock'; import uniqueTempDir from 'unique-temp-dir'; @@ -15,8 +14,8 @@ const response = { name: 'Buster', }; -describe('#server()', function () { - before(async function () { +describe('#server()', () => { + beforeAll(async () => { serverVariables = await loadSpec('@readme/oas-examples/3.0/json/server-variables.json'); // Set a unique cache dir so these tests won't collide with other tests and we don't need to go @@ -24,29 +23,29 @@ describe('#server()', function () { Cache.setCacheDir(uniqueTempDir()); }); - beforeEach(function () { + beforeEach(() => { sdk = api(serverVariables); }); - afterEach(function () { + afterEach(() => { fetchMock.restore(); }); - it('should use server variable defaults if no server or variables are supplied', async function () { + it('should use server variable defaults if no server or variables are supplied', async () => { fetchMock.post('https://demo.example.com:443/v2/global', response); - await sdk.postGlobal().then(({ data }) => expect(data).to.deep.equal(response)); + await sdk.postGlobal().then(({ data }) => expect(data).toStrictEqual(response)); }); - it('should support supplying a full server url', async function () { + it('should support supplying a full server url', async () => { fetchMock.post('https://buster.example.com:3000/v14/global', response); sdk.server('https://buster.example.com:3000/v14'); - await sdk.postGlobal().then(({ data }) => expect(data).to.deep.equal(response)); + await sdk.postGlobal().then(({ data }) => expect(data).toStrictEqual(response)); }); - it('should support supplying a server url with server variables', async function () { + it('should support supplying a server url with server variables', async () => { fetchMock.post('http://dev.local/v14/global', response); sdk.server('http://{name}.local/{basePath}', { @@ -54,10 +53,10 @@ describe('#server()', function () { basePath: 'v14', }); - await sdk.postGlobal().then(({ data }) => expect(data).to.deep.equal(response)); + await sdk.postGlobal().then(({ data }) => expect(data).toStrictEqual(response)); }); - it.skip('should be able to supply a url on an OAS that has no servers defined'); + it.todo('should be able to supply a url on an OAS that has no servers defined'); - it.skip("should be able to supply a url that doesn't match any defined server"); + it.todo("should be able to supply a url that doesn't match any defined server"); }); diff --git a/packages/httpsnippet-client-api/.gitignore b/packages/httpsnippet-client-api/.gitignore index f8f5b061..ef229ed3 100644 --- a/packages/httpsnippet-client-api/.gitignore +++ b/packages/httpsnippet-client-api/.gitignore @@ -1,3 +1,3 @@ -.nyc_output/ +coverage/ dist/ node_modules/ diff --git a/packages/httpsnippet-client-api/.mocharc.json b/packages/httpsnippet-client-api/.mocharc.json deleted file mode 100644 index 3e04cc82..00000000 --- a/packages/httpsnippet-client-api/.mocharc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "require": [ - "test/helpers/init.js", - "ts-node/register" - ], - "watch-extensions": [ - "ts" - ], - "watch-files": ["src/*.ts", "test/**/*.ts"], - "recursive": true, - "reporter": "spec", - "timeout": 60000 -} diff --git a/packages/httpsnippet-client-api/.npmignore b/packages/httpsnippet-client-api/.npmignore index 675a7586..ca9b2142 100644 --- a/packages/httpsnippet-client-api/.npmignore +++ b/packages/httpsnippet-client-api/.npmignore @@ -1,6 +1,6 @@ -.nyc_output/ +coverage/ test/ .eslint* .gitignore -.mocharc.json .prettier* +jest.config.js diff --git a/packages/httpsnippet-client-api/jest.config.js b/packages/httpsnippet-client-api/jest.config.js new file mode 100644 index 00000000..e858821e --- /dev/null +++ b/packages/httpsnippet-client-api/jest.config.js @@ -0,0 +1,22 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + coveragePathIgnorePatterns: [ + '/dist', + '/node_modules', + '/test/__datasets__/', + '/test/__fixtures__/', + '/test/helpers/', + ], + modulePaths: [''], + roots: [''], + testPathIgnorePatterns: ['/test/__datasets__/', '/test/__fixtures__/', '/test/helpers/'], + testRegex: '(/test/.*|(\\.|/)(test|spec))\\.(js?|ts?)$', + transform: { + '^.+\\.[tj]s$': [ + 'ts-jest', + { + tsconfig: 'test/tsconfig.json', + }, + ], + }, +}; diff --git a/packages/httpsnippet-client-api/package.json b/packages/httpsnippet-client-api/package.json index 91723197..7cb11b49 100644 --- a/packages/httpsnippet-client-api/package.json +++ b/packages/httpsnippet-client-api/package.json @@ -8,7 +8,7 @@ "build": "tsc", "prebuild": "rm -rf dist/", "prepack": "npm run build", - "test": "nyc mocha \"test/**/*.test.ts\"" + "test": "jest --coverage" }, "repository": { "type": "git", @@ -35,22 +35,14 @@ "@readme/oas-examples": "^5.9.0", "@readme/openapi-parser": "^2.4.0", "@types/content-type": "^1.1.5", + "@types/jest": "^29.5.2", "@types/stringify-object": "^4.0.2", "api": "file:../api", - "chai": "^4.3.7", "fetch-mock": "^9.11.0", "isomorphic-fetch": "^3.0.0", - "mocha": "^10.2.0", - "nyc": "^15.1.0", - "sinon": "^15.0.1", - "sinon-chai": "^3.7.0", + "jest": "^29.6.1", + "ts-jest": "^29.1.1", "typescript": "^4.9.5" }, - "prettier": "@readme/eslint-config/prettier", - "nyc": { - "exclude": [ - "dist/", - "test/" - ] - } + "prettier": "@readme/eslint-config/prettier" } diff --git a/packages/httpsnippet-client-api/src/index.ts b/packages/httpsnippet-client-api/src/index.ts index 290f40f6..e0f0135d 100644 --- a/packages/httpsnippet-client-api/src/index.ts +++ b/packages/httpsnippet-client-api/src/index.ts @@ -35,7 +35,7 @@ function buildAuthSnippet(authKey: string | string[]) { } function getAuthSources(operation: Operation) { - const matchers: { header: Record; query: string[]; cookie: string[] } = { + const matchers: { cookie: string[]; header: Record; query: string[] } = { header: {}, query: [], cookie: [], @@ -79,8 +79,8 @@ function getAuthSources(operation: Operation) { export interface APIOptions { apiDefinition: OASDocument; apiDefinitionUri: string; - indent?: string | false; escapeBrackets?: boolean; + indent?: string | false; } const client: Client = { diff --git a/packages/httpsnippet-client-api/test/.eslintrc b/packages/httpsnippet-client-api/test/.eslintrc index a16e4a4a..f5de24fc 100644 --- a/packages/httpsnippet-client-api/test/.eslintrc +++ b/packages/httpsnippet-client-api/test/.eslintrc @@ -1,6 +1,6 @@ { - "extends": "@readme/eslint-config/testing-mocha", + "extends": "@readme/eslint-config/testing", "rules": { - "func-names": "off" + "jest/no-export": "off" } } diff --git a/packages/httpsnippet-client-api/test/helpers/fetch-mock.js b/packages/httpsnippet-client-api/test/helpers/fetch-mock.js deleted file mode 100644 index 383247f5..00000000 --- a/packages/httpsnippet-client-api/test/helpers/fetch-mock.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - // https://stackoverflow.com/questions/10623798/how-do-i-read-the-contents-of-a-node-js-stream-into-a-string-variable - streamToString(stream) { - const chunks = []; - return new Promise((resolve, reject) => { - stream.on('data', chunk => chunks.push(Buffer.from(chunk))); - stream.on('error', err => reject(err)); - stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))); - }); - }, -}; diff --git a/packages/httpsnippet-client-api/test/helpers/fetch-mock.ts b/packages/httpsnippet-client-api/test/helpers/fetch-mock.ts new file mode 100644 index 00000000..f264819f --- /dev/null +++ b/packages/httpsnippet-client-api/test/helpers/fetch-mock.ts @@ -0,0 +1,11 @@ +/** + * @see {@link https://stackoverflow.com/questions/10623798/how-do-i-read-the-contents-of-a-node-js-stream-into-a-string-variable} + */ +export function streamToString(stream): Promise { + const chunks = []; + return new Promise((resolve, reject) => { + stream.on('data', chunk => chunks.push(Buffer.from(chunk))); + stream.on('error', err => reject(err)); + stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))); + }); +} diff --git a/packages/httpsnippet-client-api/test/helpers/init.js b/packages/httpsnippet-client-api/test/helpers/init.js deleted file mode 100644 index 107f45fb..00000000 --- a/packages/httpsnippet-client-api/test/helpers/init.js +++ /dev/null @@ -1,5 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const path = require('path'); - -process.env.TS_NODE_PROJECT = path.resolve('test/tsconfig.json'); -process.env.NODE_ENV = 'development'; diff --git a/packages/httpsnippet-client-api/test/index.test.ts b/packages/httpsnippet-client-api/test/index.test.ts index 914e4800..4e501f90 100644 --- a/packages/httpsnippet-client-api/test/index.test.ts +++ b/packages/httpsnippet-client-api/test/index.test.ts @@ -1,5 +1,4 @@ /* eslint-disable global-require */ -/* eslint-disable mocha/no-setup-in-describe */ import type { HarRequest, Request } from '@readme/httpsnippet'; import type { Client } from '@readme/httpsnippet/dist/targets/targets'; import type { MockMatcher, MockOptions } from 'fetch-mock'; @@ -13,39 +12,31 @@ import vm from 'vm'; import { HTTPSnippet, addTargetClient } from '@readme/httpsnippet'; import readme from '@readme/oas-examples/3.0/json/readme.json'; import openapiParser from '@readme/openapi-parser'; -import chai, { expect } from 'chai'; import fetchMock from 'fetch-mock'; import 'isomorphic-fetch'; import rimraf from 'rimraf'; -import sinon from 'sinon'; -import sinonChai from 'sinon-chai'; import client from '../src'; -chai.use(sinonChai); - const DATASETS_DIR = path.join(__dirname, '__datasets__'); const SNIPPETS = readdirSync(DATASETS_DIR); -// eslint-disable-next-line mocha/no-exports export interface SnippetMock { - har: HarRequest; definition: OASDocument; fetch: { req: MockMatcher | MockOptions; res: Record; }; + har: HarRequest; } function getSnippetDataset(snippet): Promise { return import(path.join(DATASETS_DIR, snippet, 'index')).then(r => r.default); } -describe('httpsnippet-client-api', function () { - beforeEach(function () { +describe('httpsnippet-client-api', () => { + beforeEach(() => { try { - // Mocha doesn't tear this down so if you run Mocha with `--watch` it'll be set up already - // throwing the error that we're ignoring below. addTargetClient('node', client as Client); } catch (err) { if (err.message !== 'The supplied custom target client already exists, please use a different key') { @@ -54,9 +45,9 @@ describe('httpsnippet-client-api', function () { } }); - it('should have info', function () { - expect(client).to.have.property('info'); - expect(client.info).to.deep.equal({ + it('should have info', () => { + expect(client).toHaveProperty('info'); + expect(client.info).toStrictEqual({ key: 'api', title: 'API', link: 'https://npm.im/api', @@ -64,16 +55,16 @@ describe('httpsnippet-client-api', function () { }); }); - it('should error if no apiDefinitionUri was supplied', async function () { + it('should error if no apiDefinitionUri was supplied', async () => { const { har } = await getSnippetDataset('petstore'); const snippet = new HTTPSnippet(har); expect(() => { snippet.convert('node', 'api'); - }).to.throw(/must have an `apiDefinitionUri` option supplied/); + }).toThrow(/must have an `apiDefinitionUri` option supplied/); }); - it('should error if no apiDefinition was supplied', async function () { + it('should error if no apiDefinition was supplied', async () => { const { har } = await getSnippetDataset('petstore'); const snippet = new HTTPSnippet(har); @@ -81,11 +72,11 @@ describe('httpsnippet-client-api', function () { snippet.convert('node', 'api', { apiDefinitionUri: 'https://api.example.com/openapi.json', }); - }).to.throw(/must have an `apiDefinition` option supplied/); + }).toThrow(/must have an `apiDefinition` option supplied/); }); // This test should fail because the url in the HAR is missing `/v1` in the path. - it('should error if no matching operation was found in the apiDefinition', function () { + it('should error if no matching operation was found in the apiDefinition', () => { const har = { httpVersion: 'HTTP/1.1', method: 'GET', @@ -103,16 +94,16 @@ describe('httpsnippet-client-api', function () { apiDefinitionUri: 'https://api.example.com/openapi.json', apiDefinition: readme, }); - }).to.throw(/unable to locate a matching operation/i); + }).toThrow(/unable to locate a matching operation/i); }); - describe('snippets', function () { + describe('snippets', () => { SNIPPETS.forEach(snippet => { - describe(snippet, function () { + describe(`${snippet}`, () => { let mock: SnippetMock; let consoleStub; - beforeEach(async function () { + beforeEach(async () => { try { // Since we're doing integration testing with these snippets against the real `api` // library we should clear out the cache that it creates so our tests will run in a @@ -122,7 +113,7 @@ describe('httpsnippet-client-api', function () { // If we couldn't delete the `api` specs cache then it probably doesn't exist yet. } - consoleStub = sinon.stub(console, 'log'); + consoleStub = jest.spyOn(console, 'log').mockImplementation(); mock = await getSnippetDataset(snippet); @@ -132,12 +123,12 @@ describe('httpsnippet-client-api', function () { await openapiParser.validate(spec); }); - afterEach(function () { - consoleStub.restore(); + afterEach(() => { + consoleStub.mockRestore(); fetchMock.restore(); }); - it('should generate the expected snippet', async function () { + it('should generate the expected snippet', async () => { const expected = await fs.readFile(path.join(DATASETS_DIR, snippet, 'output.js'), 'utf-8'); const code = new HTTPSnippet(mock.har).convert('node', 'api', { @@ -145,10 +136,11 @@ describe('httpsnippet-client-api', function () { apiDefinition: mock.definition, }); - expect(`${code}\n`).to.equal(expected); + expect(`${code}\n`).toStrictEqual(expected); }); - it('should generate a functional snippet', async function () { + it('should generate a functional snippet', async () => { + // eslint-disable-next-line jest/no-if if (!mock.fetch.req || !mock.fetch.res) { throw new Error( `The mock definition for ${snippet} must include required \`req\` and \`res\` expectations.` @@ -213,7 +205,7 @@ describe('httpsnippet-client-api', function () { script.runInContext(context); }); - expect(consoleStub).to.be.calledWith(`The ${snippet} request works properly!`); + expect(consoleStub).toHaveBeenCalledWith(`The ${snippet} request works properly!`); }); }); });